zoukankan      html  css  js  c++  java
  • 0064 MyBatis动态SQL--choose-when-otherwise--foreach--set--bind

    读写数据库的时候,往往要根据传入的参数的不同,改变sql语句。
    比如:如果传入了某个参数值,那就查询对应的字段,没传入,那就不查,这就是0048中的where--if
    再比如:

    1. 如果传入了某个参数值,那就只查询这个字段,如果没传入,就看下一个字段是否传入,如果这些字段值都没有传入,那就按默认的条件查询。这是choose--when--otherwise
    2. update操作的时候,如果传入了某个参数值,那就更新该字段,如果没传入那就不更新该字段。这是set
    3. 如果要用in查询将某个集合中相关的数据都查出来,这就要foreach
    4. 如果程序传进来的参数值,还需要进一步拼接,这就要bind

    choose--when--otherwise

    查询书籍信息,如果传入了isbn号,那就只查这个字段,没传入的话,就看书名,有的话就查书名,如果isbn和书名都没有,那就把douban评分大于7分的查出来.
    类似于switch,选择一条执行

    <mapper namespace="net.sonng.mbt.mapper.BookMapper">
        <select id="findBooks" parameterType="net.sonng.mbt.entity.Book" resultType="net.sonng.mbt.entity.Book">
            SELECT * FROM book WHERE 
                <choose>
                    <when test="isbn!=null" > <!-- 如果传入了isbn号,那就只按isbn查 -->
                        isbn=#{isbn}
                    </when>
                    <when test="name!=null">   <!-- 如果没传入isbn号,就看是否有书名,有的话就只按书名查 -->
                        `name`=#{name}         <!-- 注意name貌似是mysql的关键字,用上横(上划线)括起来 -->
                    </when>
                    <otherwise>           <!-- 如果isbn和书名都没有,就将douban>7的书籍查出来 -->
                        douban>7     <!-- 实践证明,大于号>在这里可以正常用,换成转移字符:&gt;,也能用 -->
                    </otherwise>
                </choose>
        </select>
    </mapper>
    

    BookMapper.java接口略
    测试类:

    package net.sonng.mbt.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    import net.sonng.mbt.entity.Book;
    import net.sonng.mbt.mapper.BookMapper;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class BookTest {
        public static void main(String[] args) throws IOException{
            InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session=sqlSessionFactory.openSession();
            BookMapper bookMapper=session.getMapper(BookMapper.class);
            Book book=new Book();
            book.setName("深入理解Java 7 核心技术与最佳实践");
            book.setPress("机械工业出版社");
            book.setAuthor("成富著");
            book.setDouban(6.9f);
            book.setIsbn("9787111380399");                  //传入了isbn
            List<Book> books=bookMapper.findBooks(book);
            for(Book b:books){
                System.out.println(b);
            }
        }
    }
    

    输出如下:

    DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE isbn=?   //传入了isbn就只按isbn查
    DEBUG [main] - ==> Parameters: 9787111380399(String)
    DEBUG [main] - <==      Total: 1
    Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=6.9]
    

    book.setIsbn("9787111380399"); 注释掉,输出如下:

    DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE `name`=?         //没有isbn,有name,就只按name查
    DEBUG [main] - ==> Parameters: 深入理解Java 7 核心技术与最佳实践(String)
    DEBUG [main] - <==      Total: 1
    Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=6.9]
    
    

    book.setName("深入理解Java 7 核心技术与最佳实践");注释掉,输出如下:

    DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE douban>7   //isbn和书名都没有,就把douban>7的列出了,下面有3条查询结果
    DEBUG [main] - ==> Parameters: 
    DEBUG [main] - <==      Total: 3
    Book [id=1, name=深入理解Java虚拟机 JVM高级特性与最佳实践, press=机械工业出版社, author=周志明著, isbn=9787111421900, douban=8.8]
    Book [id=2, name=疯狂Java讲义 第3版, press=电子工业出版社, author=李刚著, isbn=9787121236693, douban=7.8]
    Book [id=4, name=Java编程思想 第4版, press=机械工业出版社, author=(美)Bruce Eckel著, isbn=9787111213826, douban=9.1]
    

    set

    更新一条书籍信息,可能更新name、press、isbn、author、douban的一个或多个

        <select id="findBookById" parameterType="int" resultType="net.sonng.mbt.entity.Book">
            SELECT * FROM book WHERE id=#{id}
        </select>
        <update id="updateBook" parameterType="net.sonng.mbt.entity.Book" >
            UPDATE book 
            <set>  <!-- set跟where的作用类似 -->
                <if test="name!=null" >`name`=#{name},</if>
                <if test="press!=null" >press=#{press},</if>
                <if test="author!=null" >author=#{author},</if>
                <if test="isbn!=null" >isbn=#{isbn},</if>
                <if test="douban!=null" >douban=#{douban}</if>
            </set>
            WHERE id=${id}
        </update>
    

    测试类:

    package net.sonng.mbt.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    import net.sonng.mbt.entity.Book;
    import net.sonng.mbt.mapper.BookMapper;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class BookTest {
        public static void main(String[] args) throws IOException{
            InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session=sqlSessionFactory.openSession();
            BookMapper bookMapper=session.getMapper(BookMapper.class);
            Book book=bookMapper.findBookById(5);   //update的时候,一般先将数据查出来再修改数据再更新
            book.setDouban(10.0f);
            bookMapper.updateBook(book);
            session.commit();             //注意不要忘了提交事务
            session.close();
        }
    }
    

    foreach

    用in查询的时候,传入的参数个数不明确,这时候就用foreach进行遍历

        <select id="findBookInId" parameterType="list" resultType="net.sonng.mbt.entity.Book">
            SELECT * FROM book WHERE id In 
            <foreach item="id" index="i" collection="list" open="(" separator="," close=")">
                #{id}
            </foreach>
        </select>
    

    测试类:

    package net.sonng.mbt.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import net.sonng.mbt.entity.Book;
    import net.sonng.mbt.mapper.BookMapper;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class BookTest {
        public static void main(String[] args) throws IOException{
            InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session=sqlSessionFactory.openSession();
            BookMapper bookMapper=session.getMapper(BookMapper.class);
            List<Integer> ids=new ArrayList<Integer>();
            ids.add(1);
            ids.add(2);
            ids.add(5);
            List<Book> books=bookMapper.findBookInId(ids);
            for(Book book:books){
                System.out.println(book);
            }
            session.close();
        }
    }
    

    输出如下:

    DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE id In ( ? , ? , ? ) 
    DEBUG [main] - ==> Parameters: 1(Integer), 2(Integer), 5(Integer)
    DEBUG [main] - <==      Total: 3
    Book [id=1, name=深入理解Java虚拟机 JVM高级特性与最佳实践, press=机械工业出版社, author=周志明著, isbn=9787111421900, douban=8.8]
    Book [id=2, name=疯狂Java讲义 第3版, press=电子工业出版社, author=李刚著, isbn=9787121236693, douban=7.8]
    Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=10.0]
    
    

    foreach元素的几个属性:
    ----item:迭代元素的别名
    ----index:指定一个名字,用于表示在迭代过程中,每次迭代到的位置
    ----collection:传进来的参数的类型:list(单参数且参数类型为List)、array(单参数且参数类型为数组)、map(多参数)
    ----open:in后面的语句以什么开始
    ----separator:元素间的分隔符
    ----close:in后面的语句以什么结束

    bind

    该元素从OGNL表达式创建一个变量并将其绑定到上下文

        <select id="findBookLikeName" parameterType="string" resultType="net.sonng.mbt.entity.Book">
            <bind name="pattern" value="'%'+_parameter+'%'" />   <!-- 传进来的参数是java,这里将其拼接成:%java% -->
            SELECT * FROM book WHERE `name` LIKE #{pattern}
        </select>
    

    测试类:

    package net.sonng.mbt.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import net.sonng.mbt.entity.Book;
    import net.sonng.mbt.mapper.BookMapper;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class BookTest {
        public static void main(String[] args) throws IOException{
            InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session=sqlSessionFactory.openSession();
            BookMapper bookMapper=session.getMapper(BookMapper.class);
            List<Book> books=bookMapper.findBookLikeName("java");
            for(Book book:books){
                System.out.println(book);
            }
            session.close();
        }
    }
    

    输出:

    DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE `name` LIKE ? 
    DEBUG [main] - ==> Parameters: %java%(String)   //传入的参数是拼接后的字符串
    DEBUG [main] - <==      Total: 4
    Book [id=1, name=深入理解Java虚拟机 JVM高级特性与最佳实践, press=机械工业出版社, author=周志明著, isbn=9787111421900, douban=8.8]
    Book [id=2, name=疯狂Java讲义 第3版, press=电子工业出版社, author=李刚著, isbn=9787121236693, douban=7.8]
    Book [id=4, name=Java编程思想 第4版, press=机械工业出版社, author=(美)Bruce Eckel著, isbn=9787111213826, douban=9.1]
    Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=10.0]
    
    

    bind的value属性:
    ----_parameter:注意下划线,表示传进来的参数本身
    ----parameter:没有下划线,表示传进来的参数的parameter属性
    ----_parameter.getName():注意下划线,表示调用传进来的参数对象的getName()方法的返回值

    小结

    if:传进来的某个参数不为空,那么查询该字段
    where:可以动态的处理and和,
    choose--otherwise:从前往后,哪个参数传进来了,那就只查询该参数,否则按otherwise查询
    set:用于update语句,跟where作用类似
    foreach:多用于IN查询,用于迭代传进来的参数集合
    bind:将传进来的参数进行一些修改

    这个文档可以看看:https://www.kancloud.cn/digest/andyalien-mybatis/190191

  • 相关阅读:
    P3723 【[AH2017/HNOI2017]礼物】
    P4555 【[国家集训队]最长双回文串】
    manacher学习笔记
    多项式学习笔记
    题解 CF1097F 【Alex and a TV Show】
    docker数据卷容器
    python基础学习
    docker监控之cadvisor
    docker监控系统
    ssh配置详解及公私钥批量分发
  • 原文地址:https://www.cnblogs.com/sonng/p/6681820.html
Copyright © 2011-2022 走看看