Mybatis的基础和高级查询应用实践
toqiye 2024-09-08 09:42 4 浏览 0 评论
前言
将分为3部分介绍:
- 基本应用
- 基于xml的复杂映射开发
- Mybatis注解开发
[玫瑰][玫瑰]你的“关注”“收藏”是我最大的动力。非常感谢。[玫瑰][玫瑰]
基本应用
1.快速入门
快速入门查看官网 :http://www.mybatis.org/mybatis-3
开发步骤
1.添加Mybatis的坐标(添加pom.xml依赖)
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
2.创建数据库表 + 编写实体
表设计和实体根据自己业务实际编写即可
3.编写映射文件Mapper.xml与标签说明
<!--
<?xml ...> 映射文件DTD约束头
<mapper> 根标签
namespae 命名空间,与语句ID标识id组成查询的标识
<select> 查询操作
<update> 更新操作
<insert> 添加操作
<delete> 删除操作
id 语句ID标识,与命名空间一起组织成查询标识
resultType 查询结果对应的实体类型
parameterType 查询对象类型
-->
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="UserMapper">
<select id="find" resultType="com.otoom.pojo.User" parameterType="com.otoom.pojo.User">
select * from User WHERE username = #{username}
</select>
</mapper>
4.编写核心文件SqlMapConfig.xml
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN“ "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties"/>
<!--环境,默认环境为:development-->
<environments default="development">
<!--环境配置-->
<environment id="development">
<!--当前事务交给JDBC处理-->
<transactionManager type="JDBC"/>
<!--使用mybatis提供的连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--引入配置文件-->
<mappers>
<!--使用指定文件路径
<mapper resource="com/xxx/mapper/UserMapper.xml"/>
-->
<!--
指定包名,会扫描这个文件夹下所有的xml
这个xml的路径包名在resource中,需要和接口的包名一致
如: resources目录下:com/xxx/mapper 存放xml文件
-->
<package name="com.xxx.mapper"/>
</mappers>
</configuration>
5.使用
public static void main(String[] args){
//获取配置信息
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//获取工厂类
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(resourceAsStream);
//开启sql会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//开始执行对应操作
User query = new User();
query.setUsername("Tom");
int insert = sqlSession.insert("userMapper.find", query);
//提交事务
//sqlSession.commit(); //CUD操作需要提交事务
//关闭会话
sqlSession.close();
}
sqlConfig.xml核心配置文件标签说明
<environments>: 数据库环境的配置,支持多种环境配置
<environment>: 环境变量
<transactionManager>: 事务管理器,有两种类型:
- JDBC:使用了JDBC的提交和回滚设置,依赖于从数据源得到的链接来管理事务作用域
- MANAGED:这个配置几乎什么都没有做,它从不提交和回滚一个链接,而是让容器去管理事务的整个生命周期。默认情况下它会关闭连接,然后有些容器不希望关闭,所以需要将 closeConnection 属性设置为false来阻止它的默认行为
<dataSource>: 数据源,有三种类型:
- UNPOOLED:非连接池类型。这个数据源实现的只是每次请求时打开和关闭连接
- POOLED:连接池类型。这种数据源实现利用"池"的概念将JDBC连接对象组织起来
- JNDI:这个数据源实现是为了能在如EJB或者应用服务器这类的容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文引用
<property>: 属性
<propertys>: 属性该标签可以加载额外配置的properties文件,如resource文件夹下的jdbc.properties。使用方式为:${jdbc.driver} 可以引用对应的值
<mappers>: 映射器,作用是加载sql的映射,有四种方式
- 使用类路径:<mapper resource="com/xxx/mapper/UserDao.xml"/>
- 使用完全限定资源定位符(URL): <mapper url="file:///user/xx/project/xxx/UserDao.xml"/>
- 使用映射器接口实现类的完全限定类名: <mapper class="com.xxx.UserDao"/>
- 使用包内的映射器接口实现全部注册为映射器: <package name="com.xxx.mapper"/>
基于xml复杂映射开发
准备:演示说明具体的xml复杂映射开发前,需要准备一下模拟信息
- 实体
- Mapper接口
- 实体(对应数据库表)
public class User{
private Integer id;
private String userName;
//一个用户,有多个订单(一对多)
private List<Order> orderList;
//用户角色(多对多)
private List<Role> roleList;
}
public class Order{
private Integer id;
private Integer userId;
private String orderTime;
//一个订单,只有一个用户(一对一)
private User user;
}
public class Role{
private Integer id;
private String roleName;
}
public class UserRole{
private Integer userId
private Integer roleid;
}
- Mapper接口
public class OrderMapper{
List<Order> findAll();
//查询一对一
List<Order> finUserAndOrder();
}
public class UserMapper{
User findById(Integer userId);
//查询一对多
List<User> findAll();
//查询多对对
List<User> findAllUserAndRole();
}
public class RoleMapper{
//查询多对对
List<Role> findByUserId(Integer userId);
}
一对一查询
<mapper namespace="OrderMapper">
<!--一对一映射配置-->
<resultMap id="orderMap" type="Order">
<result property="id" column="id"/>
<result property="userId" column="userId"/>
<result property="orderTime" column="orderTime"/>
<!--
这里配置User对象里面的user属性的User对象与表字段的映射关系
实现把user和order的一对一关系映射
-->
<association property="user" javaType="User">
<result property="id" column="userId"/>
<result property="username" column="username"/>
</association>
</resultMap>
<!--resultMap: 手动配置实体属性与表字段的映射关系-->
<select id="finUserAndOrder" parameterType="Order" resultMap="orderMap">
select * from order o,user u where o.userId = u.id
</select>
</mapper>
一对多查询
从用户角度出发,查询一对多结果;
<mapper namespace="UserMapper">
<!--一对多映射配置-->
<resultMap id="userMap" type="User">
<result property="id" column="id"/>
<result property="username" column="username"/>
<!--这里配置orderList属性的Order对象与表字段的映射关系-->
<collection property="orderList" ofType="Order">
<result property="id" column="oid"/>
<result property="userId" column="userId"/>
<result property="orderTime" column="orderTime"/>
</collection>
</resultMap>
<!--resultMap: 手动配置实体属性与表字段的映射关系-->
<select id="findAll" parameterType="User" resultMap="userMap">
select *,o.id oid from user u left join order o on o.userId = u.id
</select>
</mapper>
多对多查询
用户和角色的关系,就是多对多查询;
<mapper namespace="UserMapper">
<!--多对多映射配置-->
<resultMap id="userRoleMap" type="User">
<result property="id" column="id"/>
<result property="username" column="username"/>
<!--这里配置roleList属性的Role对象与表字段的映射关系-->
<collection property="roleList" ofType="Role">
<result property="id" column="rid"/>
<result property="roleName" column="roleName"/>
</collection>
</resultMap>
<select id="findAllUserAndRole" parameterType="User" resultMap="userRoleMap">
select u.*,r.*,r.id rid from user u
left join user_role ur on u.id = ur.userId
left join role r on r.id = ur.roleId
</select>
</mapper>
测试复杂映射
public static void main(String[] args){
//获取配置输入流
InputStream inputStream = Resources.getResourceAsSteam("splMapConfig.xml");
//获取sql会话
SqlSession sqlSession = SqlSessionFactoryBuilder.build(inputStream).openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//执行查询
/*一对一*/
List<Order> orderList = orderMapper.finUserAndOrder();
for(Order order : orderList){
System.out.println(order)
}
/*一对多*/
List<User> userList = userMapper.findAll();
for(User user : userList){
System.out.println(user)
}
/*多对多*/
List<User> userList = userMapper.findAllUserAndRole();
for(User user : userList){
System.out.println(user)
}
sqlSession.close();
}
Mybatis注解开发
常用注解:使用注解开发前,先介绍以下常用的注解
- @Insert 新增
- @Update 更新
- @Delete 删除
- @Select 查询
- @Result 实现结果集封装。代替了xml中的和标签,有以下属性:
- column 数据库的字段名
- property 对应对象的属性名one 需要使用的@One注解 :@Result( one=@One )
- many 需要使用@Many注解:@Result( many=@Many )
- @Results 可以与@Result一起使用,封装多个结果集
- 代替了xml中的标签,也可以使用@Result集合,使用格式:
@Results({
@Result(),@Result()
})
- @One 一对一结果集封装
代替了标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。有以下属性:
- select 指定用来多表查询的 sqlmapper
@Result(column="",property="",one=@One(select=""))
- @Many 一对多结果集封装
代替了标签,是多表查询的关键,再注解中用来指定子查询返回的对象集合。有以下属性:
- select 指定用来多表查询的 sqlmapper
@Result(column="",property="",one=@Many(select=""))
使用注解一对一查询
public class OrderMapper{
//查询一对一
@Select("select * from order")
@Results({
@Result(id=true,property="id",column="id"),
@Result(property="userId",column="userId"),
@Result(property="orderTime",column="orderTime")
@Result(property="user",column="userId",
javaType=User.class,
one=@One(select="com.xxx.mapper.UserMapper.findById")
)
})
List<Order> finUserAndOrder();
}
public class UserMapper{
@Select("select * from user where id=#{userId}")
User findById(Integer userId);
}
使用注解一对多查询
public class OrderMapper{
@Select("select * from order where userId=#{userId}")
List<Order> findByUserId(Integer userId);
}
public class UserMapper{
//查询一对多
@Select("select * from user")
@Results({
@Result(id=true,property="id",column="id"),
@Result(id=true,property="username",column="username"),
@Result(property="orderList",column="id",
javaType=List.class,
many=@Many(select="com.xxx.mapper.OrderMapper.findByUserId")
})
List<User> findAllUserAndOrder();
}
使用注解多对多查询
public class UserMapper{
//查询多对对
@Select("select * from user")
@Results({
@Result(id=true,property="id",column="id"),
@Result(property="username",column="username"),
@Result(property="roleList",column="id",
javaType=List.class,
many=@Many(select="com.xxx.mapper.RoleMapper.findByUserId"))
})
List<User> findAllUserAndRole();
}
public class RoleMapper{
//查询多对对
@Select("select * from role r,user_role ur where r.id=ur.roleId and ur.userId = #{userId}")
List<Role> findByUserId(Integer userId);
}
结语
以上是对mybatis的基础使用和高级用法,实际项目中,可以结合情况,使用xml查询或者使用两者结合查询都是可行的。
可以的话,麻烦“关注”一下哦。后续文章中,会继续介绍mybatis的缓存和插件机制。
快捷访问:Mybatis一级缓存和二级缓存
相关推荐
- 暗网是什么?到底有多可怕?(暗网有多可怕)
-
https://mp.weixin.qq.com/s/O7l4rveLnXLt-XE2A0WZ3g
- “暗网”是什么,到底有多可怕,互联网的“另外一个世界”
-
来源成戈科技说悄悄告诉你何为“暗网”,暗网的用途是什么?到底多可怕?暗网的英文是“deepnet或deepweb”,也就是深网的意思,我们都知道,南北极的冰川看起来非常雄伟,但是你物理稍微懂一点你就...
- 什么是暗网?暗网有什么用?进来我告诉你
-
网的英文是“deepnet或deepweb”,也就是深网的意思,我们都知道,南北极的冰川看起来非常雄伟,但是你物理稍微懂一点你就会知道,我们看到的只是冰山的10%,还有90%在水面以下,很容易看出来,...
- 网工跳槽必备,2022年最新大厂高频技术面试真题整理
-
2022年金三银四正在进行,很多粉丝问我要网络工程师面试方面的资料,有在学校准备实习的,有已经工作准备跳槽的。我翻看最近的笔记,正好有整理一份今年大厂的面试题分享给大家。可以先说的是,国内的互联网面试...
- 三天吃透操作系统面试八股文(三天吃透计算机网络八股文)
-
操作系统的四个特性?并发:同一段时间内多个程序执行(与并行区分,并行指的是同一时刻有多个事件,多处理器系统可以使程序并行执行)...
- 掌握前端面试八股文,提升个人能力,实战面试必备!
-
前言:前端面试是每个前端开发者职业发展中的重要环节。掌握一些常见的前端面试题目,不仅能够在面试中表现出色,还能够提升自身的技术能力和知识广度。本文将为你介绍一些实用的前端面试题目,帮助你在面试中脱颖而...
- 进大厂必备的Java八股文大全(2022最强精简易懂版)
-
2022年秋招即将来临,很多同学会问Java面试八股文有必要背吗?答案是,必须背,博主是个三本,今年凭借这篇八股文斩获了多个大厂暑期实习offer,相信秋招一定也可以发挥重要作用。你可以讨厌这种模式,...
- 2022最新软件测试八股文,能不能拿心仪Offer就看你背得怎样了
-
前言鉴于目前测试就业越来越严峻,内卷也成了测试领域的代名词了。我的一个HR朋友告诉我,由于门槛较低,现在普通测试岗(偏功能)的投递比已经将近100,也就是一个岗位差不多有百分简历投进来。所以现在还想从...
- 《面试八股文》之Dubbo17卷(面试 八股文)
-
作者:moon原文:https://mp.weixin.qq.com/s/-kVf5qWqcw-4AJF7LL3uWw前言...
- 前端面试八股文?不存在的!(2021前端面试问题)
-
最近刷到一位前端小姐姐海外工作分享的视频,分享了她的求职,面试以及工作生活的感受,了解到海外求职面试的一个过程,其中我们经常聊的...
- 凭借这份《2022测试八股文》候选者逆袭面试官,offer拿到手软
-
《2023测试面试八股文》800道软件测试面试真题,高清打印版打包带走,横扫软件测试面试高频问题,涵盖测试理论、Linux、MySQL、Web测试、接口测试、App测试、Python、Selen...
- 面试常考八股文及算法(一)(八股文的要求)
-
define和const的区别1.define是预处理指令,用于创建符号常量。`const`是C和C++的关键字,用于创建具有常量值的变量,本质是只读变量。2.`define`在预处理阶...
- 面试必备(背)--计算机网络八股文系列
-
1.OSI七层、TCP/IP四层的关系和区别?七层模型,亦称OSI(OpenSystemInterconnection),它是一个七层的、抽象的模型体,不仅包括一系列抽象的术语或概念,也包括...
- Java面试一定要坚持背的八股文!错过会很可惜!
-
很多人对java面试题都嗤之以鼻,认为无法衡量出一个程序员的真实水平。还有一部分原因,也是因为太难背了。那我们到底还要不要背?背!当然要背!但也不是死记硬背。在我们背诵的过程中,就把java的核心知识...
- 面试问八股文的公司都是垃圾?(八股文负面影响)
-
做医生的需要有医师资格证,做财务的有CPA证书,做教师的有教师资格证等等,做程序员的从来没听说过面试的时候需要你提供什么证书,既然没有可以证明从业能力的证书,那面试的时候如何来判断候选人的基本能力呢?...
你 发表评论:
欢迎- 一周热门
-
-
如何解决npm安装依赖报错ERESOLVE unable to resolve dependency tree
-
软件推荐丨gocron —— 定时任务管理系统
-
常见面试第三题之Activity的几种启动模式介绍
-
Vite 4.0 正式发布(vite版本)
-
Ruby on Rails 作者的 WYSIWYG 编辑器 Trix 火了!
-
一个 Python 小项目的小结(python小型项目)
-
岁月静好2015/08月批发榜 批发韩版女装
-
Cordova打包Android应用流程(MAC)
-
有赞技术团队vue开源UI框架vant快速入门
-
0019-Yarn的JobHistory目录权限问题导致MapReduce作业异常
-
- 最近发表
- 标签列表
-
- systemproperties (65)
- canvas图片 (57)
- npm版本管理 (61)
- localhost:15672 (59)
- materialtheme (86)
- node-ssh (68)
- 全局路由守卫 (57)
- 图床搭建 (62)
- vue3addeventlistener (60)
- mybatisselectone (78)
- css圆形进度条 (69)
- androidble蓝牙开发 (62)
- android-gif-drawable (60)
- appender-ref (64)
- springbootmockito (68)
- css边框渐变色和圆角 (58)
- gsonfastjson (59)
- 依赖注入的方式 (62)
- cookie跨域共享 (63)
- easyexcel导出图片 (77)
- dp数组 (61)
- js获取兄弟节点 (68)
- sysctl-a (60)
- java知音 (58)
- window.target (62)