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的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis 动态SQL

MyBatis:动态sql语句

MyBatis学习——动态SQL

MyBatis4:动态SQL

mybatis 动态SQL .2

mybatis 详解------动态SQL