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");  
  • 相关阅读:
    day17_sql优化——AWR
    [笔记]《HTTP权威指南》- 媒体类型和字符集
    分析 webpack 打包后的代码
    跨站点请求伪造(CSRF)
    如何定制 fis3-jello
    [翻译]简单的实现一个Promise
    浏览器的 bfcache 特性
    Linux 下搭建 FTP 服务器
    better-scroll 源码分析
    [笔记]移动端的 viewport 和各种像素区分
  • 原文地址:https://www.cnblogs.com/a8457013/p/9074974.html
Copyright © 2011-2022 走看看