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-标签,接口,动态sql--G07_第1张图片
image.png

mybatis-标签,接口,动态sql--G07_第2张图片
image.png

1输入参数分类
基本类型,字符串,java bean,map,数组(删除操作时体现),List(添加时体
现)等每种情况定义如下

基本数据类型

字符串数据类型

javabean类型

map类型

2输出类型

int类型

字符串类型

map类型

List类型

[[3.输入输出不同类型的案例测试]{.underline}]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第3张图片
image.png

[数据库字段:]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第4张图片
image.png

1)配置UserMapper.xml






    
    
    
    
    
    
    
    
    
    


    
    
    
    
    
    
    
    
    








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 {

   String  userName =userDao.queryUserNameById(6);
    System.out.println("userName:--"+userName);
}
/**
 * 测试输出类型为Map
 */
@Test
public void queryUserMapById() throws Exception {

   Map  map =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-标签,接口,动态sql--G07_第5张图片
image.png

输入类型字符串

![
mybatis-标签,接口,动态sql--G07_第6张图片
image.png

输入类型javabean


mybatis-标签,接口,动态sql--G07_第7张图片
image.png

输入类型map结果

mybatis-标签,接口,动态sql--G07_第8张图片
image.png

[[输出结果为int]{.underline}]{.smallcaps}

![
mybatis-标签,接口,动态sql--G07_第9张图片
image.png

输出结果 为STRING


mybatis-标签,接口,动态sql--G07_第10张图片
image.png

[[返回结果为map]{.underline}]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第11张图片
image.png

[[返回结果为list]{.underline}]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第12张图片
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 id
        
        INSERT 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);
    public  Integer addUserHasKey(User user); //添加返回主键1
    public  Integer addUserHasKey2(User user); //添加返回主键2
    public  Integer 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);
        Integer  total = 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-标签,接口,动态sql--G07_第13张图片
image.png

[[b.添加记录返回主键(标签)]{.underline}]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第14张图片
image.png

[[c添加记录返回主键(设置属性)]{.underline}]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第15张图片
image.png

[[d批量添加记录]{.underline}]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第16张图片
image.png

3.Update 元素标签使用

3.1更新单条记录返回影响行数

3.2批量更新多条记录 属性配置

[[3.3批量更新实例]

1) UserMapper.xml配置文件


    
        UPDATE user set user_name=#{userName},user_Pwd=#{userPwd} WHERE  id=#{id}
    
    
    
        UPDATE user set user_pwd='123456' where id in(
        
            #{item}
        
        )
    




2)UserMapper接口中添加方法

public interface UserMapper {
    /*
    测试更新操作(接口加方法)
     */
    public  Integer 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-标签,接口,动态sql--G07_第17张图片
image.png

[[b批量更新]
mybatis-标签,接口,动态sql--G07_第18张图片

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-标签,接口,动态sql--G07_第19张图片
image.png

5.sql
sql 元素用来定义一个可以复用的 SQL
语句段,供其它语句调用。比如:


    先定义一个可以复用的sql
     id,user_name as userName,user_pwd as userPwd 

    
    
    
    
    
    


6.参数(Parameters)
MyBatis 的参数可以使用的基本数据类型和 Java 的复杂数据类型。
基本数据类型,string,int,date 等。
但是使用基本数据类型,只能提供一个参数,所以需要使用 Java 实
体类,或 Map 类型做参数类型。通过#{}可以直接得到其属性。

7.字符串替换
默认情况下,使用#{}格式的语法会导致 MyBatis
创建预处理语句属性并安全地设置值
(比如?) 。 这样做更安全, 更迅速, 通常也是首选做法,
不过有时你只是想直接在SQL 语句中插入一个不改变的字符串。 比如, 像 ORDER
BY, 你可以这样来使用:
ORDER BY ${columnName}

8.Result Maps
resultMap 元素是 MyBatis 中最重要最强大的元素. 简单理解它的作用就是描述
对象的属性和数据库的对应关系. 将我们从数据库中查询出来的结果自动映射成
javabean. 有了它我们不但可以单独查询一个表还可以级联查询.


    resultmap的用法
    
        
        
        
    

    
    


二、 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-标签,接口,动态sql--G07_第20张图片
image.png

1)UserMapper.xml中添加if标签,判断模糊匹配的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);
    }


[[测试结果]

```

2.choose, when, otherwise 选择器使用
我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis
提供
了 choose 元素,它有点像 Java 中的 switch 语句

1)配置UserMapper.xml文件





这条语句的意思就是说 如果我传进 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-标签,接口,动态sql--G07_第21张图片
image.png

[[nation设定值值结果]{.underline}]{.smallcaps}

mybatis-标签,接口,动态sql--G07_第22张图片
image.png

*3.trim, where, set*
***前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题,
然后我们再来看第一条的配置

3.1where标签

1)配置UserMapper.xml文件,利用where标签,判断userName或者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-标签,接口,动态sql--G07_第23张图片
image.png

userName和userPwd都设定值,两个条件一起查询

image.png

3.2trim标签

我们还是可以通过自定义 trim 元素来定制我们想要的功能。 比如, 和 where
元素等价的自定义 trim 元素.

prefixOverrides
属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要
的)。它带来的结果就是所有在 prefixOverrides
属性中指定的内容将被移除,并且插
入 prefix 属性中指定的内容。

1)配置UserMapper.xml文件,添加trim标签,自定义prefix内容,模拟where一样的效果.


    


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-标签,接口,动态sql--G07_第24张图片
image.png

4.foreach
**动态 SQL的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN
条件语句或者是批量插入。

 

编写测试方法

@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-标签,接口,动态sql--G07_第25张图片
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);

}


测试结果

image.png

你可能感兴趣的:(mybatis-标签,接口,动态sql--G07)