MyBatis打工人——sql配置文件详解

	这一篇,老多代码了,我的天。我用了经典的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 id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into user(id,uname,age,gender,hobby) values (#{id},#{uname},#{age},#{gender},#{hobby})
    insert>
	
    <insert id="insertUser2" >
        <selectKey order="BEFORE" keyProperty="id" resultType="integer">
            select max(id)+1 from user
        selectKey>
        insert into user(id,user_name) values(#{id},#{userName})
    insert>
	

2、select元素

这个元素是相当的麻烦,麻烦就麻烦这个顶级元素上了。秀到飞起

1、当查询语句的时候,一般我们都会动态的将属性添加到sql语句中,在Mybatis中当然也一样了

 
 <select id="selectEmpById" resultType="com.kaisi.bean.Emp">
        select * from emp where empno = #{qwer}
  select>
 

为什么引用数据类型就不行了呢?

/*
在Emp的接口中,我也是根据empno进行查询对象,但是我单参数传入的却是一个对象
(可以确定是引用类型对吧!)
那么在sql映射的配置文件 EmpDao.xml中对应的sql语句是否可以#{jqk或qwe}随便写?
测试就会发现,不能了,因为当参数为一个对象的时候,是根据具体的属性名来确定从对象中的那个属性来取到需要数值
*/
public Emp selectByEmp(Emp emp);

xml文件sql如下

 
<select id="selectByEmp" resultType="com.kaisi.bean.Emp">
        select * from emp where empno = #{empno}
  select>

在SQL映射文件中单参数验证完毕后,就需要验证多参数传递了

//接口定义,多参数
public Emp selectByBoth(Integer empno,Double sal);
	
    
    <select id="selectByBoth" resultType="com.kaisi.bean.Emp">
        select * from emp where empno=#{arg0} and sal>#{arg1}
    select>

当然了,你如果觉得上面这种arg或者param比较low,你也可以用注解的形式

public Emp selectByBoth(@Param("empno") Integer empno,@Param("sal") Double sal);

测试类以及测试结果:想用哪种用哪种,随自己的心情
MyBatis打工人——sql配置文件详解_第1张图片

参数的取值方式(插一嘴)

在xml中我们是有俩种取值方式的一种是${}一种是#{}

 
    <select id="selectEmpByNoAndName" resultType="com.kaisi.bean.Emp">
        select * from ${t} where empno=#{empno} and ename=${ename}
    select>

自定义结果集

当出现数据库表字段与实体类的属性不不应的时候,是无法直接进行映射的,那么就需要自定义结果集了

例如:在表中的列 我全部加了d当做开头
在这里插入图片描述

//在Java中我定义的属性却是没有d开头的(能自动映射上才是遇到鬼了)
	private Integer id;
    private String name;
    private Integer age;
    private String gender;

那么 就需要我们自定义结果集来进行属性和列的映射关系

<mapper namespace="com.kaisi.dao.DogDao">
    
    <resultMap id="myDog" type="com.kaisi.bean.Dog">
        <id property="id" column="id">id>
        <result property="name" column="dname">result>
        <result property="age" column="dage">result>
        <result property="gender" column="dgender">result>
    resultMap>
   <select id="selectById" resultMap="myDog">
       select * from dog where id=#{qweqw}
   select>
mapper>

在resultMap标签中还有俩个特殊的子标签association和collection
现在进行代码演示,association的用法
步骤:在Emp实体类中加入dept对象属性,那么在查询当前员工信息的时候并且查询到员工的部门信息


    
<resultMap id="empDept" type="com.kaisi.bean.Emp">
        <id column="empno" property="empno">id>
        <result column="ename" property="ename">result>
        <result column="job" property="job">result>
        <result column="mgr" property="mgr">result>
        <result column="hiredate" property="hiredate">result>
        <result column="sal" property="sal">result>
        <result column="comm" property="common">result>
        <result column="deptno" property="dept.deptno">result>
        <result column="dname" property="dept.dname">result>
        <result column="loc" property="dept.loc">result>
    resultMap>
    <select id="selectEmpAndDept" resultMap="empDept">
        select * from emp e left join dept d on e.deptno = d.deptno where e.empno=#{empnoxx}
    select>

 <resultMap id="empDept2" type="com.kaisi.bean.Emp">
        <id column="empno" property="empno">id>
        <result column="ename" property="ename">result>
        <result column="job" property="job">result>
        <result column="mgr" property="mgr">result>
        <result column="hiredate" property="hiredate">result>
        <result column="sal" property="sal">result>
        <result column="comm" property="common">result>
        <result column="deptno" property="deptno">result>
        <association property="dept" javaType="com.kaisi.bean.Dept">
            <id column="deptno" property="deptno">id>
            <result column="loc" property="loc">result>
            <result column="dname" property="dname">result>
        association>
    resultMap>
    <select id="selectEmpAndDept2" resultMap="empDept2">
        select * from emp left  join dept on emp.deptno=dept.deptno where emp.empno=#{empno}
    select>

呼呼,下面开始collocation标签的用法
这里的步骤:在Dept表中加入Emp对象属性,采用一对多的关系,查询部门下所有员工信息以及部门信息

<!--
    开始进行一对多的表与属性映射:也就是将从数据库中查到的数据一一映射到实体类中
    唉西;这种一对多,演示中,一个部门会有多个员工,那么就需要另一个标签,collection。用于
    在collection标签中,有一个ofType属性:指定集合中的元素类型
    -->
    <resultMap id="DeptEmp" type="com.kaisi.bean.Dept">
        <id property="deptno" column="deptno"></id>
        <result property="dname" column="dname"></result>
        <result property="loc" column="loc"></result>
        <collection property="emps" ofType="com.kaisi.bean.Emp">
            <id column="empno" property="empno"></id>
            <result column="ename" property="ename"></result>
            <result column="job" property="job"></result>
            <result column="mgr" property="mgr"></result>
            <result column="hiredate" property="hiredate"></result>
            <result column="sal" property="sal"></result>
            <result column="comm" property="common"></result>
            <result column="deptno" property="deptno"></result>
        </collection>
    </resultMap>
    <select id="selectDeptAndEmp" resultMap="DeptEmp">
        select * from emp left join dept on dept.deptno=emp.deptno where dept.deptno=#{deptno}
    </select>

分步查询

和关联查询结果一样,但是更加灵活。这给大家写个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文件配置如下

  
    <select id="selectDeptByStep" resultType="com.kaisi.bean.Dept">
        select * from dept where deptno=#{deptno}
    select>

EmpDap.xml文件配置如下

 <resultMap id="empStep" type="com.kaisi.bean.Emp">
        <id column="empno" property="empno">id>
        <result column="ename" property="ename">result>
        <result column="job" property="job">result>
        <result column="mgr" property="mgr">result>
        <result column="hiredate" property="hiredate">result>
        <result column="sal" property="sal">result>
        <result column="comm" property="comm">result>
        <result column="deptno" property="deptno">result>
        <association property="dept"  select="com.kaisi.dao.DeptDao.selectDeptByStep" column="deptno">association>
    resultMap>
    <select id="selectByStep" resultMap="empStep">
        select * from emp where empno=#{empno}
    select>

从下面结果就可以看出,我调用了一个接口方法,但是sql语句执行了俩条,并且把结果都组合成新的结果集并且返回。
这就是分步查询:好处:海量数据下表关联查询效率会降低,分步查询效率此时会高于表连接查询
但是在表中数据量比较小的情况下,关联查询和分步查询的效率就没有很大的区别了;
但是分步查询有个好处,就是可以延迟查询
MyBatis打工人——sql配置文件详解_第2张图片

延迟查询

延迟查询的开启只需要再全局配置文件中加入

	<settings>
        
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        
        <setting name="lazyLoadingEnabled" value="true"/>
       
    settings>

分析结果:当开启懒加载后,我们在调用的时候只是使用了dept表的中的dname属性,并不需要emp表中的数据,那么减少数据库压力,当然是越少执行越好,这就是懒加载的好处。
MyBatis打工人——sql配置文件详解_第3张图片

下面我把懒加载关闭,再看结果

<settings>
        
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        
        <setting name="lazyLoadingEnabled" value="false"/>
       
    settings>

相同的调用,关闭懒加载却执行了分步查询的所有sql(是基于刚刚分步的基础上做的,俩俩配合使用奇妙的味道)
MyBatis打工人——sql配置文件详解_第4张图片

你可能感兴趣的:(mybatis)