这一篇,老多代码了,我的天。我用了经典的emp表和dept表做演示。加油!打工人。(看到隔壁的铁人为了调休奋战了36小时没睡,我陷入入了沉思)
Mybatis SQL映射
在SQL映射文件中,有需要的顶级元素标签:
--cache – 该命名空间的缓存配置。
--cache-ref – 引用其它命名空间的缓存配置。
--resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
--parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
--sql – 可被其它语句引用的可重用语句块。
--insert – 映射插入语句。
--update – 映射更新语句。
--delete – 映射删除语句。
--select – 映射查询语句。
并且在每个顶级元素标签里,是能添加很多数据的。当然了,常用就那么几个
1、insert、update、delete元素
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符,可以被用来引用这条语句。 |
parameterType |
将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。 |
parameterMap |
用于引用外部 parameterMap 的属性,目前已被废弃。请使用行内参数映射和 parameterType 属性。 |
flushCache |
将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。 |
statementType | 可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
useGeneratedKeys | (仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。 |
keyProperty |
仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset )。如果生成列不止一个,可以用逗号分隔多个属性名称。 |
keyColumn |
(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。 |
databaseId |
如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。 |
不要怕,`useGeneratedKeys`来帮你
insert into user(id,uname,age,gender,hobby) values (#{id},#{uname},#{age},#{gender},#{hobby})
order="BEFORE" keyProperty="id" resultType="integer">
select max(id)+1 from user
insert into user(id,user_name) values(#{id},#{userName})
2、select元素 这个元素是相当的麻烦,麻烦就麻烦这个顶级元素上了。秀到飞起
1、当查询语句的时候,一般我们都会动态的将属性添加到sql语句中,在Mybatis中当然也一样了
id="selectEmpById" resultType="com.kaisi.bean.Emp">
select * from emp where empno = #{qwer}
为什么引用数据类型就不行了呢?
/*
在Emp的接口中,我也是根据empno进行查询对象,但是我单参数传入的却是一个对象
(可以确定是引用类型对吧!)
那么在sql映射的配置文件 EmpDao.xml中对应的sql语句是否可以#{jqk或qwe}随便写?
测试就会发现,不能了,因为当参数为一个对象的时候,是根据具体的属性名来确定从对象中的那个属性来取到需要数值
*/
public Emp selectByEmp(Emp emp);
xml文件sql如下
id="selectByEmp" resultType="com.kaisi.bean.Emp">
select * from emp where empno = #{empno}
在SQL映射文件中单参数验证完毕后,就需要验证多参数传递了
//接口定义,多参数
public Emp selectByBoth(Integer empno,Double sal);
id="selectByBoth" resultType="com.kaisi.bean.Emp">
select * from emp where empno=#{arg0} and sal>#{arg1}
【MyBatis打工人——sql配置文件详解】当然了,你如果觉得上面这种arg或者param比较low,你也可以用注解的形式
public Emp selectByBoth(@Param("empno") Integer empno,@Param("sal") Double sal);
测试类以及测试结果:想用哪种用哪种,随自己的心情
文章图片
参数的取值方式(插一嘴) 在xml中我们是有俩种取值方式的一种是${}一种是#{}
id="selectEmpByNoAndName" resultType="com.kaisi.bean.Emp">
select * from ${t} where empno=#{empno} and ename=${ename}
自定义结果集 当出现数据库表字段与实体类的属性不不应的时候,是无法直接进行映射的,那么就需要自定义结果集了
例如:在表中的列 我全部加了d当做开头
文章图片
//在Java中我定义的属性却是没有d开头的(能自动映射上才是遇到鬼了)
private Integer id;
private String name;
private Integer age;
private String gender;
那么 就需要我们自定义结果集来进行属性和列的映射关系
id="selectById" resultMap="myDog">
select * from dog where id=#{qweqw}
在resultMap标签中还有俩个特殊的子标签association和collection
现在进行代码演示,association的用法
步骤:在Emp实体类中加入dept对象属性,那么在查询当前员工信息的时候并且查询到员工的部门信息
id="selectEmpAndDept" resultMap="empDept">
select * from emp e left join dept d on e.deptno = d.deptno where e.empno=#{empnoxx}
id="selectEmpAndDept2" resultMap="empDept2">
select * from emp leftjoin dept on emp.deptno=dept.deptno where emp.empno=#{empno}
呼呼,下面开始collocation标签的用法
这里的步骤:在Dept表中加入Emp对象属性,采用一对多的关系,查询部门下所有员工信息以及部门信息
="selectDeptAndEmp" resultMap="DeptEmp">
select * from emp left join dept on dept.deptno=emp.deptno where dept.deptno=#{deptno}
分步查询 和关联查询结果一样,但是更加灵活。这给大家写个Mybatis中分步查询的案例
老规矩:需要以下食材:
1、实体类俩份,一份Emp,一份Dept
2、全局配置xml文件一份(上一篇有写)
3、接口俩个EmpDao和DeptDao
4、sql配置文件俩 EmpDao.xml文件和DeptDao.xml文件
起锅烧油:开始
菜系:查询Emp表中某员工信息并且附带此员工的部门信息
一:
在EmpDao接口中
//我先查出这个员工信息,因为员工信息是有部门编号的
public Emp selectByStep(Integer empno);
在DeptDao接口中
//既然是分步,那么这个dept的部门编号是从员工信息中获取的才是
public Dept selectDeptByStep(Integer deptno);
DeptDao.xml文件配置如下
id="selectDeptByStep" resultType="com.kaisi.bean.Dept">
select * from dept where deptno=#{deptno}
EmpDap.xml文件配置如下
id="selectByStep" resultMap="empStep">
select * from emp where empno=#{empno}
从下面结果就可以看出,我调用了一个接口方法,但是sql语句执行了俩条,并且把结果都组合成新的结果集并且返回。
这就是分步查询:好处:海量数据下表关联查询效率会降低,分步查询效率此时会高于表连接查询
但是在表中数据量比较小的情况下,关联查询和分步查询的效率就没有很大的区别了;
但是分步查询有个好处,就是可以延迟查询
文章图片
延迟查询 延迟查询的开启只需要再全局配置文件中加入
>name="mapUnderscoreToCamelCase" value="https://www.it610.com/article/true"/>name="lazyLoadingEnabled" value="https://www.it610.com/article/true"/>
分析结果:当开启懒加载后,我们在调用的时候只是使用了dept表的中的dname属性,并不需要emp表中的数据,那么减少数据库压力,当然是越少执行越好,这就是懒加载的好处。
文章图片
下面我把懒加载关闭,再看结果
>name="mapUnderscoreToCamelCase" value="https://www.it610.com/article/true"/>name="lazyLoadingEnabled" value="https://www.it610.com/article/false"/>
相同的调用,关闭懒加载却执行了分步查询的所有sql(是基于刚刚分步的基础上做的,俩俩配合使用奇妙的味道)
文章图片
推荐阅读
- #|Mybatis的if else妙用(Choose标签使用)
- 框架大集合|【MyBatis详解】——动态SQL解析与执行原理
- java|java基础巩固16
- MyBatis|SpringBoot & Mybatis-Plus实现多数据源的方法
- Spring|SpringBoot整合常用组件
- Maven|Maven进阶实战
- 框架|SpringBoot基础篇 (4)—SSMP整合案例
- mybatis|mybatis日期查询的坑(具体查询某一天的数据,数据库中能查询到结果,但是mybatis中却查询不到)
- SSM框架解析|【SSM框架】Mybatis详解10(源码自取)之入参、返回值map