mybatis-标签|mybatis-标签,接口,动态sql--G07

mybatis-02(mapper.xml映射文件,动态sql)
一.mapper xml映射文件
MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强
大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC
代码进
行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL
构建的,并
且比普通的方法做的更好。
SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
? cache -- 给定命名空间的缓存配置。
? cache-ref -- 其他命名空间缓存配置的引用。
? resultMap --
是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加
载对象。
? parameterMap -- 已废弃!老式风格的参数映射。内联参数是首选,这个元素可
能在将来被移除,这里不会记录。
? sql -- 可被其他语句引用的可重用语句块。
? insert -- 映射插入语句
? update -- 映射更新语句
? delete -- 映射删除语句
? select -- 映射查询语句
查询语句是 MyBatis 中最常用的元素之一(映射文件配置见代码)
**1.Select 元素标签使用
**有以下属性可供在查询时配置其对应查询属性

mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 1输入参数分类
基本类型,字符串,java bean,map,数组(删除操作时体现),List(添加时体
现)等每种情况定义如下
基本数据类型
字符串数据类型
javabean类型
map类型
2输出类型
int类型
字符串类型
map类型
List类型
[[3.输入输出不同类型的案例测试]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [数据库字段:]{.smallcaps}

mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png
1)配置UserMapper.xml

select id,user_name as userName,user_pwd as userPwd from user where id=#{id}select id,user_name as userName,user_pwd as userPwd from user where user_name=#{userName}select id,user_name as userName,user_pwd as userPwd from user where user_name=#{userName}select id,user_name as userName,user_pwd as userPwd from user where user_name=#{userName}SELECT count(*) FROM userSELECT user_name FROM user WHERE id=#{id}SELECT * FROM user WHERE id=#{id}SELECT * FROM user

2)UserMapper接口中添加方法
*/ public interface UserMapper { /*测试不同输入类型*/ public User queryUserById(Integer id); public User queryUserByName(String userName); public User queryUserByUser(User user); public User queryUserByMap(Map map); /* 测试不同输出结果类型 */ public Integer queryUserTotal(); public String queryUserNameById(Integer id); public Map queryUserMapById(Integer id); public List queryUserList(); }

3)实现类UserDaoImpl中复写方法
public class UserDaoImpl implements UserMapper { /** * 到整合 spring 时 直接注入即可 */ private SqlSessionFactory build; public UserDaoImpl(SqlSessionFactory build) { this.build = build; }@Override public User queryUserById(Integer id) { SqlSession session = build.openSession(); /** * 调用 selectOne 查询方法 返回单条记录 多条记录会报错! * 参数 1:UserMapper.xml 中对应的 statement id 同时加上命名空间 * 参数 2:输入参数 */ UserMapper userMapper = session.getMapper(UserMapper.class); User user = userMapper.queryUserById(id); session.close(); return user; } /* 测试输入类型为String */ @Override public User queryUserByName(String userName) { SqlSession session = build.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user = userMapper.queryUserByName(userName); session.close(); return user; }/** * 测试输入类型为javabean * @param user * @return */ @Override public User queryUserByUser(User user) { SqlSession session = build.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user2 = userMapper.queryUserByUser(user); session.close(); return user2; }/* 测试输入类型为map */ @Override public User queryUserByMap(Map map) { SqlSession session = build.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user = userMapper.queryUserByMap(map); session.close(); return user; }/** * 测试输出类型为int * @return */ @Override public Integer queryUserTotal() { SqlSession session = build.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.queryUserTotal(); session.close(); return total; }/** * 测试返回结果为字符串 * @param id * @return */ @Override public String queryUserNameById(Integer id) { SqlSession session = build.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); String userName = userMapper.queryUserNameById(id); session.close(); return userName; }/** * 测试返回类型为map * @param id * @return */ @Override public Map queryUserMapById(Integer id) { SqlSession session = build.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); Map map = userMapper.queryUserMapById(id); session.close(); return map; }/** * 返回值为list * @return */ @Override public List queryUserList() { SqlSession session = build.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); List list = userMapper.queryUserList(); session.close(); return list; }}

