文章目录
一、SQL映射文件
SQL映射是MyBatis框架最具有特色的部分,功能强大且使用简单
1.1 SQL映射文件中的几个顶级元素
属性 | 描述 |
---|---|
mapper | SQL映射文件的根元素,只有一个属性namespace,用于区分不同的mapper,必须全局唯一 |
cache | 为给定命名空间配置缓存 |
cache—ref | 引用其他命名空间中的缓存配置 |
resultMap | 用来描述查询结果集中的字段和Java实体类属性的对应关系 |
sql | 定义可重用的SQL语句块,可以在其他语句映射中引用,提高编写和维护SQL语句的效率 |
insert | 映射insert语句 |
update | 映射update语句 |
delete | 映射delete语句 |
select | 映射select语句 |
二、MyBatis框架的条件查询
2.1 实现单一条件查询
属性 | 描述 |
---|---|
id | 1.命名空间中唯一的标识符 2.接口中的方法与映射文件中的SQL语句id一一对应 |
parameterType | 传入SQL语句的参数类型 |
resultType | SQL语句返回值类型的完全限定名或别名 |
//接口
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 | 实体类中用来映射查询结果子集的属性 |
javaType | property指定的属性的数据类型,可以使用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 | 实体类中用来映射查询结果子集的集合属性 |
ofType | property指定的集合属性中的元素的数据类型,可以使用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>