mybatis学习4

数据库表结构可查看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用法

表达式
1el or e2
2el and e2
3el == e2 或 el eq e2
4el ! = e2 或 el neq e2
5el lt e2 :小于
6el lte e2 :小于等于,其他表示为 gt (大于)、 gte (大于等于)
7el + e2 、e2 * e2、 e1/e2 、e1 - e2、e1% e2
8! e或not e:非,取反
9e.method(args): 调用对象方法
10e.property: 对象属性值
11el[e2] :按索引取值( List 、数组和 Map)
12@class@method(args):调用类的静态方法
13. @class@field :调用类的静态字段值
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值