Mybatis的动态SQL
Posted pere
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis的动态SQL相关的知识,希望对你有一定的参考价值。
L110301X1:
查询user表中userName字段中姓名含“孙”字且userRole为3的人:
改造testGetUserList5()类,将原来的使用类对象传参改成使用两个参数传参
在UserMapper.xml文件中配置
</select>
<resultMap type="user" id="userList6">
<result property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/>
<result property="userRole" column="userRole"/>
<result property="userRoleName" column="roleName"/>
</resultMap>
<select id="getUserList6" resultMap="userList6">
select u.*,r.roleName from smbms_user u,smbms_role r
where userName like CONCAT (‘%‘,#{userName},‘%‘)
and userRole=#{userRole} and u.userRole=r.id
</select>
UserMapper接口中增加代码
public List<User> getUserList6(
@Param("userName")String userName,@Param("userRole")Integer roleId);
UserMapperTest类增加代码
@Test
public void testGetUserList6() {
List<User> userList=null;
SqlSession sqlSession = null;
String userName="孙";
Integer roleId=3;
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getUserList6(userName,roleId);
} catch (Exception e) {
e.printStackTrace();
}finally{
MyBatisUtil.closeSqlSession(sqlSession);}
for(User user1:userList){
logger.debug("UserMapperTest userCode---> " + user1.getUserCode()
+"and userName:"+user1.getUserName()
+"and userRoleName:"+user1.getUserRoleName()
//+"and age:"+user1.getAge()
+"and address:"+user1.getAddress());}}
结果:Preparing: select u.*,r.roleName from smbms_user u,smbms_role r where userName like CONCAT (‘%‘,?,‘%‘) and userRole=? and u.userRole=r.id
Parameters: 孙(String), 3(Integer)
L110301X2:
查询userName姓名中含“孙”字userRole为null的用户的姓名和角色名称
L110301X1:中代码查询user表中userName字段中姓名含“孙”字且userRole为null的人如果将L110301X1中UserMapperTest的Integer roleId=3;改成Integer roleId=null;
查询结果什么也没有:其拼接的SQL语句为:
Preparing: select u.*,r.roleName from smbms_user u,smbms_role r where userName like CONCAT (‘%‘,?,‘%‘) and userRole=? and u.userRole=r.id
参数为:Parameters: 孙(String), null将参数放入SQL语句看
select u.*,r.roleName from smbms_user u,smbms_role r where userName like CONCAT (‘%‘,孙,‘%‘) and userRole=null and u.userRole=r.id
由于user表中没有userRole=null的人,所以查询结果什么也没有
由于前面结果不对,因此改造代码查询userName字段中姓名含“孙”字的,不管他的userRole是多少的员工姓名和角色名称
在UserMapper.xml文件中配置(resultMap代码不变)
</select>
<select id="getUserList7" resultMap="userList7">
select u.*,r.roleName from smbms_user u,smbms_role r
where u.userRole=r.id
<if test="userRole !=null">
and userRole=#{userRole}
</if>
<if test="userName !=null and userName !=‘‘">
and userName like CONCAT(‘%‘,#{userName},‘%‘)
</if>
</select>
UserMapper接口中增加代码
getUserList6改成getUserList7
UserMapperTest类增加代码
getUserList6改成getUserList7
结果如下:SQL语句为
Preparing: select u.*,r.roleName from smbms_user u,smbms_role r where u.userRole=r.id and userName like CONCAT(‘%‘,?,‘%‘)
参数为:Parameters: 孙(String),结果如下
L110301ZX3:
查询userName=””的,且userRole为3的用户姓名和角色编号
在L110301ZX2的基础上提出需求为,不需要显示角色名称,只需要显示角色编号和用户姓名就可以,(查询角色为3的下面的所有信息)
在UserMapper.xml文件中配置
<select id="getUserList8" resultType="User">
select u.*,r.roleName from smbms_user u,smbms_role r where
<if test="userName !=null and userName !=‘‘">
and userName like CONCAT(‘%‘,#{userName},‘%‘)
</if>
<if test="userRole !=null">
and userRole=#{userRole}
</if>
</select>
其他代码不变将String userName="孙";Integer roleId=null;
改成String userName="";Integer roleId=3;运行结果:
报错,原因在拼接的SQL语句
Preparing: select u.*,r.roleName from smbms_user u,smbms_role r where and userRole=?
从sql语句可以看出where后面直接跟了and,在前面的代码中由于where后面有where u.userRole=r.id所以跟上and没有问题
使用where改造上面的代码解决错误
UserMapper.xml文件中配置,其他代码不变
<select id="getUserList8" resultType="User">
select u.*,r.roleName from smbms_user u,smbms_role r
<where>
<if test="userName !=null and userName !=‘‘">
and userName like CONCAT(‘%‘,#{userName},‘%‘)
</if>
<if test="userRole !=null">
and userRole=#{userRole}
</if>
</where>
</select>
L110301ZX4:
使用trim改造L110301ZX5中代码,需求一样,使用trim代替where
UserMapper.xml文件中配置,其他代码不变
<select id="getUserList9" resultType="User">
select u.*,r.roleName from smbms_user u,smbms_role r
<trim prefix="where" prefixOverrides="and | or">
<if test="userName !=null and userName !=‘‘">
and userName like CONCAT(‘%‘,#{userName},‘%‘)
</if>
<if test="userRole !=null">
and userRole=#{userRole}
</if>
</trim>
</select>
结果同L110301x3一样 1
L110302X1
需求:更新user表中id=17的姓名和地址,其他字段值不变
在UserMapper.xml文件中配置
<update id="modify1" parameterType="user">
update smbms_user set userCode=#{userCode},userName=#{userName},userPassword=#{userPassword},gender=#{gender},birthday=#{birthday},phone=#{phone},address=#{address},userRole=#{userRole},modifyBy=#{modifyBy},modifyDate=#{modifyDate}
where id=#{id}
</update>
UserMapper接口中增加代码
public int modify1(User user);
UserMapperTest类增加代码
@Test
public void testModify1(){
logger.debug("testAdd--------------");
SqlSession sqlSession=null;
int count=0;
try{
sqlSession=MyBatisUtil.createSqlSession();
User user=new User();
user.setId(17);
//user.setUserCode("test001_M");
user.setUserName("测试用户001_M");
user.setAddress("测试地址_M");
//user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1984-12-12"));
//user.setGender(1);
//user.setUserPassword("123123123");
//user.setUserRole(1);
//user.setModifyDate(new Date());
//user.setModifyBy(1);
count=sqlSession.getMapper(UserMapper.class).modify1(user);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
count=0;
}finally{
MyBatisUtil.closeSqlSession(sqlSession);
}
logger.debug("testAdd count--------------"+count);
}
执行结果为:
Preparing: update smbms_user set userCode=?,userName=?, userPassword=?,gender=?,birthday=?, phone=?,address=?,userRole=?, modifyBy=?,modifyDate=? where id=?
Parameters: null, 测试用户001_M(String), null, null, null, null, 测试地址_M(String), null, 1(Integer), null, 17(Integer)
从结果可以看出,执行上述代码后,将其他不修改的字段的值都修改成了null,原因从参数中可以看出,不修改的字段的参数都默认成了null
使用if-set处理上面的问题
在UserMapper.xml文件中配置
<update id="modify1" parameterType="user">
update smbms_user
<set>
<if test="userCode !=null">userCode=#{userCode},</if>
<if test="userName !=null">userName=#{userName},</if>
<if test="userPassword !=null">userPassword=#{userPassword},</if>
<if test="gender !=null">gender=#{gender},</if>
<if test="birthday !=null">birthday=#{birthday},</if>
<if test="phone !=null">phone=#{phone},</if>
<if test="address !=null">address=#{address},</if>
<if test="userRole !=null">userRole=#{userRole},</if>
<if test="modifyBy !=null">modifyBy=#{modifyBy},</if>
<if test="modifyDate !=null">modifyDate=#{modifyDate},</if>
</set>
where id=#{id}
</update>
其他代码不变,执行结果:
Preparing: update smbms_user SET userName=?, address=? where id=?
Parameters: 测试用户001_M(String), 测试地址_M(String), 14(Integer)
从结果可以看出,正是想要的结果,不更新的字段没有被修改
使用trim-set将上面UserMapper.xml文件中配置
中代码改造成以下代码
<update id="modify1" parameterType="user">
update smbms_user
<trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
<if test="userCode !=null">userCode=#{userCode},</if>
<if test="userName !=null">userName=#{userName},</if>
<if test="userPassword !=null">userPassword=#{userPassword},</if>
<if test="gender !=null">gender=#{gender},</if>
<if test="birthday !=null">birthday=#{birthday},</if>
<if test="phone !=null">phone=#{phone},</if>
<if test="address !=null">address=#{address},</if>
<if test="userRole !=null">userRole=#{userRole},</if>
<if test="modifyBy !=null">modifyBy=#{modifyBy},</if>
<if test="modifyDate !=null">modifyDate=#{modifyDate},</if>
</trim>
</update>
其他代码不变,经执行结果与前面一样 2
L110303X1
需求:查询用户角色为3和2的用户列表
在UserMapper.xml文件中配置
<resultMap type="User" id="userMapByRole">
<id property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/>
</resultMap>
<select id="getUserByRoleId_foreach_arrary" resultMap="userMapByRole">
select * from smbms_user where userRole in
<foreach collection="array" item="roleIds"
open="(" separator="," close=")">
#{roleIds}
</foreach>
</select>
UserMapper接口中增加代码
public List<User> getUserByRoleId_foreach_arrary(Integer[] roleId);
UserMapperTest类增加代码
@Test
public void getUserByRoleId_foreach_arrary() {
List<User> userList=new ArrayList<User>();
SqlSession sqlSession = null;
Integer[] userIds={2,3};
try {
sqlSession = MyBatisUtil.createSqlSession();
userList =sqlSession.getMapper(UserMapper.class)
.getUserByRoleId_foreach_arrary(userIds);
} catch (Exception e) {
e.printStackTrace();
}finally{
MyBatisUtil.closeSqlSession(sqlSession);}
for(User user1:userList){
logger.debug("testGetUserList userCode:---> " + user1.getUserCode()+"and userName:"+user1.getUserName()); }}
执行结果为:
Preparing: select * from smbms_user where userRole in ( ? , ? )
Parameters: 2(Integer), 3(Integer)
L110303X2
需求用List替换L110303X1中的array方法
在UserMapper.xml文件中配置
</select>
<select id="getUserByRoleId_foreach_List" resultMap="userMapByRole">
select * from smbms_user where userRole in
<foreach collection="list" item="roleList"
open="(" separator="," close=")">
#{roleList}
</foreach>
</select>
UserMapper接口中增加代码
public List<User> getUserByRoleId_foreach_List(List<Integer> roleList);
UserMapperTest类增加代码
@Test
public void getUserByRoleId_foreach_List() {
List<User> userList=new ArrayList<User>();
SqlSession sqlSession = null;
List<Integer> roleList=new ArrayList<Integer>();
roleList.add(2);
roleList.add(3);
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_List(roleList);
} catch (Exception e) {
e.printStackTrace();
}finally{
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User user1:userList){
logger.debug("testGetUserList userCode:---> " + user1.getUserCode()
+"and userName:"+user1.getUserName());
}
}
结果与L110303X1一样
L110303X3
需求:在上一例子中增加一个参数gender,需要查询出指定性别和用户角色列表下的用户列表
在UserMapper.xml文件中配置
<select id="getUserByConditionMap_foreach_map" resultMap="userMapByRole">
select * from smbms_user where gender=#{gender} and userRole in
<foreach collection="roleIds" item="roleMap"
open="(" separator="," close=")">
#{roleMap}
</foreach>
</select>
UserMapper接口中增加代码
public List<User> getUserByConditionMap_foreach_map(Map<String, Object> conditionMap);
UserMapperTest类增加代码
@Test
public void getUserByConditionMap_foreach_map() {
List<User> userList=new ArrayList<User>();
SqlSession sqlSession = null;
Map<String, Object> conditionMap=new HashMap<String, Object>();
List<Integer> roleList=new ArrayList<Integer>();
roleList.add(2);
roleList.add(3);
conditionMap.put("gender", 1);
conditionMap.put("roleIds", roleList);
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getUserByConditionMap_foreach_map(conditionMap);
} catch (Exception e) {
e.printStackTrace();
}finally{
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User user1:userList){
logger.debug("testGetUserList userCode:---> " + user1.getUserCode()
+"and userName:"+user1.getUserName());
}
}
结果如下:
Preparing: select * from smbms_user where gender=? and userRole in ( ? , ? )
Parameters: 1(Integer), 2(Integer), 3(Integer)
L110303X4
需求:将L110303X2中的单参数封装成Map进行传参
在UserMapper.xml文件中配置
<select id="getUserByRoleId_foreach_map" resultMap="userMapByRole">
select * from smbms_user where userRole in
<foreach collection="rKey" item="roleMap"
open="(" separator="," close=")">
#{roleMap}
</foreach>
</select>
UserMapper接口中增加代码
public List<User> getUserByRoleId_foreach_map(Map<String, Object> roleMap);
UserMapperTest类增加代码
@Test
public void getUserByRoleId_foreach_map() {
List<User> userList=new ArrayList<User>();
SqlSession sqlSession = null;
Map<String, Object> roleMap=new HashMap<String, Object>();
List<Integer> roleList=new ArrayList<Integer>();
roleList.add(2);
roleList.add(3);
roleMap.put("rKey", roleList);
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_map(roleMap);
} catch (Exception e) {
e.printStackTrace();
}finally{
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User user1:userList){
logger.debug("testGetUserList userCode:---> " + user1.getUserCode()
+"and userName:"+user1.getUserName());
}
} 3
L110304X1
需求:传入name、code、role三个参数,在实际查询中可能用一个,也可能用多个,或者一个也没有传入,都没有传入的时候用creationDate查询
在UserMapper.xml文件中配置
<select id="getUserList_choose" resultType="user">
select * from smbms_user where 1=1
<choose>
<when test="userName !=null and userName !=‘‘">
and userName like CONCAT (‘%‘,#{userName},‘%‘)
</when>
<when test="userCode !=null and userCode !=‘‘">
and userCode like CONCAT (‘%‘,#{userCode},‘%‘)
</when>
<when test="userRole !=null">
and userRole=#{userRole}
</when>
<otherwise>
and YEAR(creationDte)=YEAR(#{creationDate})
</otherwise>
</choose>
</select>
UserMapper接口中增加代码
public List<User> getUserList_choose(@Param("userName")String userName,
@Param("userCode")String userCode,
@Param("userRole")Integer userRole,
@Param("creationDate")Date creationDate);
UserMapperTest类增加代码
@Test
public void getUserList_choose() {
List<User> userList=new ArrayList<User>();
SqlSession sqlSession = null;
String userName="";
String userCode="";
Integer userRole=1;
try {
Date creationDate=new SimpleDateFormat("yyyy-MM-dd").parse("2016-01-01");
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getUserList_choose(userName, userCode, userRole, creationDate);
} catch (Exception e) {
e.printStackTrace();
}finally{
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User user1:userList){
logger.debug("testGetUserList userCode:---> " + user1.getUserCode()
+"and userName:"+user1.getUserName());
}
}
结果:
Preparing: select * from smbms_user where 1=1 and userRole=?
Parameters: 1(Integer)
userCode:---> adminand userName:系统管理员
L110305X1
需求:传入name、role参数查询出用户列表,按每页2条记录显示
在UserMapper.xml文件中配置
<resultMap type="user" id="userList10">
<result property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/>
<result property="userRole" column="userRole"/>
<result property="userRoleName" column="roleName"/>
</resultMap>
<select id="getUserList10" resultMap="userList10">
select u.*,r.roleName from smbms_user u,smbms_role r
where u.userRole=r.id
<if test="userName !=null and userName !=‘‘">
and userName like CONCAT(‘%‘,#{userName},‘%‘)
</if>
<if test="userRole !=null">
and userRole=#{userRole}
</if>
order by creationDate DESC limit #{from},#{pageSize}
</select>
UserMapper接口中增加代码
public List<User> getUserList10(@Param("userName")String userName,
@Param("userRole")Integer roleId,
@Param("from")Integer currentPageNo,
@Param("pageSize")Integer page);
UserMapperTest类增加代码
@Test
public void testGetUserList10() {
List<User> userList=null;
SqlSession sqlSession = null;
String userName="";
Integer roleId=null;
以上是关于Mybatis的动态SQL的主要内容,如果未能解决你的问题,请参考以下文章