MyBatis3-映射文件

三.映射文件

>映射文件指导着MyBatis如何进行数据库增删改查,

有着非常重要的意义;
•resultMap – 自定义结果集映射
•insert – 映射插入语句
•update – 映射更新语句
•delete – 映射删除语句
•select – 映射查询语句

3.1 insert

<!--public void addEmp(Employee employee);-->
    <insert id="addEmp" parameterType="com.itlc.mybatis.bean.Employee"
       useGeneratedKeys="true" keyProperty="id">
        INSERT INTO tbl_employee(last_name, gender, email)
        VALUES(#{lastName},#{gender},#{email})
    </insert>

mysql支持自增主键,自增主键值的获取,mybatis也是利用statement。getGenreatedKeys();
useGeneratedKeys=”true”;使用自增主键获取主键值策略
keyProperty;指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的那个属性
Oracle不支持自增,Oracle使用序列来模拟自增, 每次插入的数据的主键都是从序列中拿到的值,如何获取这个值

3.2 delete

<!--public void deleteEmpById(Integer id);-->
    <delete id="deleteEmpById">
        DELETE FROM tbl_employee WHERE id=#{id}
    </delete>

3.3 update

<!--public void updateEmp(Employee employee);-->
    <update id="updateEmp" parameterType="com.itlc.mybatis.bean.Employee">
        UPDATE tbl_employee SET last_name=#{lastName},gender=#{gender},email=#{email}
        WHERE id=#{id}
    </update>

3.4 select

3.4.1 参数类型
① 单个参数

单个参数:mybatis不会做特殊处理
#{参数名};取出参数值


    <!--public Employee getEmpById(Integer id);-->
    <select id="getEmpById" resultType="com.itlc.mybatis.bean.Employee" >
        Select * FROM tbl_employee WHERE id=#{id}
    </select>
② 多个参数

多个参数:mybatis会做特殊处理
多个参数会被封装成一个map
key:parm1….parmN,或者参数的索引0,1…N
value:对应的参数值
#{}就是从map中获取指定的key的值
常用:命名参数:明确指定封装参数时map的key;@Param(“指定名称”)放到参数前,就可以自定义key了
使用#{自定义key}取出对应的值

!-- public Employee getEmpByIdAndLastName(@Param("id") Integer id, @Param("lastName") String lastName);-->
    <select id="getEmpByIdAndLastName" resultType="com.itlc.mybatis.bean.Employee">
        Select * FROM tbl_employee WHERE id=#{param1} AND last_name=#{param2}
    </select>
③ pojo参数

如果多个参数正好是我们的业务逻辑的数据模型,我们直接传pojo:
使用#{属性名}:取出pojo的属性值

④ Map封装

Map:
如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map
如果多个参数不是业务模型中的数据,没有对应的pojo,经常使用,推荐编写一个TO(Transfer Object)
数据传输对象
Page{
int index;
int size;
}
使用#{属性名}:取出pojo的属性值

⑤ 总结和注意
public Employee getEmp(@Param("id")Integer id,String lastName);
    取值:id--->#{id/param1}    lastName-->#{param2}

public Employee getEmp(Integer id,@Param("e")Employee emp);
    取值:id-->#{param1}  lastName-->#{param2.lastName/e.lastName}

特别注意:如果Collection(List,set)类型或者是数组,会进行特殊处理,
          会把传入的list或者数组封装进map里面
          key:Collection(collection),如果List还可以使用list作为key
          数组(array)
public Employee getEmp(List<Integer> ids);
    取值;取第一个id的值:#{list[0]}
3.4.2 参数处理

参数值的获取
#{}:可以获取map中的值或者pojo对象属性的值;
${}:可以获取map中的值或者pojo对象属性的值;
区别:
#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
${}:取出的值直接拼装在sql语句中,会有安全问题
大多情况下,我们取参数都使用#{}

原生jdbc不支持占位符的地方我们就可以使用${}进行取值,非参数的位置
比如分表;按照年份

select * from ${year}_salary where xxx; 

#{}的其他用法:
规定参数的一些规则:
– javaType、jdbcType、mode(存储过程)、numericScale、
resultMap、typeHandler、jdbcTypeName、expression(未来准备支持的功能)
jdbcType统筹需要再某种特定的条件下被设置:
在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错)

