zoukankan      html  css  js  c++  java
  • spring boot-mybatis三种动态sql(5)

    脚本sql

    XML配置方式的动态SQL我就不讲了,有兴趣可以自己了解,下面是用<script>的方式把它照搬过来,用注解来实现。适用于xml配置转换到注解配置
    @Select("<script>select * from user <if test="id !=null ">where id = #{id} </if></script>")    
    public List<User> findUserById(User user); 

    很明显,在java中写xml可读性和维护性太差,尤其当SQL很长时,这样写是很痛苦的。

    在方法中构建sql

    dao接口中是不能写实现的,所以这里借用内部类来生成动态SQL。增改删也有对应的@InsertProvider、@UpdateProvider、@DeleteProvider
     
    @Mapper  
    public interface MybatisDao {  
        //使用UserDaoProvider类的findUserById方法来生成sql  
        @SelectProvider(type = UserDaoProvider.class, method = "findUserById")  
        public List<User> findUserById(User user);  
          
        class UserDaoProvider {  
            public String findUserById(User user) {  
                String sql = "SELECT * FROM user";  
                if(user.getId()!=null){  
                    sql += " where id = #{id}";  
                }  
                return sql;  
            }  
        }  

    这比<script>更加清晰,适用于查询语句不是很长、条件不多的场景,SQL很直观。但是在写很长的SQL时,这样拼接SQL同样会很痛苦

    结构化SQL

    public String findUserById(User user) {      
                return new SQL(){{      
                    SELECT("id,name");      
                    SELECT("other");      
                    FROM("user");      
                    if(user.getId()!=null){      
                        WHERE("id = #{id}");      
                    }      
                    if(user.getName()!=null){      
                        WHERE("name = #{name}");      
                    }      
                //从这个toString可以看出,其内部使用高效的StringBuilder实现SQL拼接      
                }}.toString();      
            }      
    这是把前面的内部类改造一下
    SELECT:表示要查询的字段,如果一行写不完,可以在第二行再写一个SELECT,这两个SELECT会智能的进行合并而不会重复
    FROM和WHERE:跟SELECT一样,可以写多个参数,也可以在多行重复使用,最终会智能合并而不会报错
    这样语句适用于写很长的SQL时,能够保证SQL结构清楚。便于维护,可读性高。但是这种自动生成的SQL和HIBERNATE一样,在实现一些复杂语句的SQL时会束手无策。所以需要根据现实场景,来考虑使用哪一种动态SQL
    上面的例子只是最基本的用法:更多详细用法,可以参考mybatis中文网的专门介绍
    http://www.mybatis.org/mybatis-3/zh/statement-builders.html

    List传值错误

    动态SQL中,有时要对批量数据进行处理,难免会使用list做为参数
     
    @SelectProvider(type = UserDaoProvider.class, method = "find")  
        public List<Map> find(List list);      
          
        class UserDaoProvider {  
            public String find(List list) {  

    这是一个最简单的list传参,但是在运行时会报传参错误。这是mybatis内部机制造成的,其参数需要是key/value结构,当遇到这里不是key/value结构的list时,mybatis会自己把它转换成key/value结构,key就是他的名字"list",value就是他的值List,要正确传参需要使用key/value结构的map,如下

    @SelectProvider(type = UserDaoProvider.class, method = "find")  
        public List<Map> find(List list);      
          
        class UserDaoProvider {  
            public String find(Map map) {  
                List list = (List) map.get("list");  
  • 相关阅读:
    48. Rotate Image
    83. Remove Duplicates from Sorted List
    46. Permutations
    HTML5笔记
    18. 4Sum
    24. Swap Nodes in Pairs
    42. Trapping Rain Water
    Python modf() 函数
    Python min() 函数
    Python max() 函数
  • 原文地址:https://www.cnblogs.com/a8457013/p/9074974.html
Copyright © 2011-2022 走看看