SQL映射文件

目录

一、预习检查

二、上章回顾

三、本章目标

四、SQL映射的XML文件

五、mapper

六、select单一条件查询

七、select多条件查询

八、resultMap

九、resultMap将结果集映射到Java对象

十、resultMap元素

十一、嵌套结果映射之association

十二、association映射复用

十三、嵌套结果映射之collection

十四、resultType与resultMap小结

十五、MyBatis自动映射

十六、增Insert删Delete改Update

十七、缓存

十八、本章总结


一、预习检查

1、列举下SQL映射文件的几个顶级元素 2、MyBatis多参数入参有几种处理方式? 3、mapper元素的namespace属性的作用是什么? 4、不同的SQL映射文件,元素的id必须不同吗? 5、谈谈你对association和collection元素的理解

二、上章回顾

MyBatis基本要素:

核心对象最佳生命周期
SqlSessionFactoryBuilder局部变量
SqlSessionFactory从应用服务启动开始一直到应用服务停止
SqlSession一次请求的有效期

核心对象 SqlSessionFactoryBuilder SqlSessionFactory SqlSession 通过namespace+id运行映射的SQL语句 基于Mapper接口的方式执行SQL语句 核心配置文件 properties typeAliases environments mappers SQL映射文件

三、本章目标

1、掌握基于SQL映射文件的增删改查操作 2、掌握为SQL映射文件传递参数的方法 3、掌握使用resultMap映射查询结果 4、了解MyBatis框架中缓存的使用方法

四、SQL映射的XML文件

MyBatis真正的特色在于SQL映射语句,功能强大,使用简单

SQL映射文件的几个顶级元素

mapper – SQL映射文件的根元素,有一个namespace属性 cache – 配置给定命名空间的缓存 cache-ref – 从其他命名空间引用缓存配置 resultMap – 用来描述数据库结果集和对象的对应关系 sql – 可以重用的SQL块,也可以被其他语句引用 insert – 映射插入语句 update – 映射更新语句 delete – 映射删除语句 select – 映射查询语句

五、mapper

mapper namespace属性,区别不同的mapper namespace和子元素的id联合保证唯一 绑定DAO接口 namespace的命名必须跟某个接口同名 接口中的方法与映射文件中SQL语句id一一对应

示例:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace 绑定一个对应的dao/mapper接口-->
<mapper namespace="cn.cvs.mapper.SysUserMapper">
<!--查询全部用户信息-->
<select id="getUserList" resultType="cn.cvs.pojo.SysUser">
  SELECT * FROM `t_sys_user`
</select>
</mapper>
1234567891011

注意事项:接口中的方法与映射文件中的sql语句ID一一对应

package cn.cvs.mapper;
import cn.cvs.pojo.SysUser;
import java.util.List;
/**
 * @Created by Aiden
 * @Date 2022
 */
public interface SysUserMapper {
    /**
     * 查询全部用书信息
     * @return
     */
    List<SysUser> getUserList();
}
1234567891011121314
六、select单一条件查询

select是MyBatis中最常用的元素之一 select元素有很多属性,可以详细配置每一条查询语句

id 命名空间中唯一的标识符 接口中的方法与映射文件中的SQL语句id一一对应 parameterType 传入SQL语句的参数类型 resultType SQL语句返回值类型的完整类名或别名

七、select多条件查询

教学思路: 抛出问题,根据项目截图说明,在查询的时候经常会多条件查询, 引申到增加和修改功能,参数可能会更多

parameterType

使用复杂数据类型 ​ 1)Java实体类 ​ 2)Map ​ 3)通过 #{属性名} 或者 #{map的keyName} 获取传入的值 ​ 使用多个简单数据类型 ​ 1)int、String、Date等,一个参数传递单一数值 ​ 2)使用==@Param注解==为参数命名,通过 #{参数名} 获取传入的值

教学指导: 演示案例,改造上个案例,把paramteterType改为 对象入参和Map 入参 \==注意:==对于多个参数入参的方式,建议使用@Param注解为参数命名

八、resultMap

问题:

