目录
一.MyBatis框架动态SQL处理简单的多参数查询
MyBatis框架动态SQL的常用标签:
1.if:条件判断,与Java中的计语句类似
2.where:为SQL语句动态添加where关键字
3.choose:条件判断,这是组合标签,需要与when、otherwise标签搭配使用。可实现与
Java中的switch语句类似的功能
4.foreach:以遍历方式处理集合类型参数
5.set:为SQL语句动态添加set关键字,实现动态实现数据更新
6.trim:对SQL语句进行格式化处理,添加或移除前后缀
1.if标签
if标签是MyBatis框架动态SQL技术中最重要且最常用的标签之一,它所实现的功能与Java中的if语句基本相同,用法也很相似。
①.首先在接口里面创建一个方法
List<SysUser> selectList(@Param("realName") String realName, @Param("roleId") int roleId);
②.在xml中编写SQL语句
<select id="selectList" resultMap="SysUserResult">
select u.*, r.roleName
from t_sys_user u,
t_sys_role r
where u.roleId = r.id
<if test="roleId != null">
and u.roleId = #{roleId}
</if>
<if test="realName != null and realName != '' ">
and u.realName like concat('%', #{realName}, '%')
</if>
</select>
③.在编写测试类
@Test
public void testGetUserListByChoose() {
List<SysUser> userList = new ArrayList<SysUser>();
try {
sqlSession = MyBatisUtil.createSqlSession();
String realName = "";
int roleId = 2;
String accunt = "zhong";
Date createdTime = new SimpleDateFormat("yyyy-MM-dd").parse("2019-11-11");
userList = sqlSession.getMapper(SysUserMapper.class).selectListByChoose(realName, accunt, roleId, createdTime);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.info("查询到用户数量:" + userList.size());
for (SysUser user : userList) {
logger.info("查询到用户信息:" + user);
}
}
2.where标签
where标签的主要作用是对SQL语句中的where关键字进行简化处理,并可以智能地处理其内部and、or等关键字,避免多余字符带来的语法错误。
①.在上一个xml中进行更改
<select id="selectList" resultType="sysUser">
select * from t_sys_user
<where>
<if test="realName != null and realName != '' ">
and realName like conact('%',#{realName},'%')
</if>
<if test="roleId != null">
roleId=#{roleId}
</if>
</where>
</select>
3.choose(when、otherwise)
choose标签是一个组合标签,通常与when、otherwise标签配合使用,实现类似于Java中的switch语句的功能。
①.在接口处创建方法
List<SysUser> selectListByChoose(@Param("realName") String realName, @Param("account") String account, @Param("roleId") int roleId, @Param("createdTime") Date createdTime);
②.在xml中编写SQL语句
<select id="selectListByChoose" resultType="sysUser">
select * from t_sys_user
<where>
<choose>
<when test="realName != null and realName != '' ">
and realName like concat('%',#{realName},'%')
</when>
<when test="roleId != null">
and roleId=#{roleId}
</when>
<when test="account != null and account != ' ' ">
and account like concat('%',#{account},'%')
</when>
<otherwise>
and YEAR(createdTime)=YEAR(#{createdTime})
</otherwise>
</choose>
</where>
</select>
③.编写测试类
@Test
public void testGetUserListByChoose() {
List<SysUser> userList = new ArrayList<SysUser>();
try {
sqlSession = MyBatisUtil.createSqlSession();
String realName = "";
int roleId = 2;
String accunt = "zhong";
Date createdTime = new SimpleDateFormat("yyyy-MM-dd").parse("2019-11-11");
userList = sqlSession.getMapper(SysUserMapper.class).selectListByChoose(realName, accunt, roleId, createdTime);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.info("查询到用户数量:" + userList.size());
for (SysUser user : userList) {
logger.info("查询到用户信息:" + user);
}
}
二.Mybatis框架动态SQL处理集合参数
1.foreach标签处理数组类型参数
MyBatis框架通过foreach标签对这类参数进行循环处理,最终拼出一个符合MySQL语法的in语句来处理这类参数。
下面是语法中的属性介绍:<foreach collection="参数名称" item="元素名称" open="(" separator="," close=")" index="当前元素位置下标" > #{元素别名} </foreach>
item 遍历数组时,为数组或LIst集合中的元素起别名。 open 起始位置的拼接字符,表示in语句以"("左括号开始。 close 结束位置的拼接字符,表示in语句以"("右括号结束。 Separator 元素之间的连接字符,表示in语句中的元素之间以“,逗号链接 Collection 参数名称。当参数为数组类型时,默认参数名为array。当参数类型为List集合时,默认参数名为list。当参数为Map时,参数名为Map中集合元素所在健值对的 key。
①.在接口处创建方法
public List<SysUser> getUserByRoleIdArray(Integer[] roleIds);
②.在xml中编写SQL语句
<select id="getUserByRoleIdArray" resultType="sysUser">
select * from t_sys_user where roleId in
<foreach collection="array" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
③.编写测试类
@Test
public void testGetUserByRoleIdArray() {
List<SysUser> userList = new ArrayList<SysUser>();
Integer[] roleIds = {1, 2};
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(SysUserMapper.class).getUserByRoleIdArray(roleIds);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.info("查询到用户数量:" + userList.size());
for (SysUser user : userList) {
logger.info("查询到用户信息:" + user);
}
}
2.foreach标签处理List类型数据
①.在接口处创建方法
public List<SysUser> getUserByRoleIdList(List<Integer> roleIdList);
②.在xml中编写SQL语句
<select id="getUserByRoleIdList" resultType="sysUser">
select * from t_sys_user where roleId in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
③.编写测试类
@Test
public void testGetUserByRoleIdList() {
List<SysUser> userList = null;
List<Integer> roelList = new ArrayList<Integer>();
roelList.add(1);
roelList.add(2);
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(SysUserMapper.class).getUserByRoleIdList(roelList);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.info("查询到用户数量:" + userList.size());
for (SysUser user : userList) {
logger.info("查询到用户信息:" + user);
}
}
3.foreach标签处理Map类型数据
①.在接口处创建方法
public List<SysUser> getUserByRoleIdMap(Map<String, Object> roleMap);
②.在xml中编写SQL语句
<select id="getUserByRoleIdMap" resultType="sysUser">
select * from t_sys_user where roleId in
<foreach collection="roleIdList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
③.编写测试类
@Test
public void testGetUserByRoleIdMap() {
List<SysUser> userList = null;
List<Integer> roelList = new ArrayList<Integer>();
roelList.add(1);
roelList.add(2);
Map<String, Object> roleMap = new HashMap<String, Object>();
roleMap.put("roleIdList", roelList);
userList = sqlSession.getMapper(SysUserMapper.class).getUserByRoleIdMap(roleMap);
logger.info("查询到用户数量:" + userList.size());
for (SysUser user : userList) {
logger.info("查询到用户信息:" + user);
}
}
小结:
(1)当参数为数据基本类型或数组、List集合类型时,MyBatis框架会将参数封装在一个Map对象中。
(2)当参数为数组类型时,collection对应值默认为array。
(3)当参数为List集合类型时,collection对应值默认为list
(4)如果使用@Param注解为参数设置了名称,collection对应值为参数名
(5)当参数为Map对象时,collection对应值为该Map对象中数组或集合元素对应的Key。
三.Mybatis框架动态SQL处理更新能力
1.利用ste标签包裹if标签来实现忽略不需要修改的字段。
<update id="update" parameterType="supplier">
update t_supplier
<set>
<if test="supCode !=null">supCode=#{supCode},</if>
<if test="supName !=null">supName=#{supName},</if>
<if test="supDesc !=null">supDesc=#{supDesc},</if>
<if test="supContact !=null">supContact=#{supContact},</if>
<if test="supPhone !=null">supPhone=#{supPhone},</if>
<if test="supAddress !=null">supAddress=#{supAddress},</if>
<if test="supFax !=null">supFax=#{supFax},</if>
<if test="createdUserId !=null">createdUserId=#{createdUserId},</if>
<if test="createdTime !=null">createdTime=#{createdTime},</if>
<if test="updatedTime !=null">updatedTime=#{updatedTime},</if>
<if test="updatedUserId !=null">updatedUserId=#{updatedUserId},</if>
</set>
where id=#{id}
</update>
四.Mybatis框架动态SQL知识扩展
1.trim标签
where、set标签能够动态地为SQL语句添加前后缀,并可以自能地忽略后面的标签前后多余的and、or或逗号等字符。除where和set标签外,MyBatis框架还提供了更为灵活的trim标签来实现类似的功能。
2.trim标签语法
<trim preifix="前缀" suffix="后缀"
prefixOverrides="忽略前缀" suffixOverrides="忽略后缀">
.....
</trim>
五.Mybatis框架分页功能
数据库的limit是分页的关键字。
1.在接口处创建方法
public List<SysUser> selectPageList(@Param("realName") String realName, @Param("roleId") int roleId, @Param("pageBegin") int pageBegin, @Param("pageSize") int pageSize);
2.在xml处编写SQL语句
<select id="selectPageList" resultType="sysUser">
select * from t_sys_user
<trim prefix="where" prefixOverrides="and|or">
<if test="realName !=null and realName !=''">
and realName like concat('%',#{realName},'%')
</if>
<if test="roleId">
and roleId==#{roleId}
</if>
</trim>
order by createdTime desc
limit #{pageBegin},#{pageSize}
</select>
3.测试类
@Test
public void testGetUserPage() {
List<SysUser> userList = new ArrayList<SysUser>();
try {
sqlSession = MyBatisUtil.createSqlSession();
String realName = "";
int roleId = 2;
int pageIndex = 2;
int pageSize = 2;
int pageBegin = (pageIndex - 1) * pageSize;
userList = sqlSession.getMapper(SysUserMapper.class).selectPageList(realName, roleId, pageBegin, pageSize);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.info("查询到用户数量:" + userList.size());
for (SysUser user : userList) {
logger.info("查询到用户信息:" + user);
}
}