<!--public Employee getEmpByLastNameLike(String lastName);-->
    <!--resultType:若要返回一个集合,要写集合中元素的类型-->
    <select id="getEmpByLastNameLike" resultType="com.itlc.mybatis.bean.Employee">
        SELECT * FROM tbl_employee WHERE last_name LIKE #{lastName}
    </select>
3.4.3 自动映射

①.全局setting设置

– autoMappingBehavior默认是PARTIAL,开启自动映射
的功能。唯一的要求是列名和javaBean属性名一致
– 如果autoMappingBehavior设置为null则会取消自动映射
– 数据库字段命名规范,POJO属性符合驼峰命名法,如
A_COLUMNaColumn,我们可以开启自动驼峰命名规
则映射功能,mapUnderscoreToCamelCase=true。

②.自定义resultMap,实现高级结果集映射。

resultMap
• constructor - 类在实例化时, 用来注入结果到构造方法中
– idArg - ID 参数; 标记结果作为 ID 可以帮助提高整体效能
– arg - 注入到构造方法的一个普通结果
• id – 一个 ID 结果; 标记结果作为 ID 可以帮助提高整体效能
• result – 注入到字段或 JavaBean 属性的普通结果
• association – 一个复杂的类型关联;许多结果将包成这种类型
– 嵌入结果映射 – 结果映射自身的关联,或者参考一个
• collection – 复杂类型的集
– 嵌入结果映射 – 结果映射自身的集,或者参考一个
• discriminator – 使用结果值来决定使用哪个结果映射
– case – 基于某些值的结果映射
• 嵌入结果映射 – 这种情形结果也映射它本身,因此可以包含很多相同的元
素,或者它可以参照一个外部的结果映射。

3.4.4属性详解:

1.id & result

• id 和 result 映射一个单独列的值到简单数据类型
(字符串,整型,双精度浮点数,日期等)的属性或字段。

 <!--
        不使用resultType,使用resultMap:
        自定义某个javaBean的封装规则
        type:自定义规则的Java类型
        id:唯一id方便引用
    -->
    <resultMap id="MyEmp" type="com.itlc.mybatis.bean.Employee">
        <!--指定对应的javaBean属性
            id定义主键会底层有优化
            result定义普通列封装规则
            column:指定查询到的数据的某一列
            property:指定对应javaBean属性
         -->
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <!--其他不指定的列会自动封装,但我们只要写resultMap,就推荐把全部的映射规则都写上-->
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </resultMap>
2. association

场景一:查询员工信息的同时查出部门
Employee===》Department
每个员工都有与之对应的部门信息;

    <!--
        id last_name gender dept_id did dept_name
        联合查询:1.级联属性封装结果集
                  2.association
    -->
    <!--1.级联属性-->
    <resultMap id="MyEmp1" type="com.itlc.mybatis.bean.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="did" property="dept.id"/>
        <result column="dept_name" property="dept.departmentName"/>
    </resultMap>

    <!--
        2.association可以指定联合的javaBean对象
            property:指定那个属性是联合的对象
            javaType: 指定这个属性对象的类型{必要项}
          在association的字标签中使用id和result来指定对应项
    -->
    <resultMap id="MyEmp2" type="com.itlc.mybatis.bean.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <association property="dept" javaType="com.itlc.mybatis.bean.Department">
            <id column="did" property="id"/>
            <result column="dept_name" property="departmentName"/>
        </association>
    </resultMap>

    <!-- public Employee getEmpAndDept(Integer id)-->
    <select id="getEmpAndDept" resultMap="MyEmp2">
        SELECT e.id id,e.last_name last_name,e.gender gender,e.dept_id dept_id
        ,d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d WHERE
        e.dept_id=d.id AND e.id=1;
    </select>

②.分布查询

使用association进行分步查询
1.先按照员工id查询员工信息
2.根据查询员工信息的dept_id去部门表查出部门信息
3.部门设置到员工中

  <!--public Employee getEmpByIdStep(Integer id);-->
    <select id="getEmpByIdStep" resultMap="MyEmpByStep">
        SELECT * FROM tbl_employee WHERE id=#{id}
    </select>

    <resultMap id="MyEmpByStep" type="com.itlc.mybatis.bean.Employee">
        <result column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>
        <!--
            用association定义关联对象的封装规则
                select:表明当前属性是调用select指定的方法查出的结果
                column:指定将那一列的值传给这个方法

            流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,
                  并封装给property
        -->
        <association property="dept"
                     select="com.itlc.mybatis.dao.DepartmentMapper.getDeptById"
                     column="dept_id">
        </association>
    </resultMap>

