),就像我所在的公司,要求入职要会Mybatis。在前面也有Mybatis的几篇文章《mybatis 介绍合集》,今天来介绍Mybatis的一些高级技巧,也算是对mybatis用法的补充。一、多条件查询
二、动态SQL
三、多表操作
四、注解开发
MyBatis封装了JDBC通过Mapper代理的方式,以前繁琐的操作通过“属性与字段映射”就简单化解,MyBatis的动态SQL完美展现了DBMS的独特魅力
一、多条件查询
基于Mybatis的多条件查询,是在Mapper代理的映射文件中写上原有的SQL,然后接口中写一个带参的方法即可,就像这样:

但是用户的查询永远是动态的操作,他可能在多个条件中选择其中少量条件进行查询,我们的SQL是死的,而用户需求对应的SQL却是活的,这样就会造成不匹配而形成语法错误
比如,根据这张表,若是要根据部分字段查出整体,我们可以写对应需求的SQL,但是我要是查询的条件变少了或者变多了呢?若用户只想通过一个条件来查询,那么在其他占位符的位置不输入于是成了null,过不了语法自然查不了,还得重新写SQL,多麻烦

二、动态SQL
1. if-where
<select id="selByCondition" resultMap="rm">
select *
from mybatis
<where>
<if test="status !=null">
and STATUS=#{STATUS}
</if>
<if test="companyName !=null and companyName !=''">
and company_name like #{companyName}
</if>
<if test="bracdName !=null and bracdName !=''">
and bracd_name like #{bracdName}
</if>
</where>
</select>
<where>标签可以自动帮我们去掉and”,这样,不管查询的条件怎么变,我跟着这个逻辑流程走就不会出现SQL语法毛病而导致查询不出来的毛病啦,因为null的情况已经被if所过滤掉了,真是太哇塞了!
2. choose-when-ortherwise
<choose>相当于switch,
<when>相当于case
<select id="selByCondition2" resultMap="rm">
select *
from mybatis where
<choose>
<when test="status !=null">
STATUS=#{STATUS}
</when>
<when test="companyName !=null and companyName !=''">
company_name like #{companyName}
</when>
<when test="bracdName !=null and bracdName !=''">
bracd_name like #{bracdName}
</when>
<otherwise>1=1</otherwise>
</choose>
</select>
<otherwise>中写上
1=1让语法成立,反之,若选择了条件则会返回正常结果
3. foreach
对于批量删除的场景,传统的方法是通过in关键字结合占位符来确定,就像这样
where id in (?,?,?)
PS:MyBatis会将数组参数封装成一个Map集合,默认情况(K-V)array=数组
下面使用了@Param
注解改变了map集合中默认的key

<foreach>解决了这一麻烦:
collection属性决定了要遍历哪个数组/集合,item属性则来存放选出的元素,并把它放在占位符里,
separator属性表示分隔符
<delete id="deleteById">
delete frpm mybatis where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>;
</delete>
#{id},我的属性字段不止这一个呀?此id非彼id他是一个数组/集合
三、多表操作
多表之间的关系有一对一,一对多,多对一,多对多,每一种都有建表的原则,以用户-订单模型为例
利用传统的方法进行多表查询无非是通过id来连接表然后封装返回结果,MyBatis中也是如此,我们在Mapper文件中写好表字段之间的映射关系,定义好类型即可,只不过这一过程有点复杂,但一次配好之后即可极大减少硬编码问题,提高效率
1. 一对一

1.先把表写好
CREATE TABLE orders (
id INT PRIMARY KEY ,
ordertime VARCHAR(20) NOT NULL DEFAULT '',
total DOUBLE,
uid INT);
INSERT INTO orders VALUES(1,2020,2000,1);
INSERT INTO orders VALUES(2,2021,3000,2);
INSERT INTO orders VALUES(3,2022,4000,3);
CREATE TABLE USER (
id INT PRIMARY KEY ,
username VARCHAR(50) NOT NULL DEFAULT '',
passwords VARCHAR(50) NOT NULL DEFAULT '');
INSERT INTO USER VALUES(1,'lyy',333);
INSERT INTO USER VALUES(2,'myy',444);
INSERT INTO USER VALUES(3,'xyy',555);
2.写Mapper配置文件
private User user;这一属性,这样根据id连接的两个实体才能完美对接!

<association>把两张表对应的实体类连接起来,只不过是主键ID要用单独的标签
property
: 当前实体(order)中的属性名称(private User user)javaType
: 当前实体(order)中的属性的类型(User)
<select id="findAll" resultMap="orderMap">
SELECT *,o.id oid FROM orders o,USER u WHERE o.uid=u.id
</select>
resultMap把字段和属性映射封装。
2.一对多
一个用户有多张订单

private List<Order> orderList;,目的是为了把订单的信息封装到用户的这个属性里,在Mapper文件中体现:
<collection property="orderList" ofType="order">
<!--封装order的数据-->
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
</collection>
property
:集合名称,User实体中的orderlist属性ofType
:当前集合中的数据类型,就是order实体
然后就是写一对多的SQL:
<select id="findAll" resultMap="userMap">
SELECT *,o.id oid FROM USER u,orders o WHERE u.id=o.uid
</select>
总结来看,一对多相比于一对一就是在那个“一”中增添了封装“多”的属性而已,然后稍微调整一下SQL
3.多对多
多用户多角色

多对多的建表原则是引入一张中间表,用于维护外键,就是一张表通过中间表找到另一张表
<collection property="roleList" ofType="role">
<id column="roleId" property="id"></id>
<result column="roleName" property="roleName"></result>
<result column="roleDesc" property="roleDesc"></result>
</collection>
多表的连接是靠中间表,这点在Mapper文件中通过映射实现,具体是把两张外表的id(userId和roleId)在id标签中配置成同一个属性,就像这样:
<id column="userId" property="id"></id>
<id column="roleId" property="id"></id>
<select id="findUserAndRoleAll" resultMap="userRoleMap">
SELECT * FROM USER u,user-role ur,role r WHERE u.id=ur.userId AND ur.roleId=r.id
</select>
四、注解开发
针对于简单的CRUD注解开发可以极大地提升效率,顾名思义就是把SQL写在注解里
查询(@Select):


修改(@Update):

删除(@Delete) :

往 期 精 彩
Java开发实践总结系列 面试官:听说你熟练掌握SpringMVC,咱来好好聊下(超全的SpringMVC的40个注解) 电商系统:以一个订单服务为例来讲讲如何设计一个基础服务 程序员如何成为架构师? 电商系列:自动关闭订单的方式有那些? Spring Boot 实现接口幂等性的 4 种方式 MyBatis使用技巧:如何实现数据存储的保密性? 以终为始:如何让你的开发符合预期
每天分享干货文章,帮你筛选,让你随时了解
技术行业的动态,欢迎关注




