MyBatis 多条件查询、动态SQL、多表操作、注解开发,应有尽有,一网打尽!()

  本篇文章为你整理了MyBatis 多条件查询、动态SQL、多表操作、注解开发,应有尽有,一网打尽!()的详细内容,包含有 MyBatis 多条件查询、动态SQL、多表操作、注解开发,应有尽有,一网打尽!,希望能帮助你了解 MyBatis 多条件查询、动态SQL、多表操作、注解开发,应有尽有,一网打尽!。

  分享Java技术,高并发编程,分布式技术,架构设计,Java面试题,算法,行业动态,程序人生等。

  
来源:iyu77.blog.csdn.net/article/details/125761737

  MyBatis封装了JDBC通过Mapper代理的方式,以前繁琐的操作通过“属性与字段映射”就简单化解,MyBatis的动态SQL完美展现了DBMS的独特魅力

  一、多条件查询

  基于Mybatis的多条件查询,是在Mapper代理的映射文件中写上原有的SQL,然后接口中写一个带参的方法即可,就像这样:

  相比于原生的JDBC那一套,通过MyBatis确实解决了不少硬编码的问题

  但是用户的查询永远是动态的操作,他可能在多个条件中选择其中少量条件进行查询,我们的SQL是死的,而用户需求对应的SQL却是活的,这样就会造成不匹配而形成语法错误

  比如,根据这张表,若是要根据部分字段查出整体,我们可以写对应需求的SQL,但是我要是查询的条件变少了或者变多了呢?若用户只想通过一个条件来查询,那么在其他占位符的位置不输入于是成了null,过不了语法自然查不了,还得重新写SQL,多麻烦

  这个时候MyBatis的特色就体现出来了——动态SQL

  二、动态SQL

  SQL语句会随着用户的输入或者外部条件的变化而变化,则称之为动态SQL

  1. if-where

  因为采用了Mapper代理开发,我们可以通过写xml的形式来编写我们的SQL,动态SQL的特性也就在这一举动中所蕴育,在原有的Mapper文件里我们进行如下改造,让平平无奇的SQL焕然一新:

  

 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所过滤掉了,真是太哇塞了!

  推荐一个开源免费的 Spring Boot 最全教程:

  https://github.com/javastacks/spring-boot-best-practice

  2. choose-when-ortherwise

  对于从多个条件中选择一个的单条件查询的场景,利用分支嵌套就可以实现动态选择单条件:

  在MyBatis的Mapper代理中, 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

  

 

  与多条件查询不同的是,SQL语句中只会有一个分支生效

  当用户一个条件都不选时,可以在 otherwise 中写上1=1让语法成立,反之,若选择了条件则会返回正常结果

  3. foreach

  对于批量删除的场景,传统的方法是通过in关键字结合占位符来确定,就像这样

  

where id in (?,?,?)

 

  

 

  但对于动态的场景,批量的数量永远是不确定的,这就导致还需要去改SQL里的占位符数量啊,又是一件麻烦事

  PS:MyBatis会将数组参数封装成一个Map集合,默认情况(K-V)array=数组

  下面使用了@Param注解改变了map集合中默认的key

  于是MyBatis中的 foreach 解决了这一麻烦:

  本质是通过遍历的形式,批量删除的数据是由id数组或者集合来决定,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. 一对一

  一个用户有一张订单

  首先还是那套路,建好实体类,写好接口方法,配置Mapper文件,而多表操作的麻烦点就在于配置文件,这里通过例子细说一下

  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)

  这两个user有着本质上的却别,就好像前者是在一个人的名字,后者正是被叫的那个人,MyBatis好像就利用了这一特性,通过标签的形式连接了两个实体

  

 select id="findAll" resultMap="orderMap" 

 

   SELECT *,o.id oid FROM orders o,USER u WHERE o.uid=u.id

   /select

  

 

  SQL环节和原来没什么区别,同样也是通过resultMap把字段和属性映射封装。

  2.一对多

  一个用户有多张订单

  首先,在原有的User实体中得加上一个表示“用户有哪些订单的属性”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.多对多

  多用户多角色

  多对多的建表原则是引入一张中间表,用于维护外键,就是一张表通过中间表找到另一张表

  和一对多的模型类似,先在User实体类中增添一个“用户具备哪些角色”的属性private List roleList;其次配置Mapper文件:

  

 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

  

 

  SQL环节就得用多对多的套路了

  

 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

  

 

  回想进行多表操作时MyBatis为我们带来了什么?他确实减少了很多硬编码,我每一次新的SQL只需要在标签里改几个属性就可以,只要理清字段与属性的映射关系,在MyBatis中进行多表操作就是一个“对号入座”。

  四、注解开发

  针对于简单的CRUD注解开发可以极大地提升效率,顾名思义就是把SQL写在注解里

  查询(@Select):

  添加(@Insert):

  修改(@Update):

  删除(@Delete) :

  近期热文推荐:

  1.1,000+ 道 Java面试题及答案整理(2022最新版)

  2.劲爆!Java 协程要来了。。。

  3.Spring Boot 2.x 教程,太全了!

  4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

  5.《Java开发手册(嵩山版)》最新发布,速速下载!

  觉得不错,别忘了随手点赞+转发哦!

  以上就是MyBatis 多条件查询、动态SQL、多表操作、注解开发,应有尽有,一网打尽!()的详细内容,想要了解更多 MyBatis 多条件查询、动态SQL、多表操作、注解开发,应有尽有,一网打尽!的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: