1.sql标签

公共sql块,一般用在查询字段上.

<sql id="allFields">uid,uname,uemail,upwd,uphone,create_time,update_time
</sql>

在select标签中通过include包含sql块

<select id="selectByKey" resultType="sysuser">select<include refid="allFields"></include>from sysuser where uid=#{uid}
</select>

2.resultMap标签(重要)

ResultMap标签使用起来偏复杂,用来对实体对象的属性与数据库字段名做映射,同时提供子标签做对象之间的关系映射,进行级联查询操作。

ResultMap 的设计思想是,对于简单的语句不需要配置显式的结果映射(属性名与字段名一致),而对于复杂一点的语句只需要描述它们的关系就行了。

结果集映射标签,把数据库中的字段名映射到某个实体类的成员变量.

     <!-- id结果集名称 type结果集映射的实体类-->
<resultMap id="sysuserMap" type="sysuser"><!--coleumn列名 property属性名--><id column="uid" property="uid"></id><result column="user_address" property="uaddress"/><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result>
</resultMap>相同字段可以不写

如果字段名与属性名相同,可省了配置,但id不能省.一般都全部配置.

语句中使用resultMap在标签中的resultType更改成resultMap="sysuserMap"

<!--select标签的resultMap属性的值对应resultMap标签的id-->
<select id="selectUserById" parameterType="int" resultMap="sysuserMap">select * from sysuser where uid=#{uid}
</select>

注意:

​ 1.select标签的resultMap属性与resultType属性不能同时出现,resultType属性的值一般是实体类map或简单型;

​ 2.resultMap属性的值必须是resultMap标签的id值。

​ 3.resultMap标签的id子标签用来进行主键列映射;result子标签进行非主键列映射;

3.对象关系映射(重要)

对象之间的关系:分为持有聚合

1.多对一持有关系(用个用户持有一个角色)

A对象持有B对象的引用,A类中有一个成员变量是B类型的.

比如:用户对象持有角色对象,查询用户的时候,查询出用户的角色信息.

方法1:手工进行两次的单表查询,第一次查询用户,第二次查询角色,把查询结果组合起来.掌握(建议)

  • 创建SysuserMapper.java与sysuserMapper.xml
public interface SysuserMapper {public Sysuser selectUserByKey(Integer uid);
}<select id="selectUserByKey" parameterType="int" resultType="Sysuser">select * from sysuser where uid=#{uid}
</select>
  • 创建SysroleMapper.java与sysroleMapper.xml
public interface SysroleMapper {public Sysrole selectRoleByRid(Integer rid);
}<select id="selectRoleByRid" parameterType="int" resultType="sysrole">select * from sysrole where rid=#{rid}
</select>
  • 测试,结果组合
SysRoleMapper rm = session.getMapper(SysRoleMapper.class);
SysUserMapper2 um = session.getMapper(SysUserMapper2.class);
//第一次查询用户
Sysuser sysuser = um.selectUserByKey(13);
//第二次查询该用户的角色
Sysrole sysrole = rm.selectRoleByKey(sysuser.getRid());
//组装对象
sysuser.setSrole(sysrole);

方法2:由mybatis进行两次单表查询,使用association标签指定二次查询的位置.掌握(两个mapper.两个映射文件)

property:持有对象的变量名 column:传入二次查询的参数的字段

javaType:持有对象的类型 ,二次查询返回值的类型 select : 二次查询的位置(namespace+id )

<!--select:二次查询的位置namespace.idsrole:持有对象的变量名javaType:持有对象的类型,二次查询的返回值类型column:传入二次查询的字段,二次查询需要的参数-->
<association property="srole" column="rid" javaType="sysrole"select="com.javasm.mapper.SysroleMapper.selectByKey"></association><resultMap id="sysuserAndRoleMap" type="sysuser"><id column="uid" property="uid"></id><result column="uname" property="uname"></result><result column="uemail" property="uemail"></result><result column="uphone" property="uphone"></result><result column="upwd" property="uped"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result><association property="srole" column="rid" javaType="sysrole"                                          select="com.javasm.mapper.SysRoleMapper.selectRoleByKey"></association>
</resultMap><select id="selectUserAndRoleByUKey" resultMap="sysuserAndRoleMap">select * from sysuser where uid = #{uid}
</select>
//角色映射文件中
<select id="selectRoleByKey" parameterType="int" resultType="sysrole">select *  from sysrole where rid = #{rid}
</select>

方法3:使用sql语句表级联查询,一次需要的列全查出来,不需要进行二次查询.association不推荐使用(单表操作索引生效,夺多表操作索引失效)复杂的报表分析可以使用(当使用在报表分析的时候直接返回map)

<resultMap id="sysuserAndRoleMap2" type="sysuser"><id column="uid" property="uid"></id><result column="uname" property="uname"></result><result column="uemail" property="uemail"></result><result column="uphone" property="uphone"></result><result column="upwd" property="uped"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result><association property="srole" javaType="sysrole" ><id column="rid" property="rid"></id><result column="rname" property="rname"></result><result column="rdec" property="rdec"></result><result column="roleCreateTime" property="createTime"></result><result column="roleUpdateTime" property="updateTime"></result></association>
</resultMap><select id="selectUserAndRoleByUKey2" resultMap="sysuserAndRoleMap2">select u.*,r.rname,r.rdec,r.create_time,r.update_time as roleCreateTime,r.update_time as     roleUpdateTime from  sysuser u,sysrole r where u.rid=r.rid and u.uid=#{uid}
</select>

2.聚合关系(一个角色聚合了多个用户)

A对象持有了B对象的集合,A类中有一个List集合,集合泛型是B类型的.比如:角色对象聚合了用户对象,查询角色并查询出该角色下的所有用户信息.

使用collection标签进行聚合映射

方法1:手工进行两次的单表查询,把查询结果组合起来.掌握(建议)

方法2:由mybatis进行两次单表查询,使用association标签指定二次查询的位置.掌握(两个mapper.两个映射文件)

<resultMap id="roleAndUsersMap" type="sysrole"><id column="rid" property="rid"></id><result column="rname" property="rname"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result><collection property="susers" ofType="sysuser" column="rid" select="com.javasm.mapper.SysUserMapper2.selectUsersByRoleId"></collection>
</resultMap>
<select id="selectRoleAndUserByRid" resultMap="roleAndUsersMap" parameterType="int">select *  from sysrole where rid=#{rid};
</select>//另外一个映射文件
<resultMap id="sysuserMap" type="sysuser"><id column="uid" property="uid"></id><result column="uname" property="uname"></result><result column="uemail" property="uemail"></result><result column="uphone" property="uphone"></result><result column="upwd" property="upwd"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result>
</resultMap>
<select id="selectUsersByRoleId" parameterType="int" resultMap="sysuserMap">select * from sysuser where rid=#{rid}
</select>

方法3:使用sql语句表级联查询,一次需要的列全查出来,不需要进行二次查询.collection

property:持有对象的变量名 javaType:只有两种list或者set
ofType:集合的泛型类型是什么 column:传入入二次查询的参数的字段

<!--ofType:集合的泛型类型-->
<collection property="susers" ofType="sysuser" column="rid" select="com.javasm.mapper.SysuserMapper2.selectUsersByRoleId"></collection>
<resultMap id="roleAndUsersMap2" type="sysrole"><id column="rid" property="rid"></id><result column="rname" property="rname"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result><collection property="susers" ofType="sysuser"><id column="uid" property="uid"></id><result column="uname" property="uname"></result><result column="ctime" property="createTime"></result><result column="utime" property="updateTime"></result></collection>
</resultMap><select id="selectRoleAndUserByRid2" resultMap="roleAndUsersMap2" parameterType="int">select r.*,u.uid,u.uname,u.uphone,u.uemail,u.create_time as ctime,u.update_time as utime from sysrole r,sysuser u where r.rid=u.rid and r.rid =#{rid}</select>

4.动态sql语句(重要)

在映射文件中进行sql语句拼接.

if/where标签
  • if:用来做条件判断
  • where:用来生成where关键字.并忽略紧跟其后的and或or如果if都为null或者’'那么这个where标签不会添加where
<select id="selectUsers" parameterType="sysuser" resultType="sysuser">select uid,uname,uphone,upwd,uemail,create_time,update_time from sysuser<where><if test="uname!=null and uname!=''">and  uname=#{uname}</if><if test="uphone!=null and uphone!=''">and uphone=#{uphone}</if><if test="uemail!=null and uemail!=''">and  uemail=#{uemail}</if><!--  如果查询的字段是Intger类型则不用写and uphone!=''<if test="uphone!=null">uphone=#{uphone}</if>--></where>order by update_time desc
</select>
set标签
  • set:用来生成set关键字,update语法.并忽略最后的逗号,
<update id="updateUser" parameterType="sysuser">update sysuser<set>/*修改不用写uname!=''因为可能前端想故意把字段写为''空*/<if test="uname!=null">uname=#{uname},</if><if test="uphone!=null">uphone=#{uphone},</if></set>where uid=#{uid}
</update>
foreach标签
  • foreach:用来做批量删除
     int delUsers(List<Integer> uids);批量删除,=========================================================
方法一   | List<Integer> uids    :mybatis底层把List封装成map,默认key是<list>
方法二   | Integer[] uids      :mybatis底层把数组封装成map,默认key是<array>
方法三   | 用@Param("uids")注解自定义key

collection – 传递参数类型list/array/自定义key index – 循环索引

item – 集合中的元素 open –以什么开始; close – 以什么结束

<delete id="delUsers" parameterType="map">DELETE FROM sysuser WHERE uid in <foreach collection="list" open="(" close=")" item="uid_item" separator=",">#{uid_item}</foreach>
</delete>
  • 批量增加
 int addUsers(@Param("users") Sysuser[] users);
<insert id="addUsers" parameterType="map">insert into sysuser(uname,uphone) values<foreach collection="users" separator="," item="user">//没有开始和关闭,自己写(#{user.uname},#{user.uphone})</foreach>
</insert>
choose-when-otherwis标签
  • choose-when-otherwise:单条件查询,没用.

只会有一个when条件成立如果没有一个when条件成立那么会执行otherwise标签内容

<select id="selectUsers2" parameterType="sysuser" resultType="sysuser">select uid,uname,uphone,upwd,uemail,create_time,update_time from sysuser<where><choose><when test="uname!=null and uname!=''">and  uname=#{uname}</when><when test="uphone!=null and uphone!=''">and uphone=#{uphone}</when><otherwise>1=1</otherwise></choose></where>order by update_time desc
</select>

5.mybatis的延迟加载,不重要

mybatis中的延迟加载仅在有二次查询的场景下生效.

延迟加载目的:减少无效的数据库查询操作,提高响应的效率.

延迟加载:分页,树形结构数据,前端图片的延迟加载

开启延迟加载时需要配置的setting

<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--启用延迟加载-->
<setting name="lazyLoadingEnabled" value="true"></setting>
<!--消极加载,只有当调用二级查询的字段时才加载-->
<setting name="aggressiveLazyLoading" value="false"></setting>
<!-- value值从equals,clone,hashCode,toString中选取如果以上些行为均不想触发则写上空格-->
<setting name="lazyLoadTriggerMethods" value=""></setting>

6.mybatis缓存,不重要

cache:减少数据库的重复查询操作.基于内存把第一次查询的结果保存的缓存对象中,当后续查询时,先查询缓存,缓存中有则返回;缓存中没有则查询数据库,并把查询结果放缓存.

mybatis的缓存分为两级:

session级别缓存:默认开启.在同一个session会话中发起相同的查询.

factory级别缓存:默认未开启.可以做到不同会话之间共享缓存数据.

开启factory二级缓存的步骤

  1. 在配置文件中添加settings
<setting name="cacheEnabled" value="true"></setting>
  1. 在对应的映射文件中做缓存策略配置
<!--缓存策略,只对当前namespace下的所有查询全部生效,
可以在用户查询概率较少的select标签中加useCache="false"禁用二级缓存,
可以在update,delete中使用flushCache="true"强制清空缓存-->
<cacheeviction="FIFO"                 FIFO先进先出策略|LRU最近最少使用flushInterval="60000"                60秒清楚所有缓存size="512"                      最大保存记录条数readOnly="true"/>                 只读

mybatis进阶(动态sql、关系映射、延迟加载、缓存)相关推荐

  1. MyBatis 接口绑定方案及多参数传递、动态 SQL、ThreadLocal、缓存

    一.MyBatis 接口绑定方案及多参数传递 作用:实现创建一个接口后把mapper.xml由mybatis 生成接口的实现 类,通过调用接口对象就可以获取 mapper.xml 中编写的 sql. ...

  2. 9、mybatis中动态sql的使用

    对于初学者,如何进行mybatis的学习呢?我总结了几点,会慢慢的更新出来.首先大家需要了解mybatis是什么.用mybatis来做什么.为什么要用mybatis.有什么优缺点:当知道了为什么的时候 ...

  3. java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】...

    第1章 Mybatis 连接池与事务深入 1.1 Mybatis 的连接池技术 1.1.1 Mybatis 连接池的分类 1.1.2 Mybatis 中数据源的配置 1.1.3 Mybatis 中 D ...

  4. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

  5. 利用MyBatis的动态SQL特性抽象统一SQL查询接口

    1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...

  6. 2022/5/1 Mybatis框架动态SQL

    目录 1丶动态 SQL 2丶if标签 3丶choose.when.otherwise 4丶trim.where.set 5丶foreach 6丶script 7丶bind 8丶多数据库支持 9丶动态 ...

  7. MyBatis 03 动态SQL

    MyBatis 03 动态SQL 文章目录 MyBatis 03 动态SQL 一.学习目标 二.动态SQL if 标签2-1 if 标签2-2 where标签2-1 where 标签2-2 choos ...

  8. Mybatis学习-动态SQL

    Mybatis学习-动态SQL Mybatis学习-动态SQL Mybatis学习-动态SQL 什么是动态SQL 搭建环境 IF 接口 Mapper 测试 trim (where, set) wher ...

  9. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有:   if choose(when,otherwis ...

  10. MyBatis中动态sql实现时间范围比较的查询

    场景 前端传递两个时间参数,开始时间和结束时间,然后从数据库中筛选出某个时间属性在此范围的数据. Mybatis的动态sql的写法. 注: 博客: https://blog.csdn.net/bada ...

最新文章

  1. Flask环境的配置
  2. 腾讯财报:业务换防,谁来扛起未来发展的大旗?
  3. python怎么网络通信_深入Python中的网络通信
  4. C#中实现视频播放器窗体程序(附源码下载)
  5. AspectJ的实现机制
  6. C语言九十三之输入一个字符x,找到输入的那句话(字符串)里面一样字母的位置。
  7. Windows 下安装 laravel框架
  8. ThinkPHP3.2.3执行页面循环案例代码(部分)
  9. 精通 Oracle+Python,第 4 部分:事务和大型对象
  10. Logback MDC
  11. 第八篇:ZTree操作总结
  12. puppet安装与使用--模块结构(iptables与rsync模块)
  13. 银联在线支付B2C UnionPay.NET
  14. 计算机应用基础配书光盘,计算机应用基础配书光盘系统客户端
  15. 皮克定理,多边形面积以及线段上整点个数
  16. Perl/Tkx ---- tcl/tk文本组件text
  17. 怎么去掉input textarea 选中后的边线框,textarea 不可以拉
  18. 手机控制的esp8266利用mqtt协议接入百度云智能插座
  19. KubeVela 云原生时代的应用管理平台
  20. dbeaver连接gaussdb

热门文章

  1. 纪念硕士论文圆满答辩结束——20180614
  2. android圆图,Android实现圆形图片或者圆角图片
  3. java并发编程(12)-- 线程池 实际⽣产使⽤哪⼀个线程池 怎么设置
  4. Hyperledger Fabric Composer安装blockchain explorer
  5. thinkphp 按指定字段统计数据条数
  6. android不是16位,16位图像和Android处理
  7. LeetCode之Z字形变换
  8. linux进程挂起的原因6,linux – 如何找出ssh进程挂起的原因?
  9. 进来偷学一招,数据归档二三事儿
  10. 阶段3 1.Mybatis_05.使用Mybatis完成CRUD_5 Mybatis的CRUD-查询返回一行一列和占位符分析...