Spring Boot (10) mybatis三种动态sql

脚本SQL

  xml配置方式见mybatis讲解,下面是用<script>的方式把它照搬过来,用注解来实现。适于xml配置转换到注解配置

    @Select("<script>select * from cat <if test=\"id != null \"> where id = #{id} </if></script>")
    List<Cat> fintCatById(Cat param);

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

 

在方法中构建SQL

  dao接口中是不能写实现的,所以这里借用内部类来生成动态sql。增删改也有对应的@InsertProvider、@UpdateProvider、@DeleteProvider

    //使用CatDaoProvider类中的findCatById方法 来生成sql
    @SelectProvider(type=CatDaoProvider.class,method = "findCatById")
    List<Cat> findCatById(Cat cat);

    class CatDaoProvider{
        public String findCatById(Cat cat){
            String sql = "select * from Cat";
            if(cat.getId() != null){
                sql += " where id = #{id} ";
            }
            return sql;
        }
    }

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

 

结构化SQL

    class CatDaoProvider{
        public String findUserById(Cat cat) {
            return new SQL(){{
                SELECT("id,cat_name,cat_age");
                FROM("cat");
                if(cat.getId() != null){
                    WHERE("id = #{id}");
                }
                if(cat.getCatName() != null){
                    WHERE("cat_name != #{catName}");
                }
            }}.toString();//内部使用高效的StringBuilder实现sql拼接
        }
    }

把前面的内部类改造一下

  SELECT:表示 要查询的字段,如果一行写不完,可以在第二行再写一个SELECT,这两个SELECT 会只能的进行合并而不会重复。

  FROM和WHERE:跟SELECT一样,可以写多个参数,也可以在多行重复使用,最终会智能合并而不会报错

这样的语句很适合写很长的sql,能够保证代码结构清楚,便于维护,可读性高。但是这种自动生成的sql和hibernate一样,在实现一些复杂语句的sql时会束手无策。

 

List传值错误

  动态sql中,有时要对批量数据进行处理,难免会使用list作为参数

    @SelectProvider(type=CatDaoProvider.class,method = "find")
    List<Map> find(List list);

传递list参数时,在运行时会报传参错误,这是mybatis内部机制造成的,其参数需要是key/value结构,当遇到这里不是Key/value结构的list时,mybatis会自动把它转换成key、value结构,key就是他的名字"list" ,value就是他的值 list,要正确传参需要使用key/value结构的map:

    @SelectProvider(type=CatDaoProvider.class,method = "find")
    List<Map> find(List list);

    class CatDaoProvider{
        public String find(Map map) {
            List list = (List) map.get("list");

 

posted @ 2018-05-29 17:31  海盗船长  阅读(770)  评论(0编辑  收藏  举报