按条件查询得到用户表列表,需要显示指定字段,并显示用户角色名称(中文表述) 用户表中的roleId字段记录的是角色id,不是其对应的名称,此时该怎办呢?

问题分析:

修改SysUser实体类,增加userRoleName属性 修改查询SQL语句,连表查询roleName字段 实体类属性名于查询结果字段名不一致

解决方案: 1、可以修改sql语句和pojo,可以使用resultType做自动映射(需要注意的是:字段名和属性名是否一致,若不一致,那么需要给字段起别名,变成一致),对于列表要求显示指定字段(可以通过sql查询字段来控制) 2、推荐第二种方案:字段名不一致,并且显示指定列,通过resultMap来映射自定义结果

九、resultMap将结果集映射到Java对象

1.先在SysUser类中添加 userRoleName字段

public class SysUser{
    private String userRoleName;//用户角色名字
​
 public String getUserRoleName() {
     return userRoleName;
 }
​
 public void setUserRoleName(String userRoleName) {
     this.userRoleName = userRoleName;
 }
}
1234567891011

2.在SysUserMapper.xml文件中添加如下配置

<resultMap id="userWithRoleName" type="SysUser">
    <id property="id" column="id"/>
 <!--注意:要确保所有的别名或者字段名都是唯一且无歧义的-->
    <result property="userRoleName" column="roleName"/>
