SQL映射文件详解


一、SQL映射文件

SQL映射是MyBatis框架最具有特色的部分,功能强大且使用简单

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

属性描述
mapperSQL映射文件的根元素,只有一个属性namespace,用于区分不同的mapper,必须全局唯一
cache为给定命名空间配置缓存
cache—ref引用其他命名空间中的缓存配置
resultMap用来描述查询结果集中的字段和Java实体类属性的对应关系
sql定义可重用的SQL语句块,可以在其他语句映射中引用,提高编写和维护SQL语句的效率
insert映射insert语句
update映射update语句
delete映射delete语句
select映射select语句

二、MyBatis框架的条件查询

2.1 实现单一条件查询

属性描述
id1.命名空间中唯一的标识符 2.接口中的方法与映射文件中的SQL语句id一一对应
parameterType传入SQL语句的参数类型
resultTypeSQL语句返回值类型的完全限定名或别名
//接口
SysUser findUserById(Integer id);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.SysUserMapper">
    <select id="findUserById" resultType="work.entity.SysUser">
        select * from t_sys_user where id=#{id}
    </select>
</mapper>

//测试类
public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession();
            SysUserMapper mapper = sqlSession.getMapper(SysUserMapper.class);
            SysUser userById = mapper.findUserById(2);
            System.out.println(userById);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }

2.2实现多条件查询

1.将查询条件封装成Java对象作为入参