③.延迟加载

使用延迟加载
Employee==>Dept;
我们每次查询Employee对象的时候,都将一起查询出来
部门信息在我们使用的时候再去查询;
分步查询的基础之上加上两个配置:

<!--显示的指定每个我们需要更改的配置的值,即使他是默认的,放在版本更新带来的问题-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
3. Collection

场景二:查询部门的时候将该部门中所有的员工信息查出来

①使用

<!--public Department getDeptByIdPlus(Integer id);-->
    <select id="getDeptByIdPlus" resultMap="MyDept">
        SELECT d.id did,d.dept_name dept_name
        ,e.id eid,e.last_name last_name,e.email email,e.gender gender
        FROM tbl_dept d LEFT JOIN tbl_employee e ON d.id=e.dept_id
        WHERE d.id=1;
    </select>

    <!--did  dept_name  || eid  last_name  email  gender-->
    <!--
        1.Collection嵌套结果集的方式,定义关联的集合类型元素
    -->
    <resultMap id="MyDept" type="com.itlc.mybatis.bean.Department">
        <id column="did" property="id"/>
        <result column="dept_name" property="departmentName"/>
        <!--
            collection定义关联集合类型的属性的封装规则
            ofType:集合里元素的类型
        -->
        <collection property="emps" ofType="com.itlc.mybatis.bean.Employee">
            <!--定义集合中元素的封装规则-->
            <id column="eid" property="id"/>
            <result column="last_name" property="lastName"/>
            <result column="email" property="email"/>
            <result column="gender" property="gender"/>
        </collection>
    </resultMap>

②.分步查询

  <!--public Department getDeptByIdStep(Integer id);-->
    <select id="getDeptByIdStep" resultMap="MydeptStep">
        SELECT id,dept_name FROM tbl_dept WHERE id=#{id};
    </select>

    <!--利用dept_id查询所有Employee-->
    <!-- public List<Employee> getEmpsByDeptId(Integer deptId);-->
    <select id="getEmpsByDeptId" resultType="com.itlc.mybatis.bean.Employee">
        SELECT * FROM tbl_employee WHERE dept_id=#{deptId}
    </select>

    <resultMap id="MydeptStep" type="com.itlc.mybatis.bean.Department">
        <id column="id" property="id"/>
        <result column="dept_name" property="departmentName"/>
        <collection property="emps"
            select="com.itlc.mybatis.dao.DepartmentMapper.getEmpsByDeptId"
            column="id" fetchType="eager">
            <!--column可以利用集合穿多个参数,column="{key1=column1,key2=column2}"-->
            <!--
                fetchType="lazy":表示使用延迟加载
                fetchType="eager":立即加载
            -->
        </collection>

    </resultMap>
4. discriminator
<!--
        <discriminator javaType=""></discriminator>
        鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为
        封装Employee:
            如果查出的是女生,就把部门信息查出来,否则不查询;
            如果是男生,就把last_name这一列的值给email;
     -->
    <select id="getEmpByIdDis" resultMap="MyEmpDis">
        SELECT * FROM tbl_employee WHERE id=#{id}
    </select>
    <resultMap id="MyEmpDis" type="com.itlc.mybatis.bean.Employee">
        <result column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>
        <!--
            使用鉴别器判断是否需要查部门信息
            column:对应列值
            javaType:该列值对应的java类型,已起好别名
        -->
        <discriminator javaType="string" column="gender">
            <!--
                value:对应的值
                resultType:指定的封装类型
            -->
            <!--女生-->
            <case value="0" resultType="com.itlc.mybatis.bean.Employee">
                <association property="dept"
                             select="com.itlc.mybatis.dao.DepartmentMapper.getDeptById"
                             column="dept_id">
                </association>
            </case>
            <!--男生-->
            <case value="1" resultType="com.itlc.mybatis.bean.Employee">
                <result column="id" property="id"/>
                <result column="last_name" property="lastName"/>
                <result column="gender" property="gender"/>
                <result column="last_name" property="email"/>
            </case>
        </discriminator>
    </resultMap>

猜你喜欢

转载自blog.csdn.net/maniacxx/article/details/80062613