4)测试类中测试结果
public class UserDaoImplTest {SqlSessionFactory build; UserDaoImpl userDao; @Before public void init() throws IOException { InputStream is= Resources.getResourceAsStream("mybatis.xml"); build = new SqlSessionFactoryBuilder().build(is); userDao = new UserDaoImpl(build); }@Test public void queryUserById() throws Exception { User user = userDao.queryUserById(6); System.out.println(user); } @Test public void queryUserByName() throws Exception { User user = userDao.queryUserByName("jackie02"); System.out.println(user); }/** * 测试输入类型为javabean * @throws Exception */ @Test public void queryUserByUser() throws Exception { User user2 =new User(); user2.setUserName("jackie02"); User user = userDao.queryUserByUser(user2); System.out.println(user); } /** * 测试输入类型为map */ @Test public void queryUserByMap() throws Exception { Map map =new HashMap(); map.put("userName","jackie02"); User user = userDao.queryUserByMap(map); System.out.println(user); } /** * 测试输出类型为int */ @Test public void queryUserTotal() throws Exception {Integer total =userDao.queryUserTotal(); System.out.println("total:--"+total); } /** * 测试输出类型为String */ @Test public void queryUserNameById() throws Exception {StringuserName =userDao.queryUserNameById(6); System.out.println("userName:--"+userName); } /** * 测试输出类型为Map */ @Test public void queryUserMapById() throws Exception {Mapmap =userDao.queryUserMapById(6); System.out.println("map:--"+map); System.out.println("map:value--"+map.get("user_name")); } /** * 测试输出类型为list */ @Test public void queryUserList() throws Exception {List list =userDao.queryUserList(); /*遍历list*/ list.stream().forEach(System.out::println); }}

5)测试结果
输入类型int类型
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 输入类型字符串


![ mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 输入类型javabean

mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 输入类型map结果
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [[输出结果为int]{.underline}]{.smallcaps}


![ mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 输出结果 为STRING

mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [[返回结果为map]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [[返回结果为list]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 2.Insert 元素标签使用
2.1添加记录不返回主键配置
1)UserMapper.xml中配置

sql插入语句

2)UserMapper接口中加方法
3)UserDaoImpl中实现此方法
addUserNoKey();
(注意默认mybatis不自动提交事务)
a:手动提交:session.commit
b:自动提交openSession(true)
4)测试类UserDaoImplTest中测试方法
2.2.添加返回主键
1)UserMapper.xml中增加配置
  • A利用标签方式添加:mysql与oracle不同
mysql情况


select LAST_INSERT_ID() as id