</resultMap>
<select id="getUserListWithRoleName" resultMap="userWithRoleName" parameterType="sysuser">
 select u.*, r.roleName from t_sys_user u, t_sys_role r
 where u.realName like CONCAT ('%', #{realName}, '%')
 and u.roleId = #{roleId} and u.roleId = r.id
</select>
12345678910
十、resultMap元素

resultMap元素的属性 id:resultMap的唯一标识 type:映射的结果类型 resultMap元素的子元素 id:指定和数据表主键字段对应的标识属性 设置此项可提高MyBatis性能 result:指定结果集字段和实体类属性的映射关系 association:映射“多对一”或“一对一”关系 (模型包含模型) collection: 映射“一对多”关系 (模型包含集合)

十一、嵌套结果映射之association

association 复杂的关联类型,映射一个嵌套JavaBean属性 多对一或一对一 属性,

第一个属性是“关联的嵌套映射”,该属性的标签名称为“association”。在resultMap中,当映射type为Java包装类时,可能会遇到包装类中含有其他Java包装类的属性,这里resultMap提供了association标签来定义结果集中包含的其他结果集。

association
复杂的关联类型,映射一个嵌套JavaBean属性
多对一或一对一
属性
property:用来映射查询结果子集的实体属性
javaType:完整Java类名或者别名
resultMap:引用外部resultMap

子元素
id
result

十二、association映射复用

上述示例中使用resultMap联合一个association来映射SysUser+SysRole实例,那么association的SysRole结果映射是否可复用?

使用resultMap 扩展出Association的另一个属性:resultMap来联合映射,这样就可以使role结果映射可以重复使用,当然 若不需要重用,可以按照之前的写法,直接嵌套这个联合结果映射。根据具体业务而定

<resultMap id="sysRole" type="SysRole" >
   <id property="id" column="rid"/>
   <result property="code" column="code"/>
   <result property="roleName" column="roleName"/>
</resultMap>
​
<resultMap id="userWithSysRole" type="SysUser">
   <id property="id" column="id"/>
   <result property="realName" column="realName"/>
   <association property="sysRole"javaType="SysRole" resultMap="sysRole" />
</resultMap>
1234567891011
十三、嵌套结果映射之collection

collection 复杂类型集合,映射嵌套结果集到一个列表 一对多 属性 property:实体类中用来映射查询结果子集的集合属性 ofType:集合中元素的类型,完整Java类名或者别名 resultMap:引用外部resultMap

子元素

id

result

<resultMap id="address" type="Address">
   <id property="id" column="aid"/>
   <result property="contact" column="contact"/>
   <result property="addressDesc" column="addressDesc"/>
   <result property="postCode" column="postCode"/>
   <result property="tel" column="tel"/>
</resultMap>
​
<resultMap id="userWithAddresses" type="SysUser">
   <id property="id" column="id"/>
   <result property="account" column="account"/>
   <result property="realName" column="realName"/>
 <!--resultMap:引用外部resultMap-->
 <collection property="addressList" ofType="address" resultMap="address"/>
</resultMap>
123456789101112131415
十四、resultType与resultMap小结

resultType 直接表示返回类型 适用于比较简单直接的数据封装场景

resultMap 是对外部resultMap的引用 能够处理结果集字段名与实体类属性名不一致、或者需要对连接查询结果使用嵌套映射等较为复杂的问题

二者本质上都是基于Map数据结构,不能同时使用

十五、MyBatis自动映射

自动映射的前提:属性名与字段名一致

自动映射级别:autoMappingBehavior

<settings>
    <setting name="autoMappingBehavior" value="[NONE|PARTIAL|FULL]" />
</settings>
123
自动映射行为resultType (不支持嵌套映射没有嵌套映射的有嵌套映射的resultMap
NONE失效手工映射手工映射
PARTIAL自动映射自动映射手工映射
FULL自动映射自动映射自动映射

十六、增Insert删Delete改Update

Insert: 新增 id: 接口方法名字 parameterType: 参数类型

注意: 1、Insert update delete 这类操作,本身默认就是返回影响的行数,所以不需要对resultType进行指定,只有查询类的操作,需要进行返回结果类型的指定 2、对于增删改这类更新操作,dao层接口方法的返回值为int类型,执行sql影响的行数。最好不要写boolean类型

演示示例:

增删改(insert、update、delete)这类操作通常返回影响行数,insert、update、delete元素均没有resultType/resultMap属性

1、SysUserMapper接口方法定义:

/**
 * 新增用户
 * @param sysUser
 * @return int 影响的行数
 */
int insert(SysUser sysUser);
123456

2、SysUserMapper.xml映射文件配置:

 <!-- 增加用户 -->
<insert id="insert" parameterType="SysUser">
    insert into t_sys_user (account, realName, password, sex, birthday,phone, address, roleId, createdUserId, createdTime)
    values (#{account}, #{realName}, #{password}, #{sex}, #{birthday},
        #{phone}, #{address}, #{roleId}, #{createdUserId}, #{createdTime})
</insert>
123456

3、SysUserMapperTest 单元测试类:

@Test
    public void insert() throws ParseException {
        SysUser user = new SysUser();
        user.setAccount("test001");
        user.setRealName("测试用户001");
        user.setPassword("1234567");
        Date birthday = new SimpleDateFormat("yyyy-MM-dd").parse("2003-10-22");
        user.setBirthday(birthday);
        user.setAddress("测试地址abc");
        user.setSex(1);
        user.setPhone("13512345678");
        user.setRoleId(1);
        user.setCreatedUserId(1);
        user.setCreatedTime(new Date());
​
        SqlSession sqlSession = null;
        int count = 0;
        try {
            sqlSession = MyBatisUtils.getSqlSession();
            //新增
            count = sqlSession.getMapper(SysUserMapper.class).insert(user);
            //模拟异常
            //int i=5/0;
            sqlSession.commit();//提交事务
            if (count > 0) {
                System.out.println("新增成功!");
            } else {
                System.out.println("新增失败");
            }
        } catch (Exception e) {
            System.out.println("错误异常,事务回滚==>"+e.getMessage());
            count = -1;
            sqlSession.rollback();//回滚事务
        } finally {
            MyBatisUtils.closeSqlSession(sqlSession);
        }
    }
12345678910111213141516171819202122232425262728293031323334353637

改 Update

id:接口方法名字 parameterType: 参数类型

1、SysUserMapper接口方法定义:

/**
 * 修改用户
 * @param sysUser
 * @return int 影响的行数
 */
int update(SysUser sysUser);
123456

2、SysUserMapper.xml映射文件配置:

<!-- 修改用户 -->
<update id="update" parameterType="SysUser">
    update t_sys_user set account=#{account}, realName=#{realName},
    password=#{password}, sex=#{sex}, phone=#{phone}, address=#{address},
    birthday=#{birthday}, roleId=#{roleId}, updatedUserId=#{updatedUserId},
    updatedTime=#{updatedTime}
    where id = #{id}
</update>
12345678

3、SysUserMapperTest 单元测试类:

@Test
public void update(){
    SqlSession sqlSession = null;
    int count = 0;
    try {
        SysUser user = new SysUser();
        user.setId(17);
        user.setAccount("testUpdate");
        user.setRealName("测试用户修改");
        user.setPassword("88888888");
        Date birthday =new SimpleDateFormat("yyyy-MM-dd").parse("1990-10-16");
        user.setBirthday(birthday);
        user.setAddress("地址测试修改");
        user.setSex(2);
        user.setPhone("13612345678");
        user.setRoleId(2);
        user.setUpdatedUserId(1);
        user.setUpdatedTime(new Date());
        sqlSession = MyBatisUtils.getSqlSession();
        count = sqlSession.getMapper(SysUserMapper.class).update(user);
        //模拟异常,进行回滚
        //int i =5/0;
        sqlSession.commit();//提交事务
        if (count > 0) {
            System.out.println("修改成功!");
        } else {
            System.out.println("修改失败");
        }
    } catch (Exception e) {
        System.err.println("错误异常,事务回滚==>"+e.getMessage());
        count = -1;
        sqlSession.rollback();//回滚事务
    }finally{
        MyBatisUtils.closeSqlSession(sqlSession);
    }
}
123456789101112131415161718192021222324252627282930313233343536

删 Delete

id: 接口方法名字 parameterType: 参数类型

1、SysUserMapper接口方法定义:

/**
 * 删除用户
 * @param id 要删除的用户用户ID
 */
public int deleteUserById(@Param("id") Integer id);
12345

2、SysUserMapper.xml映射文件配置:

<!-- 根据用户Id删除用户信息 -->
<delete id="deleteUserById" parameterType="integer">
    delete from t_sys_user where id=#{id}
</delete>
1234

3、SysUserMapperTest 单元测试类:

@Test
public void deleteUserById() {
    SqlSession sqlSession = null;
    Integer delId = 17;
    int count = 0;
    try {
        sqlSession = MyBatisUtils.getSqlSession();
        count = sqlSession.getMapper(SysUserMapper.class).deleteUserById(delId);
        sqlSession.commit();//提交事务
    } catch (Exception e) {
        System.out.println("错误异常,事务回滚==>"+e.getMessage());
        count = 0;
        sqlSession.rollback();//回滚事务
    }finally{
        MyBatisUtils.closeSqlSession(sqlSession);
    }
}
1234567891011121314151617
十七、缓存

MyBatis缓存 一级缓存:SqlSession 二级缓存 二级缓存的配置

1、MyBatis的全局cache配置
2、在SQL映射文件中设置缓存,默认情况下是没有开启缓存的
3、在SQL映射文件配置支持cache后,如果需要对个别查询进行调整,可以单独设置
123

1、MyBatis的全局cache配置

<settings>
 	<setting name="cacheEnabled" value="true" />
</settings>
123

2、在SQL映射文件中设置缓存

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
1

3、在SQL映射文件配置支持cache后,如果需要对个别查询进行调整

<select id="selectAll" resultType="SysUser" useCache="true">
	select * from t_sys_user;
</select>
123
十八、本章总结

Mybatis框架的SQL映射文件提供select丶insert丶update丶delete等元素来实现SQL语句的映射。
SQL映射文件的根节点是mapper元素,其namespace属性的值需要保证全局唯一,用于区分不同的mapper。
基于面向接口编程的理念,mapper元素的namespace属性值应指定为Mapper接口的完全限定类名。
SQL映射文件select元素可以使用resultMap或resultType指定返回结果的类型,但是二者不能同时使用。
为Mapper接口方法传入多个简单类型的参数时,建议使用@Param注解为参数命名。
在元素中可以使用association元素和collection元素实现嵌套结果映射。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值