//接口
List<StorageRecord> findRecord(StorageRecord storageRecord);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.StorageRecordMapper">
    <select id="findRecord" resultType="work.entity.StorageRecord">
        select srCode,goodsName,supplierId,totalAmount,payStatus,createdTime
        from t_storage_record
        where goodsName like concat('%',#{goodsName},'%') and supplierId=#{supplierId} and payStatus=#{payStatus}
    </select>
</mapper>

//测试类
public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession();
            StorageRecordMapper mapper = sqlSession.getMapper(StorageRecordMapper.class);
            StorageRecord storageRecord = new StorageRecord();
            storageRecord.setGoodsName("咖啡");
            storageRecord.setSupplierId(14);
            storageRecord.setPayStatus(2);
            List<StorageRecord> record = mapper.findRecord(storageRecord);
            for (StorageRecord storageRecord1 : record) {
                System.out.println(storageRecord1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }

2.将查询条件封装成Map对象作为入参

//接口
   List<StorageRecord> findRecord(Map<String,Object> StorageRecored);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.StorageRecordMapper">
    <select id="findRecord" resultType="work.entity.StorageRecord">
        select srCode,goodsName,supplierId,totalAmount,payStatus,createdTime
        from t_storage_record
        where goodsName like concat('%',#{goodsName},'%') and supplierId=#{supplierId} and payStatus=#{payStatus}
    </select>
</mapper>

//测试类
public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession();
            StorageRecordMapper mapper = sqlSession.getMapper(StorageRecordMapper.class);
            Map<String,Object> map = new HashMap<>();
            map.put("goodsName","咖啡");
            map.put("supplierId",14);
            map.put("payStatus",2);
            List<StorageRecord> record = mapper.findRecord(map);
            for (StorageRecord storageRecord : record) {
                System.out.println(storageRecord);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }

3.使用@Param注解实现多参数入参

//接口
List<StorageRecord> findRecord(@Param("goodsName") String goodsName,@Param("supplierId") int supplierId,@Param("payStatus") int payStatus);


//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.StorageRecordMapper">
    <select id="findRecord" resultType="work.entity.StorageRecord">
        select srCode,goodsName,supplierId,totalAmount,payStatus,createdTime
        from t_storage_record
        where goodsName like concat('%',#{goodsName},'%') and supplierId=#{supplierId} and payStatus=#{payStatus}
    </select>
</mapper>


//测试类
public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession();
            StorageRecordMapper mapper = sqlSession.getMapper(StorageRecordMapper.class);
            List<StorageRecord> recordList = mapper.findRecord("咖啡", 14, 2);
           	for (StorageRecord storageRecord : recordList) {
                System.out.println(storageRecord);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }

三、MyBatis框架的结果映射

MyBatis框架能正确的将查询结果封装在实体类的属性中,这是MyBatis框架自动映射的结果,MyBatis框架会获取结果集中地列名称并查找具有相同名称的属性进行赋值,实际开发中的情况会更复杂命名规则不统一,列名、属性名不相同等问题,我们会使用resultMap元素来自定义结果映射,简单灵活功能强大

3.1 使用resultMap元素自定义结果映射

//接口
List<StorageRecord> listRecord(StorageRecord storageRecord);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.ResultMapMapper">
			//id自己起名      	类的完全限定名, 或者一个类型别名
    <resultMap id="supName" type="work.entity.StorageRecord">
        <result property="supplierName" column="supName"/>
    </resultMap>					
    		//接口中的方法名		与resultMap的id相同
    <select id="listRecord" resultMap="supName">
    //此处supName为数据库中的字段名称,与实体类中定义的字段名不同
        select srCode,goodsName,supplierId,totalAmount,payStatus,re.createdTime,supName
        from t_storage_record re
        left join t_supplier su
        on re.supplierId = su.id
        where goodsName like concat('%',#{goodsName},'%') and supplierId=#{supplierId} and payStatus=#{payStatus}
    </select>
</mapper>

//测试类
public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession();
            ResultMapMapper mapper = sqlSession.getMapper(ResultMapMapper.class);
            StorageRecord storageRecord = new StorageRecord();
            storageRecord.setGoodsName("咖啡");
            storageRecord.setPayStatus(2);
            storageRecord.setSupplierId(14);
            List<StorageRecord> record = mapper.listRecord(storageRecord);
            for (StorageRecord storageRecord1 : record) {
                System.out.println(storageRecord1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }
3.1.1 resultMap属性
属性描述
id映射规则集的唯一标识。可以被select元素的result属性引用
type映射的结果类型,这里指定封装成Sysuser实例
autoMapping如果设置这个属性,MyBatis将会为本结果映射开启或者关闭自动映射。这个属性会覆盖全局的属性autoMappingBehavior。默认值:未设置(unset)
3.1.2 resultMap元素的子元素
元素名描述
id指定和数据表主键字段对应的标识属性。设置此项可以提升 MyBatis 框架的性能,特别是应用缓存和嵌套结果映射的时候(多表联查时可使用别名对其进行命名,以免不知道是哪个表的id)
result指定结果集字段和实体类属性的映射关系。
constructor用于在实例化类时,注入结果到构造方法中
association一个复杂类型的关联;许多结果将包装成这种类型
collection一个复杂类型的集合
discriminator使用结果值来决定使用哪个 resultMap

3.2 嵌套结果映射

(1)association元素
association元素处理==“一对一”、“多对一”==类型映射关系

//接口
List<StorageRecord> listRecord();

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.AssociationMapper">
    <resultMap id="associationMap" type="work.entity.StorageRecord">
        <association property="supplier"></association>
    </resultMap>
    <select id="listRecord" resultMap="associationMap">
        select srCode,goodsName,supplierId,supName,supContact,supPhone,totalAmount,payStatus
        from t_storage_record re
        left join t_supplier su
        on re.supplierId = su.id
    </select>
</mapper>

//测试类
public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession();
            AssociationMapper mapper = sqlSession.getMapper(AssociationMapper.class);
            List<StorageRecord> recordList = mapper.listRecord();
            for (StorageRecord storageRecord : recordList) {
                System.out.println(storageRecord);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }
属性名描述
property实体类中用来映射查询结果子集的属性
javaTypeproperty指定的属性的数据类型,可以使用Java完全限定类名或别名

(2)collection元素
collection元素处理“一对多”、“多对多”类型映射关系

//接口
List<Supplier> listRecord(Integer id);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.CollectionMapper">
<resultMap id="supplierWithId" type="work.entity.Supplier">
    <collection property="recordList" ofType="work.entity.StorageRecord"></collection>
</resultMap>
    <select id="listRecord" resultMap="supplierWithId">
        select su.id,supCode,supName,supContact,supPhone,srCode,goodsName,totalAmount,payStatus
        from t_supplier su
        left join  t_storage_record re
        on re.supplierId = su.id
        where supplierId=#{id}
    </select>
</mapper>

//测试类
    public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession();
            CollectionMapper mapper = sqlSession.getMapper(CollectionMapper.class);
            List<Supplier> recordList = mapper.listRecord(2);
            for (Supplier Supplier : recordList) {
                System.out.println(Supplier);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }
属性名描述
property实体类中用来映射查询结果子集的集合属性
ofTypeproperty指定的集合属性中的元素的数据类型,可以使用Java完全限定类名或别名

3.3 resultMap和resultType

从使用场景来看,resultType 属性直接指定结果类型,依靠自动映射实现对实体类等复杂数据类型的封装,适用于比较简单、直接的数据封装场景:而 resultMap 属性是对外部 resultMap 定义的引用,以自由控制结果映射规则和封装范围,能够处理结果集字段名与实体类属性名不一致,或需要对连接查询结果使用嵌套映射等较为复杂的问题
从底层实现来看,MyBatis 框架将查询出来的结果集首先存储在 Map 结构中,以字段名作为 key当 select 元素使用 resultType 属性指定结果类型时,MyBatis 架会自动将 Map 中的键值对对应赋值给实体类中与 key 同名的属性 (通过调用 setter 访问器实现): 使用 resultMap 属性时,则根据所引用的resultMap 元素中定义的映射规则把 Map 中的键值对赋值给指定的实体类属性。
注意
使用 resultType 属性或 resultMap 属性封装查询结果本质上是一样的,均基于 Map 数据结构但是,在 select 元素中使用时需要注意,二者不能同时使用。

3.4 resultMap的自动映射行为

<result column=“表字段” property="实体类字段“/>
没有将属性值设置为FULL时,嵌套结果集会自动映射,
设置为PARTIAL时自动映射但嵌套结果不会被映射,
设置为NONE 表示关闭自动映射

在这里插入图片描述

四、MyBatis框架的增、删、改操作

4.1 执行insert语句

有时需要获取插入的该列的主键值可通过使用useGeneratedKeys=“true” keyProperty=“id” 这两属性去获得
//接口
int addUser(SysUser user);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.AddMapper">
    <insert id="addUser" parameterType="work.entity.SysUser">
        insert into t_sys_user (account,realName,sex)values(#{account},#{realName},#{sex})
    </insert>
</mapper>

//测试类
 public static void add(){
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession(true);
            AddMapper mapper = sqlSession.getMapper(AddMapper.class);
            SysUser user = new SysUser();
            user.setAccount("zhangsan");
            user.setRealName("张三");
            user.setSex(2);
            mapper.addUser(user);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }

4.2 执行update语句

//接口
int updateUser(@Param("id") Integer id,@Param("sex") int sex);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.AddMapper">
    <update id="updateUser" parameterType="work.entity.SysUser">
        update t_sys_user set sex=#{sex} where id=#{id}
    </update>
</mapper>

//测试类
 public static void update(){
     SqlSession sqlSession = null;
     try {
         sqlSession = SysUserUtil.getSqlSession(true);
         AddMapper mapper = sqlSession.getMapper(AddMapper.class);
         mapper.updateUser(18,2);
     } catch (IOException e) {
         e.printStackTrace();
     }finally {
         SysUserUtil.closeSqlSession(sqlSession);
     }
 }

4.3 执行delete语句

//接口
int deleteUser(Integer id);

//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="work.mapper.AddMapper">
    <delete id="deleteUser" parameterType="work.entity.SysUser">
        delete from t_sys_user where id=#{id}
    </delete>
</mapper>

//测试类
 public static void delete(){
        SqlSession sqlSession = null;
        try {
            sqlSession = SysUserUtil.getSqlSession(true);
            AddMapper mapper = sqlSession.getMapper(AddMapper.class);
            mapper.deleteUser(18);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            SysUserUtil.closeSqlSession(sqlSession);
        }
    }

MyBatis框架的缓存

1.一级缓存

默认是开启的
范围:SQL session级别
当SQL session关闭后,一级缓存会清空,有数据变更一级缓存即刻失效

2.二级缓存
设置二级缓存的步骤

(1).在MyBatis框架的核心文件中设置

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

(2).在mapper映射文件中添加缓存
范围:mapper级别

	</cache>
</mapper>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值