insert into user(user_name,user_pwd) values(#{userName},#{userPwd})

Oracle 情况

SELECT LOGS_SEQ.nextval AS ID FROM DUAL

  • B.或者使用useGeneratedKeys="true" keyProperty="id">添加
2)接口中加方法
3)UserDaoImpl中实现方法
4)UserDaoImplTest中测试方法
2.3. 批量添加记录返回影响总记录行数(属性配置)
2.4添加记录实例
1)UserMapper.xml配置文件
INSERT INTO user( user_name,user_pwd) VALUES ( #{userName},#{userPwd})SELECT LAST_INSERT_ID() as idINSERT INTO user ( user_name, user_pwd ) VALUES ( #{userName}, #{userPwd} ) INSERT INTO user ( user_name, user_pwd ) VALUES ( #{userName}, #{userPwd} ) INSERT INTO user ( user_name, user_pwd ) VALUES ( #{item.userName}, #{item.userPwd} )

2)UserMapper接口中添加方法
public interface UserMapper { /* 测试添加操作(接口中加方法) */ public Integer addUserNoKey(User user); publicInteger addUserHasKey(User user); //添加返回主键1 publicInteger addUserHasKey2(User user); //添加返回主键2 publicInteger addUserBatch(List list); //批量添加

3)UserDaoImpl中实现方法
public class UserDaoImpl implements UserMapper {/** * 到整合 spring 时 直接注入即可 */ private SqlSessionFactory build; public UserDaoImpl(SqlSessionFactory build) { this.build = build; }/** * insert添加记录不返回主键 * @param user * @return */ @Override public Integer addUserNoKey(User user) { SqlSession session = build.openSession(true); //自动提交事务 UserMapper userMapper = session.getMapper(UserMapper.class); Integertotal = userMapper.addUserNoKey(user); //第一种,手动提交事务 /* session.commit(); */ session.close(); return total; }/** * 添加记录返回主键(通过标签配置) * @param * @return */ @Override public Integer addUserHasKey(User user) { SqlSession session = build.openSession(true); // 自动提交 UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.addUserHasKey(user); session.close(); return total; }/** * 添加记录返回主键方式2 * @param user * @return */ @Override public Integer addUserHasKey2(User user) { SqlSession session = build.openSession(true); // 自动提交 UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.addUserHasKey2(user); session.close(); return total; }/** * 批量添加记录返回影响总记录行数 * @param list * @return */ @Override public Integer addUserBatch(List list) { SqlSession session = build.openSession(true); // 自动提交 UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.addUserBatch(list); session.close(); return total; }

4)测试类UserDaoImplTest中测试方法
public class UserDaoImplTest {SqlSessionFactory build; UserDaoImpl userDao; @Before public void init() throws IOException { InputStream is= Resources.getResourceAsStream("mybatis.xml"); build = new SqlSessionFactoryBuilder().build(is); userDao = new UserDaoImpl(build); }/** * 测试添加记录不返回主键 * @throws Exception */ @Test public void addUserNoKey() throws Exception { User user =new User(); //数据库添加一条记录 user.setUserName("test888"); user.setUserPwd("888888"); Integer total = userDao.addUserNoKey(user); System.out.println(total); }/** * 测试添加记录返回主键1 * @throws Exception */ @Test public void addUserHasKey() throws Exception { User user = new User(); user.setUserName("test008"); user.setUserPwd("888888"); userDao.addUserHasKey(user); //取得ID代表返回主键成功 System.out.println("id: "+user.getId()); }/** * 添加记录返回主键2测试 * @throws Exception */ @Test public void addUserHasKey2() throws Exception { User user = new User(); user.setUserName("test009"); user.setUserPwd("99999"); userDao.addUserHasKey2(user); //取得ID代表返回主键成功 System.out.println("id: "+user.getId()); }/** * 批量添加记录测试 * @throws Exception */ @Test public void addUserBatch() throws Exception { List userList =new ArrayList<>(); for(int i=0 ; i<10; i++){//批量添加10条记录 User user = new User(); user.setUserName("test0_"+i); user.setUserPwd("99999"); userList.add(user); } userDao.addUserBatch(userList); }

[[测试结果如下] [[a,添加记录不返回主键配置]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [[b.添加记录返回主键(标签)]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [[c添加记录返回主键(设置属性)]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [[d批量添加记录]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 3.Update 元素标签使用
3.1更新单条记录返回影响行数
3.2批量更新多条记录 属性配置
[[3.3批量更新实例] 1) UserMapper.xml配置文件
UPDATE user set user_name=#{userName},user_Pwd=#{userPwd} WHEREid=#{id} UPDATE user set user_pwd='123456' where id in( #{item} )

2)UserMapper接口中添加方法
public interface UserMapper { /* 测试更新操作(接口加方法) */ publicInteger updateUser(User user); public Integer updateUserBatch(Integer[] ids);

3)UserDaoImpl中实现方法
public class UserDaoImpl implements UserMapper {/** * 到整合 spring 时 直接注入即可 */ private SqlSessionFactory build; public UserDaoImpl(SqlSessionFactory build) { this.build = build; }/** * 更新更新单条记录返回影响行数 * @param user * @return */ @Override public Integer updateUser(User user) { SqlSession session = build.openSession(true); // 自动提交 UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.updateUser(user); session.close(); return total; }/** * 批量更新记录 * @param ids * @return */ @Override public Integer updateUserBatch(Integer[] ids) { SqlSession session = build.openSession(true); // 自动提交 UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.updateUserBatch(ids); session.close(); return total; }

4)测试类UserDaoImplTest中测试方法
public class UserDaoImplTest {SqlSessionFactory build; UserDaoImpl userDao; @Before public void init() throws IOException { InputStream is= Resources.getResourceAsStream("mybatis.xml"); build = new SqlSessionFactoryBuilder().build(is); userDao = new UserDaoImpl(build); }/** * 测试更新单条记录返回受影响行数 */ @Test public void updateUser() throws Exception {User user = new User(); user.setUserName("test_100"); user.setUserPwd("888888"); user.setId(136); userDao.updateUser(user); } /** * 测试批量更新 */ @Test public void updateUserBatch() throws Exception {Integer[] ids ={134,135,136}; userDao.updateUserBatch(ids); }

[[测试结果] [[A更新单条记录]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png

[[b批量更新] mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
4.Delete 元素标签使用
4.1删除单条记录
4.2批量删除多条记录(属性配置)
4.3删除案例
1) UserMapper.xml配置文件
delete from user where id=#{id} delete from user where id in #{item}

2)UserMapper接口中添加方法
public interface UserMapper { /* 测试删除操作 */public Integer delUserById(Integer id); public Integer deleteUserBatch(Integer[] ids);

3)UserDaoImpl中实现方法
public class UserDaoImpl implements UserMapper {/** * 到整合 spring 时 直接注入即可 */ private SqlSessionFactory build; public UserDaoImpl(SqlSessionFactory build) { this.build = build; } /** * 删除单条记录 */ @Override public Integer delUserById(Integer id) { SqlSession session = build.openSession(true); // 自动提交 UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.delUserById(id); session.close(); return total; } /** * 批量删除记录 */ @Override public Integer deleteUserBatch(Integer[] ids) { SqlSession session = build.openSession(true); // 自动提交 UserMapper userMapper = session.getMapper(UserMapper.class); Integer total = userMapper.deleteUserBatch(ids); session.close(); return total; }

4)测试类UserDaoImplTest中测试方法
public class UserDaoImplTest {SqlSessionFactory build; UserDaoImpl userDao; @Before public void init() throws IOException { InputStream is= Resources.getResourceAsStream("mybatis.xml"); build = new SqlSessionFactoryBuilder().build(is); userDao = new UserDaoImpl(build); }/** * 删除单条记录 */ @Test public void delUserById() throws Exception {userDao.delUserById(133); }/** * 批量删除记录 */ @Test public void deleteUserBatch() throws Exception {Integer[] ids = {134,135,136}; userDao.deleteUserBatch(ids); }

[[测试结果] mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 5.sql
sql 元素用来定义一个可以复用的 SQL
语句段,供其它语句调用。比如:
先定义一个可以复用的sql id,user_name as userName,user_pwd as userPwd select from user where id=#{id}select from user where user_name=#{userName}

6.参数(Parameters)
MyBatis 的参数可以使用的基本数据类型和 Java 的复杂数据类型。
基本数据类型,string,int,date 等。
但是使用基本数据类型,只能提供一个参数,所以需要使用 Java 实
体类,或 Map 类型做参数类型。通过#{}可以直接得到其属性。
7.字符串替换
默认情况下,使用#{}格式的语法会导致 MyBatis
创建预处理语句属性并安全地设置值
(比如?) 。 这样做更安全, 更迅速, 通常也是首选做法,
不过有时你只是想直接在SQL 语句中插入一个不改变的字符串。 比如, 像 ORDER
BY, 你可以这样来使用:
ORDER BY ${columnName}
8.Result Maps
resultMap 元素是 MyBatis 中最重要最强大的元素. 简单理解它的作用就是描述
对象的属性和数据库的对应关系. 将我们从数据库中查询出来的结果自动映射成
javabean. 有了它我们不但可以单独查询一个表还可以级联查询.
resultmap的用法 select * from user where user_name=#{userName}

二、 mapper 接口代理方式的 crud 开发\
对于 mapper 接口方式开发,需要遵循 mybatis 开发规范,mybatis 框架可以自
动生成 mapper 接口对象。
完成账户表 crud 操作
开发规则:\
  1. mapper.xml 中 namespace 等于接口类全限定名\
  2. mapper.java 接口中的方法名必须与 mapper.xml 中 statement id 一致\
  3. mapper.java 输入参数类型必须与 mapper.xml 中 statement 的
    parameterType 参数类型一致
    4.mapper.java 中方法的返回值类型必须与 mapper.xml 中对应 statement 返回
    值类型一致。
    **接口名 与映射文件名称 不一致(集成环境)
    映射文件与接口处于同一个包中(非集成环境)
    **
三. 动态 sql 语句\
**3.1基于 xml 配置
**MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似
框架的经验,你就能体会到根据不同条件拼接 SQL
语句有多么痛苦。拼接的时候要确
保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL
这一特性
可以彻底摆脱这种痛苦。它借助 ognl(类似于 jsp 里面的 el
表达式)表达式来完成动
态 sql 的拼接使得非常简便。
1 if 条件判断
动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。
使用 if 标签就是加一个 test 属性作为判断, 如果有多个条件组合判断的话用
and, or连接.
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 1)UserMapper.xml中添加if标签,判断模糊匹配的userName是否为空
select id,user_name as userName,user_pwd as userPwd from user where 1=1 and user_name like concat('%',#{userName},'%') select id,user_name as userName,user_pwd as userPwd from user where 1=1 and user_name like concat('%',#{userName},'%')

2)userMappe.java中添加方法
当参数类型为string时,需要在方法中加@Param("userName"),防止查询出错
public interface UserMapper { /* 测试if条件判断 */ public List queryUserByUserName(User user); public List queryUserByUserName2(@Param("userName") String userName); //避免if标签会造成string取不到值,添加注解

3)测试类MybatisTest测试sql 自动判断并且拼接上了
public class MyBatisTest {UserMapper userMapper; @Before public void init() throws IOException { InputStream is = Resources.getResourceAsStream("mybatis.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is); SqlSession session = build.openSession(); userMapper = session.getMapper(UserMapper.class); }/** * 测试if标签 */ @Test public void queryUserByUserName() { User user = new User(); user.setUserName("test"); List userList = userMapper.queryUserByUserName(user); userList.stream().forEach(System.out::println); }@Test public void queryUserByUserName2() { List userList = userMapper.queryUserByUserName2("test"); //调用的时候直接传值就可以了 userList.stream().forEach(System.out::println); }

[[测试结果] mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
``` 2.choose, when, otherwise 选择器使用
我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis
提供
了 choose 元素,它有点像 Java 中的 switch 语句
1)配置UserMapper.xml文件
SELECT id, user_name as userName real_name as realName from user

这条语句的意思就是说 如果我传进 nation 不为空就查 userName 的值, 否则是
realName 的值
2)UserMapper添加方法
public interface UserMapper {/* 测试choose, when, otherwise 选择器使用 */ public List queryUserByNation(User user);

2)测试类MybatisTest验证
public class MyBatisTest {UserMapper userMapper; @Before public void init() throws IOException { InputStream is = Resources.getResourceAsStream("mybatis.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is); SqlSession session = build.openSession(); userMapper = session.getMapper(UserMapper.class); } /** * 测试choose, when, otherwise 选择器使用 */ @Test public void queryUserByNation() { User user = new User(); user.setNation("china"); List userList = userMapper.queryUserByNation(user); userList.stream().forEach(System.out::println); }

[[测试结果] [[nation为空运行结果]{.underline}]{.smallcaps}

mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png [[nation设定值值结果]{.underline}]{.smallcaps}
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png *3.trim, where, set*
***前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题,
然后我们再来看第一条的配置
3.1where标签
1)配置UserMapper.xml文件,利用where标签,判断userName或者userPwd是否为空进行不同的查询.
select id,user_name as userName,user_pwd as userPwd from user WHERE 1=1 and user_name like concat('%',#{userName},'%') and user_pwd like concat('%',#{userPwd},'%') select id,user_name as userName,user_pwd as userPwd from user and user_name like concat('%',#{userName},'%') and user_pwd like concat('%',#{userPwd},'%')

2)UserMapper中添加查询方法
public interface UserMapper {/** * trim, where, set */public List queryUserList2(User user);

3)MybatisTest进行验证
/** * 测试where标签.根据userName或者userPwd查询 */ @Test public void queryUserList2() { User user = new User(); user.setUserName("test"); //user.setUserPwd("88"); List userList = userMapper.queryUserList2(user); //userList.stream().forEach(System.out::println); }

[[测试结果: userName设定值,userPwd为空时,sql只根据userName查询
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png userName和userPwd都设定值,两个条件一起查询
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 3.2trim标签
我们还是可以通过自定义 trim 元素来定制我们想要的功能。 比如, 和 where
元素等价的自定义 trim 元素.
prefixOverrides
属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要
的)。它带来的结果就是所有在 prefixOverrides
属性中指定的内容将被移除,并且插
入 prefix 属性中指定的内容。
1)配置UserMapper.xml文件,添加trim标签,自定义prefix内容,模拟where一样的效果.
select id,user_name as userName,user_pwd as userPwd from user and user_name like concat('%',#{userName},'%') and user_pwd like concat('%',#{userPwd},'%')

2)UserMapper中添加查询方法
/* 测试trim标签 */ public List queryUserList3(User user);

3)MybatisTest进行验证,结果同上
/** * 测试trim标签,结果同上,模拟where效果 */ @Test public void queryUserList3() { User user = new User(); user.setUserName("test"); user.setUserPwd("88"); List userList = userMapper.queryUserList3(user); //userList.stream().forEach(System.out::println); }

3.3set标签
对于 update 语句, 我们采用去设置值
1)配置UserMapper.xml文件,添加set标签,用来更新user_name与user_pwd.也可以用trim标签自定义实现set的效果
UPDATE user user_name=#{userName}, user_pwd=#{userPwd}, where id=#{id} UPDATE user user_name=#{userName}, user_pwd=#{userPwd}, where id=#{id}

2)UserMapper中添加查询方法
/* 测试set标签 */ public Integer updateUser(User user); public Integer updateUser2(User user);

3)MybatisTest进行验证
/** * 测试set标签 */ @Test public void updateUser() { User user = new User(); user.setUserName("test_132"); user.setUserPwd("test_132"); user.setId(94); /* userMapper.updateUser(user); */ userMapper.updateUser2(user); }

[[测试结果 mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png 4.foreach
**动态 SQL的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN
条件语句或者是批量插入。
select userId, userName, password from user userName in #{item}

编写测试方法
@Test public void testFindUserByUserName() { InputStream is = MybatisSecondaryCacheTest.class.getClassLoader().getResourceAsStream("mybatis.x ml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession session = sessionFactory.openSession(); // 创建参数 Map params = new HashMap<>(); // 创建 string 数组然后转化成 list String[] userName = new String[]{"Tonygogo", "hello", "哈哈哈 "}; params.put("userNameList", Arrays.asList(userName)); //string 数组转 list, key 的名称要与映射文件中的变量名要一直 List users = session.selectList("findUserByUserName", params); System.out.println("查询结果: " + users.toString()); }

四.使用 Ognl 表达式 我们在上面的映射中, 如果用 if
去判断一个值是否为空或者是空字符串时我们是这样
做的 test="userName != null and userName !='' "这样写起来比较复杂,
为此我们采
用 Ognl 表达式@Ognl@isNotEmpty(userName)去判断。
*
Ognl工具类,主要是为了在ognl表达式访问静态方法时可以减少长长的类名称编写
* Ognl访问静态方法的表达式为: @class@method(args)
使用 ognl 表达式时我们要在根目录的包下面加上 Ognl 的一个 Java 类,
这里面会有各种各样的判断比如
为空判断@Ognl@isEmpty(userName)
不为空判断@Ognl@isNotEmpty(userName),
是否是空字符串@Ognl@isBlank(userName),
不为空字符串@Ognl@isNotBlank(userName)等等
我们常用的可能就是这四个,它只是方便我们去做一些操作,实际中也会用到
五.**注解形式动态 **sql\
**除了 xml 配置能够支持动态 sql 外,MyBatis 提供了各种注解如
@InsertProvider,@UpdateProvider,@DeleteProvider
和@SelectProvider,来帮助构
建动态 SQL 语句,然后让 MyBatis 执行这些 SQL 语句。

mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png
1)新建AccountDao接口,查询字符串sql由AccountProvider
类queryAccountByParams方法提供
public interface AccountDao {/** * 多条件查询账户记录 *查询字符串sql由AccountProvider 类queryAccountByParams方法提供 * @param aname * @param type * @param time * @return */ @SelectProvider(method="queryAccountByParams",type=AccountProvider.class) public List queryAccountByParams(@Param("aname") String aname, @Param("type") String type, @Param("time") String time);

2)新建AccountProvider类
public class AccountProvider {/** * 返回多条件查询sql字符串 * @param aname * @param type * @param time * @return */ public String queryAccountByParams(@Param("aname") final String aname, @Param("type")final String type, @Param("time")final String time){ String sql= new SQL(){{ SELECT("id,aname,type,remark,create_time as createTime,update_time as updateTime,user_id as userId"); FROM("account"); WHERE(" 1=1 "); if(!StringUtils.isNullOrEmpty(aname)){ WHERE(" aname like concat('%',#{aname},'%') "); } if(!StringUtils.isNullOrEmpty(type)){ WHERE(" type =#{type}"); } if(!StringUtils.isNullOrEmpty(time)){ WHERE(" create_time <=#{time}"); } }}.toString(); return sql; }}

3)测试MybatisTest,测试传不同参数查询结果
/** * 测试注解方式多条件查询账户记录 */ @Test public void queryAccountByParams() {List list = accountDao.queryAccountByParams("zhang8","1",null); list.stream().forEach(System.out::println); }

【mybatis-标签|mybatis-标签,接口,动态sql--G07】测试结果
mybatis-标签|mybatis-标签,接口,动态sql--G07
文章图片
image.png

    推荐阅读