第二章-sql映射文件详解
分类: ssm 专栏: ssm框架课 标签: sql映射文件
2022-11-28 11:13:11 1331浏览
1.sql映射文件
mybatis框架的主要思想是将sql语句从程序代码中分离出来,对jdbc访问数据库的代码进行封装,从程序中消除了所有sql参数设置以及处理结果集的jdbc代码。从而大量减少数据访问层的编码量,并且,sql语句与代码解耦,可以最大限度地实现对sql语句的灵活管理,方便sql调优以保证性能。
2.mybatis框架的条件查询
2.1实现单一的条件查询
示例1:根据用户的真实姓名模糊匹配查询用户信息
<select id="getUsersByRealName" resultType="cn.cvs.pojo.SysUser" parameterType="string">
select * from t_sys_user where realName like CONCAT('%',#{realName},'%')
</select>2.2实现多条件查询
1.将查询条件封装成Java对象作为入参
<select id="getUsersByPojo" resultType="cn.cvs.pojo.SysUser" parameterType="cn.cvs.pojo.SysUser">
select * from t_sys_user where realName like CONCAT('%',#{realName},'%') and roleId = #{roleId}
</select>SysUser user = new SysUser();
user.setRealName("李");
user.setRoleId(3);
List<SysUser> users = sqlSession.getMapper(SysUserMapper.class).getUsersByPojo(user);2.将查询条件封装成map对象作为入参
<select id="getUsersByMap" resultType="cn.cvs.pojo.SysUser" parameterType="map">
select * from t_sys_user where realName like CONCAT('%',#{rName},'%') and roleId = #{rId}
</select>Map<String,Object> map = new HashMap<>();
map.put("rName","赵");
map.put("rId",2);
List<SysUser> sysUserList = sqlSession.getMapper(SysUserMapper.class).getUsersByMap(map);3.使用@Param注解实现多参数入参
public List<SysUser> getUsersByParam(@Param("realName") String realName,@Param("roleId") int roleId); List<SysUser> sysUsers = sqlSession.getMapper(SysUserMapper.class).getUsersByParam("赵", 2);2.3实战训练
在724系统中实现查询入库记录表的功能
3.mybatis框架的结果映射
3.1使用resultMap元素自定义结果映射
查询用户信息列表,需要展示的字段包括账号 真实姓名 性别 电话 用户角色,注意:用户角色要显示角色名称而不是角色ID
SysUser实体类中增加属性:
private String userRoleName;//角色名称
<resultMap id="userWithRoleName" type="cn.cvs.pojo.SysUser">
<id property="id" column="id"></id>
<result property="userRoleName" column="roleName"></result>
</resultMap>
<select id="getUsersWithRoleName" resultType="cn.cvs.pojo.SysUser" resultMap="userWithRoleName">
SELECT
u.*,r.roleName
FROM
t_sys_user u
LEFT JOIN t_sys_role r on u.roleId =r.id
WHERE
u.realName LIKE CONCAT(
'%',
#{realName},'%') and u.roleId = #{roleId}
</select>分析:resultMap元素包含以下属性:
- id:映射规则集的唯一标识,可以被select元素的resultMap属性引用
- type:映射的结果类型,一般指的是实体类的全类名
resultMap元素包含以下子元素
- id:指定和数据表主键字段对应的标识属性,设置此项可提升mybatis的性能
- result:指定结果集字段和实体类属性的映射关系
3.2实战训练
查询入库记录以及相关的供应商名称
3.3嵌套结果映射
1.association元素
association元素用来处理has-one类型的关系,如用户类内部“有一个”用户角色类型的属性。
例子:根据用户的角色id查询出用户的姓名,角色ID 角色编码和角色名称。
<resultMap id="usersByRoleId" type="cn.cvs.pojo.SysUser">
<id property="id" column="id"></id>
<result property="realName" column="realName"></result>
<association property="sysRole" javaType="cn.cvs.pojo.SysRole">
<id property="id" column="rid"></id>
<result property="code" column="code"></result>
<result property="roleName" column="roleName"></result>
</association>
</resultMap>
<select id="getUsersByRoleId" parameterType="integer" resultMap="usersByRoleId">
SELECT
u.*,r.id as rid, r.code, r.roleName
FROM
t_sys_user u
LEFT JOIN t_sys_role r on u.roleId =r.id
WHERE
u.roleId = #{roleId}
</select> @Test
public void getUsersByRoleId(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtil.createSqlSession();
List<SysUser> usersByRoleId = sqlSession.getMapper(SysUserMapper.class).getUsersByRoleId(2);
for(SysUser user: usersByRoleId){
logger.debug("用户名:"+user.getRealName()+"roleId:"+user.getSysRole().getId() + "角色编号"+user.getSysRole().getCode() +"角色名称:"+user.getSysRole().getRoleName());
}
}catch (Exception e){
e.printStackTrace();
}finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
}association元素的主要属性如下:
- property:实体类中用来映射查询结果子集的属性
- JavaType:property指定的属性的数据类型
association元素包含如下子元素
- d:指定和数据表主键字段对应的标识属性,设置此项可提升mybatis的性能
- result:指定结果集字段和实体类属性的映射关系
2.collection元素
和association非常相似,association是一对一或者多对一,而collection是一对多。即实体类内部嵌套的是一个集合类型的属性。
例子:要求获取指定用户的信息和地址列表
<resultMap id="userAndAdressByUserId" type="cn.cvs.pojo.SysUser">
<id column="id" property="id"></id>
<result property="account" column="account"></result>
<result property="realName" column="realName"></result>
<collection property="addressList" ofType="cn.cvs.pojo.Address">
<id column="aid" property="id"></id>
<result property="contact" column="contact"></result>
<result property="addressDesc" column="addressDesc"></result>
<result property="postCode" column="postCode"></result>
<result property="tel" column="tel"></result>
</collection>
</resultMap>
<select id="getUserAndAdressByUserId" resultMap="userAndAdressByUserId" parameterType="integer">
SELECT
u.*,a.id as aid, a.contact, a.addressDesc,a.postCode,a.tel
FROM
t_sys_user u
LEFT JOIN t_address a on a.userId =u.id
WHERE
u.id = #{userId}
</select>sqlSession = MyBatisUtil.createSqlSession();
SysUser user= sqlSession.getMapper(SysUserMapper.class).getUserAndAdressByUserId(2);
logger.debug("用户账号account:"+user.getAccount()+"用户名称:"+user.getRealName());
//遍历用户地址
for(Address address : user.getAddressList()){
logger.debug("address----->id:"+address.getId()
+",contact:"+address.getContact()
+",addressDesc:"+address.getAddressDesc()
+",postCode:"+address.getPostCode()
+",tel:"+address.getTel()
);
}
collection元素有如下常用属性
- property:实体类中用来映射查询结果子集的集合属性
- ofType:property指定的集合属性中的元素的数据类型,可以使用Java的全类名
3.4resultType和resultMap小结
resultType适用于比较简单,直接的数据封装场景。
resultMap处理结果集字段名与实体类属性名不一致,或需要对连接查询结果使用嵌套映射等较为复杂的问题。
3.5实战训练
- 在724系统中使用association元素查询入库记录表,在之前的基础上实现嵌套结果映射,查询并展示入库记录编码,商品名称,供货商编码,供货商名称,联系人,联系电话,商品总额,支付状态。
- 在724系统中使用collection查询供货商及相关入库记录
3.6resultMap的自动映射行为
resultMap自动映射的默认行为是对于没有嵌套映射的resultMap使用自动映射,对于有嵌套映射的resultMap则不使用自动映射,仅为手工映射的属性赋值。
可以在mybatis框架的核心配置文件中进行设置,修改自动映射的行为,
<!--设置自动映射行为--> <setting name="autoMappingBehavior" value="FULL"/>
自动映射的三种行为:
- NONE:禁用自动映射,仅为手工映射的属性赋值
- PARTIAL:默认行为,对于没有嵌套映射的resultMap使用自动映射,而对于有嵌套映射的resultMap不使用自动映射,仅为手工映射的属性赋值
- FULL:全部使用自动映射,对有嵌套的resultMap也会自动映射。
4.mybatis的增,删,改操作
4.1执行insert语句
增加用户的方法,参数为要添加的用户实例。
<insert id="add" parameterType="cn.cvs.pojo.SysUser">
insert into t_sys_user (
account,
realName,
password,
sex,
birthday,
phone,
address,
roleId,
createdUserId,
createdTime,
updatedUserId,
updatedTime
)
VALUES (
#{account},
#{realName},
#{password},
#{sex},
#{birthday},
#{phone},
#{address},
#{roleId},
#{createdUserId},
#{createdTime},
#{updatedUserId},
#{updatedTime}
)
</insert> @Test
public void testAdd(){
SqlSession sqlSession = null;
int count = 0;
try{
sqlSession = MyBatisUtil.createSqlSession();
SysUser user = new SysUser();
user.setAccount("mayun");
user.setRealName("马云");
user.setRoleId(1);
user.setAge(45);
user.setPassword("123456");
count=sqlSession.getMapper(SysUserMapper.class).add(user);
// int i=2/0;
sqlSession.commit();
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback();
count =0;
}finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.debug("add user count:"+count);
}4.2执行update语句
根据用户ID修改用户信息的功能,
<update id="update" parameterType="cn.cvs.pojo.SysUser">
update
t_sys_user
set
`account` = #{account},
`realName` = #{realName},
`password` = #{password},
`sex` = #{sex},
`birthday` = #{birthday},
`phone` = #{phone},
`address` = #{address},
`roleId` = #{roleId},
`updatedUserId` = #{updatedUserId},
`updatedTime` = #{updatedTime}
WHERE
(`id` = #{id});
</update>4.3执行delete语句
根据用户ID删除用户
<delete id="delete" parameterType="integer">
delete from t_sys_user where id = #{id}
</delete>4.4实战训练
在724系统中实现对供货商表的增,删, 改操作
5.mybatis框架的缓存
5.1缓存分类
1.一级缓存
基于PerpetualCache的hashMap本地缓存,默认是sqlsession级别的缓存,在sqlsession的生命周期内有效,当sqlsession关闭后,该sqlsession中所有的一级缓存会被清空。mybatis框架的一级缓存默认是开启的。
2.二级缓存
是sqlSessionFactory级别的,作用域超出了一个sqlsession的范围,缓存中的数据可以被所有sqlsession共享,mybatis框架的二级缓存默认是关闭的,使用的时候需要在mybatis框架的核心配置文件中设置开启。
5.2二级缓存的使用方法
1.在mybatis的核心配置文件中设置全局开启二级缓存。
<!--开启二级缓存--> <setting name="cacheEnabled" value="true"/>
2.即使全局开启了二级缓存,默认情况下也是不使用二级缓存的,可以根据需要在sql映射文件中配置,为当前namespace启用二级缓存。
<mapper namespace="cn.cvs.dao.SysUserMapper">
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"
>
</cache>cache元素中各种属性的作用如下:
- eviction:选择缓存回收策略(FIFO:先进先出,按照对象进入缓存的顺序来移除他们,这里推荐使用LRU策略:最近最少使用的)
- flushInterval:设定缓存刷新间隔,以毫秒为单位设定缓存多长时自动刷新一次,默认不自动刷新。
- size:设定缓存中最多存放多少个对象,默认是1024
- readOnly:设定缓存数据是否只读,默认是false,表示缓存数据会用于读写操作,true表示缓存数据只用于读操作。
3.在sql映射文件中配置支持二级缓存后,如需对个别查询进行调整,可以在select元素中单独设置
<select id="count" resultType="integer" useCache="false">
……
</select>注意:二级缓存开启后,实体类一定要实现序列化接口,因为缓存要读取到内存中。
一级缓存默认开启,怎么演示:
查询两次一模一样的sql语句
List<SysUser> all =sysUserDao.getUserAndAdressByUserId(2L);
System.out.println("=======================================");
List<SysUser> all2 =sysUserDao.getUserAndAdressByUserId(2L);
一级缓存失效,一级缓存不能跨sqlsession
List<SysUser> all =sysUserDao.getUserAndAdressByUserId(2L);
MybatisUtils.closeSession(sqlSession);
System.out.println("=======================================");
sqlSession=MybatisUtils.getSession();
sysUserDao = sqlSession.getMapper(SysUserDao.class);
List<SysUser> all2 =sysUserDao.getUserAndAdressByUserId(2L);
当开启二级缓存的时候,就可以跨sqlsession了。
6.课堂视频教程
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论
您可能感兴趣的博客

新业务
springboot学习
ssm框架课
vue学习
【带小白】java基础速成