数据库表结构可查看mybatis学习2。
一、Mybatis的动态SQL在XML中支持的几种标签:
if 、choose (when oterwise)、trim (where set)、foreach 、bind
1、if用法
UserMapper:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
// ...省略其他
/**
* WHERE 条件中使用 if
* @param sysUser
* @return
*/
List<SysUser> selectByUser(SysUser sysUser);
/**
* UPDATE 更新列中使用 if
*/
int updateByIdSelective(SysUser sysUser);
/**
* INSERT 动态插入列中使用 if
*/
int insert2Selective(SysUser sysUser);
}
UserMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.linst.mapper.UserMapper">
<!-- 省略其他-->
<select id="selectByUser" resultType="cn.linst.model.SysUser">
select id,
user_name userName ,
user_password userPassword,
user_email userEmail,
user_info userInfo ,
head_img headImg ,
create_time createTime
from sys_user
where 1 = 1
<if test="userName != null and userName != ''">
and user_name like CONCAT('%', #{userName}, '%')
</if>
<if test="userEmail != null and userEmail !=''">
and user_email = #{userEmail}
</if>
</select>
<update id="updateByIdSelective">
update sys_user
set
<if test="userName != null and userName !=''">
user name= #{userName},
</if>
<if test="userPassword != null and userPassword !=''">
user_password= #{userPassword} ,
</if>
<if test="userEmail != null and userEmail != ''">
user_email = #{userEmail},
</if>
<if test="userInfo != null and userInfo != ''">
user_info= #{userInfo},
</if>
<if test="headImg != null">
head_img = #{headImg, jdbcType=BLOB},
</if>
<if test="createTime != null">
create_time = #{createTime, jdbcType=TIMESTAMP},
</if>
id = #{id}
where id = #{id}
</update>
<insert id="insert2Selective" useGeneratedKeys="true" keyProperty="id">
insert into sys_user(
user_name,user_password,
<if test="userEmail != null and userEmail != ''">
user_email,
</if>
user_info,head_img,create_time
) values (
#{userName}, #{userPassword},
<if test="userEmail != null and userEmail != ''">
#{userEmail},
</if>
#{userInfo}, #{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP}
)
</insert>
</mapper>
BaseMapperTest:
package cn.linst;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import java.io.IOException;
import java.io.Reader;
public class BaseMapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init () {
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
UserMapperTest:
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class UserMapperTest extends BaseMapperTest {
@Test
public void selectByUser() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//只查询用户名时
SysUser query = new SysUser();
query.setUserName("test");
List<SysUser> userList = userMapper.selectByUser(query);
Assert.assertTrue(userList.size() > 0);
//只查询 用户邮箱时
query = new SysUser();
query.setUserEmail("test@testemail");
userList = userMapper.selectByUser(query);
Assert.assertTrue(userList.size() > 0);
//当同时查询用户名和邮箱时
query = new SysUser();
query.setUserName("ad");
query.setUserEmail("test@testemail");
userList = userMapper.selectByUser(query);
//由于没有同时符合这两个条件的用户 ,因此查询结采数为
Assert.assertTrue(userList.size() == 0);
} finally {
// 不要忘记关闭 sqlSession
sqlSession.close();
}
}
@Test
public void testUpdateByIdSelective() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建一个新的 user 对象
SysUser user = new SysUser();
//更新 id = 的用户
user.setId(1001L);
//修改邮箱
user.setUserEmail("test@testemail111");
//更新邮箱,特别注意,这里的返回值 result 执行的是 SQL 影响的行数
int result = userMapper.updateByIdSelective(user);
//只更新一条数据
Assert.assertEquals(1, result);
//根据当前 id 查询修改后的数据
user = userMapper.selectById(1001L);
//修改后的名字保持不变,但是邮箱变成了新的
Assert.assertEquals("test", user.getUserName());
Assert.assertEquals("test@testemail111", user.getUserEmail());
} finally {
//为了不影响其他测试,这里选择回滚
sqlSession.rollback();
//不要忘记关闭 sqlSession
sqlSession.close();
}
}
@Test
public void testInsert2Selective() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建一个 user 对象
SysUser user = new SysUser();
user.setUserName("test-selective");
user.setUserPassword("123456");
user.setUserInfo("test info");
user.setUserEmail("test-selective@test-selective");
user.setCreateTime(new Date());
//插入数据库
userMapper.insert2Selective(user);
//获取插入的这条数据
user = userMapper.selectById(user.getId());
Assert.assertEquals("test-selective@test-selective", user.getUserEmail());
} finally {
sqlSession.rollback() ;
//不要忘记关闭 sqlSession
sqlSession .close();
}
}
}
2、choose用法
UserMapperTest:
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class UserMapperTest extends BaseMapperTest {
@Test
public void testSelectByIdOrUserName() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper . class);
//只有id时
SysUser query= new SysUser();
query.setId(1L);
SysUser user = userMapper.selectByIdOrUserName(query) ;
Assert.assertNotNull(user) ;
//当没有id时
query.setId(null);
query.setUserName("admin");
user = userMapper.selectByIdOrUserName(query) ;
Assert.assertNotNull(user);
// 当id和 name 都为空时
query.setUserName(null) ;
user = userMapper.selectByIdOrUserName(query);
Assert.assertNull(user);
} finally {
//不要忘记关闭 sqlSession
sqlSession.close() ;
}
}
}
UserMapper.xml:
<select id="selectByIdOrUserName" resultType="cn.linst.model.SysUser">
select id,
user_name userName ,
user_password userPassword,
user_email userEmail ,
user_info userInfo ,
head_img headImg ,
create_time createTime
from sys_user
where 1 = 1
<choose>
<when test="id != null">
and id= #{id}
</when>
<when test="userName != null and userName !=''">
and user_name = #{userName}
</when>
<otherwise>
and 1 = 2
</otherwise>
</choose>
</select>
UserMapper:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
/**
* 根据用户 id 或用户名查询
* @param sysUser
* @return
*/
SysUser selectByIdOrUserName(SysUser sysUser);
}
3、where用法
UserMapper.xml:
<select id="selectByUser2Where" resultType="cn.linst.model.SysUser">
select id,
user_name userName,
user_password userPassword,
user_email userEmail,
user_info userinfo,
head_img headImg,
create_time createTime
from sys_user
<where>
<if test="userName != null and userName !=''">
and user_name like CONCAT('%', #{userName}, '%')
</if>
<if test="userEmail != '' and userEmail != null">
and user_email = #{userEmail}
</if>
</where>
</select>
UserMapper:
/**
* where用法
* @param sysUser
* @return
*/
List<SysUser> selectByUser2Where(SysUser sysUser);
UserMapperTest:
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class UserMapperTest extends BaseMapperTest {
@Test
public void selectByUser2Where() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//只查询用户名时
SysUser query = new SysUser();
query.setUserName("test");
List<SysUser> userList = userMapper.selectByUser2Where(query);
Assert.assertTrue(userList.size() > 0);
//只查询 用户邮箱时
query = new SysUser();
query.setUserEmail("test@testemail");
userList = userMapper.selectByUser2Where(query);
Assert.assertTrue(userList.size() > 0);
//当同时查询用户名和邮箱时
query = new SysUser();
query.setUserName("ad");
query.setUserEmail("test@testemail");
userList = userMapper.selectByUser2Where(query);
//由于没有同时符合这两个条件的用户 ,因此查询结采数为
Assert.assertTrue(userList.size() == 0);
} finally {
// 不要忘记关闭 sqlSession
sqlSession.close();
}
}
}
如果if条件满足, where 元素的内容就是以 and 开头的条件, where 会自动去掉开头的 and ,这也能保证 where 条件正确。
4、set用法
set标签的作用:如果该标签包含的元素中有返回值,就插入一个set。如果set后面的字符串是以逗号结尾的,就将这个逗号剔除。
UserMapper.xml:
<update id="updateByIdSelective2Set" >
update sys_user
<set>
<if test="userName != null and userName !=''">
user_name = #{userName} ,
</if>
<if test="userPassword != null and userPassword != ''">
user_password = #{userPassword},
</if>
<if test="userEmail != null and userEmail != ''">
user_email = #{userEmail} ,
</if>
<if test="userInfo != null and userInfo !=''">
user_info = #{userInfo},
</if>
<if test="headImg != null">
head_img = #{headImg, jdbcType=BLOB},
</if>
<if test="createTime != null">
create_time = #{createTime, jdbcType=TIMESTAMP},
</if>
id = #{id},
</set>
where id = #{id}
</update>
UserMapper:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
/**
* UPDATE 更新列中使用 set
*/
int updateByIdSelective2Set(SysUser sysUser);
}
UserMapperTest:
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class UserMapperTest extends BaseMapperTest {
@Test
public void testUpdateByIdSelective2Set() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建一个新的 user 对象
SysUser user = new SysUser();
//更新 id = 的用户
user.setId(1001L);
//修改邮箱
user.setUserEmail("test@testemail111");
//更新邮箱,特别注意,这里的返回值 result 执行的是 SQL 影响的行数
int result = userMapper.updateByIdSelective2Set(user);
//只更新一条数据
Assert.assertEquals(1, result);
//根据当前 id 查询修改后的数据
user = userMapper.selectById(1001L);
//修改后的名字保持不变,但是邮箱变成了新的
Assert.assertEquals("test", user.getUserName());
Assert.assertEquals("test@testemail111", user.getUserEmail());
} finally {
//为了不影响其他测试,这里选择回滚
sqlSession.rollback();
//不要忘记关闭 sqlSession
sqlSession.close();
}
}
}
5、trim用法:
where和set 标签 的功能都可以用 trim 标签来实现,并且在底层就是通过TrimSqlNode 实现的.
<trim prefix="WHERE" prefixOverrides="AND |OR " >
...
</trim>
这里的 AND OR 后面的空格不能省略。
trim标签有以下属性:
属性 | 描述 |
---|---|
prefix | 当 trim 元素内包含内容时,会给内容增加 prefix 指定的前缀。 |
prefixOverrides | 当 trim 元素内包含内容时,会把内容中匹配的前缀字符串去掉。 |
suffix | 当 trim 元素内包含内容时,会给内容增加 suffix 指定的后缀。 |
suffixOverrides | 当 trim 元素内包含内容时,会把内容中匹配的后缀字符串去掉。 |
6、foreach 用法
foreach 遍历的对象可以分为两大类 Iterable类型和 Map 类型。
1)foreach 实现 in 集合
foreach 包含以下属性:
属性 | 描述 |
---|---|
collection | 必填,值为要选代循环的属性名。这个属性值的情况有很多。 |
item | 变量名,值为从迭代对象中取出的每一个值。 |
index | 索引的属性名,在集合数组情况下值为当前索引值 当选代循环的对象是 Map类型时,这个值为 Map的 key (键值)。 |
open | 整个循环内容开头的字符串 |
close | 整个循环内容结尾的字符串 |
separator | 每次循环的分隔符 |
collection属性设置:
Mabatis中wrapCollection实现:
private Object wrapCollection(final Object object) {
if (object instanceof Collection) {
StrictMap<Object> map = new StrictMap<Object> () ;
map.put("collection", object);
if (object instanceof List) {
map.put("list", object);
}
return map;
} else if (object != null && object.getClass().isArray()) {
StrictMap<Object> map = new StrictMap<Object>() ;
map.put("array", object);
return map;
}
return object;
}
当参数类型为集合的时候,默认会转换为 Map 类型,并添加 key为 collection值( MyBatis 3.3.0 版本中增加)。
如果参数类型是 List 集合,那么就继续添加 key 为list的值( MyBatis 3.2.8 及低版本中只有这 key )。
①只有一个数组参数或集合参数
集合参数:
UserMapper:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
/**
* 根据用户 id 集合查询。List
* @param idList
* @return
*/
List<SysUser> selectByIdList1(List<Long> idList);
}
UserMapper.xml:
collection="list"
<select id="selectByIdList1" resultType="cn.linst.model.SysUser">
select id,
user_name userName ,
user_password userPassword,
user_email userEmail,
user_info userInfo ,
head_img headImg,
create_time createTime
from sys_user
where id in
<foreach collection="list" open="(" close = ")" separator=","
item="id" index="i">
#{id}
</foreach>
</select>
UserMapperTest:
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class UserMapperTest extends BaseMapperTest {
@Test
public void testSelectByIdList1() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper = sqlSession.getMapper(UserMapper.class);
List<Long> idList = new ArrayList<Long>();
idList.add(1L);
idList.add(1001L);
List<SysUser> idListResult = userMapper.selectByIdList1(idList);
Assert.assertTrue(idListResult.size() > 0);
} finally {
//为了不影响其他测试,这里选择回滚
sqlSession.rollback();
//不要忘记关闭 sqlSession
sqlSession.close();
}
}
}
数组参数:
UserMapper.xml:
collection="array"
<select id="selectByIdList2" resultType="cn.linst.model.SysUser">
select id,
user_name userName ,
user_password userPassword,
user_email userEmail,
user_info userInfo ,
head_img headImg,
create_time createTime
from sys_user
where id in
<foreach collection="array" open="(" close = ")" separator=","
item="id" index="i">
#{id}
</foreach>
</select>
UserMapper.java:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
/**
* 根据用户 id 集合查询。Array
* @param idArray
* @return
*/
List<SysUser> selectByIdList2(Long[] idArray);
}
UserMapperTest:
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class UserMapperTest extends BaseMapperTest {
@Test
public void testSelectByIdList2() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper = sqlSession.getMapper(UserMapper.class);
Long[] idList = new Long[]{1l, 1001l};
List<SysUser> idListResult = userMapper.selectByIdList2(idList);
Assert.assertTrue(idListResult.size() > 0);
} finally {
//为了不影响其他测试,这里选择回滚
sqlSession.rollback();
//不要忘记关闭 sqlSession
sqlSession.close();
}
}
}
②有多个参数
要使用@Param 注解给每个参数指定一个名字,,此将 collection 设置为@Param 注解指定的名字即可。
③参数是 Map 类型
使用 Map 和使用@ Par am 注解方式类似,将 collection 指定为对应 Map 中的 key 即可。如果要循环所传入的 Map ,推荐使用@Param 注解指定名字,此时可将 collection 置为指定的名字,如果不想指定名字 ,就使用默认值_parameter。
④参数是一个对象
指定为对象的属性名即可。当使用对象内多层嵌套的对象时,使用属性.属性(集合和数组可以使用下标取值)的方式可以指定深层的属性值。
2)foreach 实现批量插入
UserMapper.java:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
/**
* 批量插入用户信息
* @param userList
* @return
*/
int insertList(List<SysUser> userList);
}
UserMapper.xml:
<insert id="insertList">
insert into sys_user(
user_name, user_password, user_email ,
user_info , head_img , create_time)
values
<foreach collection="list" item="user" separator=",">
(#{user.userName}, #{user.userPassword}, #{user.userEmail} ,
#{user.userInfo} , #{user.headImg, jdbcType=BLOB} ,
#{user.createTime , jdbcType=TIMESTAMP})
</foreach>
</insert>
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class UserMapperTest extends BaseMapperTest {
@Test
public void testInsertList () {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 创建一个 user 对象
List<SysUser> userList = new ArrayList<SysUser>();
for (int i = 0; i < 2; i++) {
SysUser user = new SysUser();
user.setUserName("test" + i);
user.setUserPassword("123456");
user.setUserEmail("test@testemail");
userList.add(user);
}
// 将新建的对象批量插入数据库
// 特别注意,这里的返回值 result 是执行 SQL 影响的行数
int result = userMapper.insertList(userList);
Assert.assertEquals(2, result);
} finally {
// 为了不影响其他测试,这里选择回滚
sqlSession.rollback();
//不妥忘记关闭 sqlSession
sqlSession.close();
}
}
}
通过 item 指定了循环变量名后,在引用值的时候使用的是“属性.属性”的方式。如:user.userName
Mybatis 3.3.1 版本开始 MyBatis 开始支持批量新增回写主键值的功能。这个功能首先要求数据库主键值为自增类型,同时还要求该数据库提供 JDBC
驱动可以支持返回批量插入的主键值。
如果要在 SQL中实现批量插入返回自增主键值,只需要在原来 代码基础 上进行如下修改:
<insert id="insertList" useGeneratedKeys="true" keyProperty="id">
<insert id="insertList" useGeneratedKeys="true" keyProperty="id">
insert into sys_user(
user_name, user_password, user_email ,
user_info , head_img , create_time)
values
<foreach collection="list" item="user" separator=",">
(#{user.userName}, #{user.userPassword}, #{user.userEmail} ,
#{user.userInfo} , #{user.headImg, jdbcType=BLOB} ,
#{user.createTime , jdbcType=TIMESTAMP})
</foreach>
</insert>
@Test
public void testInsertList () {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 创建一个 user 对象
List<SysUser> userList = new ArrayList<SysUser>();
for (int i = 0; i < 2; i++) {
SysUser user = new SysUser();
user.setUserName("test" + i);
user.setUserPassword("123456");
user.setUserEmail("test@testemail");
userList.add(user);
}
// 将新建的对象批量插入数据库
int result = userMapper.insertList(userList);
for (SysUser user: userList) {
// 打印回写主键值
System.out.println(user.getId());
}
// 特别注意,这里的返回值 result 是执行 SQL 影响的行数
Assert.assertEquals(2, result);
} finally {
// 为了不影响其他测试,这里选择回滚
sqlSession.rollback();
//不妥忘记关闭 sqlSession
sqlSession.close();
}
}
3)foreach 实现动态 UPDATE
UserMapper.java:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface UserMapper {
/**
* 通过 Map 更新列
*/
int updateByMap(Map<String, Object> map);
}
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.*;
public class UserMapperTest extends BaseMapperTest {
@Test
public void testUpdateByMap () {
SqlSession sqlSession = getSqlSession ();
try {
UserMapper userMapper = sqlSession . getMapper(UserMapper.class);
Map<String, Object> map= new HashMap<String , Object>();
// 查询条件,同样也是更新字段,必须保证该值存在
map.put ("id", 1L);
//要更新的其他字段
map.put("user_email", "test@testemail") ;
map.put("user_password","12345678") ;
//更新数据
userMapper.updateByMap(map) ;
//根据当前 id 查询修改后 的数据
SysUser user = userMapper.selectById(1L);
Assert.assertEquals ("test@testemail", user.getUserEmail() ) ;
} finally {
//为了不影响其他测试,这里选择回滚
sqlSession.rollback();
//不要忘记关闭 sqlSession
sqlSession.close();
}
}
}
UserMapper.xml:
<update id="updateByMap">
update sys_user
set
<foreach collection="_parameter" item="val" index="key" separator=",">
${key} = #{val}
</foreach>
where id = #{id}
</update>
当参数是 Map 类型的时候, foreach 标签的工ndex 属性值对应的不是索引值,而是 Map中的 key ,
通过这个 key 可以实现动态 UPDATE。这里的 key 作为列 ,对应的值作为该列的值。
这里没有通过@Param 注解指定参数名,因而 MyBatis 在内部的上下文中使用了默认值
_parameter 作为该参数的 key ,所以在 XML 使用了_parameter
7、bind用法
使用 concat 函数连接字符串,在 MySQL 中,这个函数支持多个参数,但在 Oracle 中只支持两个参数。
如果更换数据库,还可能要重写sql。为了解决这个问题,可以使用bind标签。
如:原来
<if test="userNarne != null and userName != ''">
and user_name like concat('%', #{userName},'%')
</if>
用bind改写:
<if test="userNarne != null and userNarne !=''">
<bind name="userNameLike" value="'%'+ userName + '%'"/>
and user_name like #{userNameLike}
</if>
bind 标签的两个属性都是必选项, name 为绑定到上下文的变量名,value为OGNL表达式。
二、多数据支持
在mybatis-config.xml中加入以下:
mybatis-config.xml:
<configuration>
<!-- 省略其他-->
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver" />
<property name="DB2" value="db2" />
<property name="Oracle" value="oracle" />
<property name="MySQL" value="mysql"/>
<property name="PostgreSQL" value="postgresql" />
<property name="Derby" value="derby" />
<property name="HSQL" value="hsqldb" />
<property name="H2" value="h2" />
</databaseIdProvider>
</configuration>
UserMapper.xml:
<select id="selectByUser" resultType="cn.linst.model.SysUser" databaseId="mysql">
select id,
user_name userName ,
user_password userPassword,
user_email userEmail,
user_info userInfo ,
head_img headImg ,
create_time createTime
from sys_user
where 1 = 1
<if test="userName != null and userName != ''">
and user_name like CONCAT('%', #{userName}, '%')
</if>
<if test="userEmail != null and userEmail !=''">
and user_email = #{userEmail}
</if>
</select>
UserMapper.java:
package cn.linst.mapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface UserMapper {
/**
* WHERE 条件中使用 if
* @param sysUser
* @return
*/
List<SysUser> selectByUser(SysUser sysUser);
}
UserMapperTest:
package cn.linst;
import cn.linst.mapper.UserMapper;
import cn.linst.model.SysRole;
import cn.linst.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;
import java.util.*;
public class UserMapperTest extends BaseMapperTest {
@Test
public void selectByUser() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//只查询用户名时
SysUser query = new SysUser();
query.setUserName("test");
List<SysUser> userList = userMapper.selectByUser(query);
Assert.assertTrue(userList.size() > 0);
//只查询 用户邮箱时
query = new SysUser();
query.setUserEmail("test@testemail");
userList = userMapper.selectByUser(query);
Assert.assertTrue(userList.size() > 0);
//当同时查询用户名和邮箱时
query = new SysUser();
query.setUserName("ad");
query.setUserEmail("test@testemail");
userList = userMapper.selectByUser(query);
//由于没有同时符合这两个条件的用户 ,因此查询结采数为
Assert.assertTrue(userList.size() == 0);
} finally {
// 不要忘记关闭 sqlSession
sqlSession.close();
}
}
}
三、OGNL用法
表达式 | |
---|---|
1 | el or e2 |
2 | el and e2 |
3 | el == e2 或 el eq e2 |
4 | el ! = e2 或 el neq e2 |
5 | el lt e2 :小于 |
6 | el lte e2 :小于等于,其他表示为 gt (大于)、 gte (大于等于) |
7 | el + e2 、e2 * e2、 e1/e2 、e1 - e2、e1% e2 |
8 | ! e或not e:非,取反 |
9 | e.method(args): 调用对象方法 |
10 | e.property: 对象属性值 |
11 | el[e2] :按索引取值( List 、数组和 Map) |
12 | @class@method(args):调用类的静态方法 |
13 | . @class@field :调用类的静态字段值 |