spring-boot+mybatis动态sql

spring-boot+mybatis动态sql

正文
在讲动态sql前 对mybatis常用的查询注解做一个简单的回顾

实体类

public class User {

    private Integer id;

    private String name;

    private Integer age;

    /**此处省略了get/set**/

}

增加

    //通过Options获取主键
    @Insert("INSERT INTO user(name,age) VALUES (#{name}, #{age}) ")
    @Options(useGeneratedKeys= true, keyProperty="id")
    int insert(User user);

删除

    @Delete("DELETE FROM user WHERE id = #{id}")
    int delete(@Param("id") Integer id);

更新

    @Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
    int update(User user);

查询

    @Select("SELECT id, name, age FROM user WHERE id = #{id}")
    User findById(Integer id);

查询结果映射
单条记录

    @Select("SELECT id, name, age FROM user WHERE id = #{id}")
    @Results({
        @Result(column="id", property="id", javaType = Integer.class),
        @Result(column="name", property="name", javaType = String.class),
        @Result(column="age", property="age", javaType = Integer.class) 
    })
    User findById(Integer id);

一对一查询 select 属性的值为需要级联的方法路径+方法名

    //一对一查询
    @Select("select * from student where id = #{id}")
    @Results(id = "studentMap", value = {
            @Result(column = "id", property = "id", id = true),
            @Result(column= "name", property="name"),
            @Result(column = "clazz_id", property="clazz",one=@One(select = "cn.sunxyz.mapper.ClazzMapper.findById"))
    })
    Student findById(@Param("id")String id);

一对多(和一对一类似 只需要替换成对应得属性和注解与方法即可)

    //一对多查询
    @Select("select * from student where id = #{id}")
    @Results(id = "studentMap", value = {
            @Result(column = "id", property = "id", id = true),
            @Result(column= "name", property="name"),
            @Result(column = "clazz_id", property="clazz",many= @Many(select = "cn.sunxyz.mapper.ClazzMapper.findById"))
    })
    Student findById(@Param("id")String id);

使用@ResultMap 设定返回数据格式
首先在@Results中id属性中定义一个值 在@ResultMap引用即可(在不同类中需添加全类名)

    @Results(
        id = "userMap" ,value={
        @Result(column="id", property="id", javaType = Integer.class),
        @Result(column="name", property="name", javaType = String.class),
        @Result(column="age", property="age", javaType = Integer.class) 
        }
    )
    User findById(Integer id);
    @Select("SELECT id, name, age FROM user")
    @ResultMap("userMap")
    List<User> findAll();

铺垫了这么多 下面开始主题——动态sql
有时候我们需要根据输入 的条件 动态地构建 SQL语句。
MyBatis 为我们提供了各种注解 如:

@InsertProvider,@UpdateProvider,@DeleteProvider,@SelectProvider

这里我们以@SelectProvider注解为例(type 为方法所在的类 ,method 为方法名称)

    // 动态生成sql 
    @SelectProvider(type = UserMapperProvider.class, method = "findByName")
    List<User> findByName(String name);
    // 动态生成sql
    public String findByName(String name) {
        String sql = "SELECT * FROM user";
        if (StringUtils.isEmpty(name)) {
            return sql;
        }
        sql += " WHERE name LIKE '%" + name + "%'";
        return sql;
    }

上面的findByName(String name)方法 在条件少的时侯好像读起来还很容易 但是随着条件的增多 各种关系就变的比较难以理清 如果能有一种类似于 hibernate中hql的语法就好了 mybatis 为我们提供了 new SQL()
现在我们可以将findByName(String name)进行重构一下

    // 使用工具类来准备相同的 SQL 语句
    public String findByName(String name) {

        return new SQL() {
            {
                SELECT("id, name, age");
                FROM("user");
                WHERE("name LIKE '%" + name + "%'");
            }
        }.toString();
    }

关系变得明朗了 这里对new SQL()使用就不再去探究了 更多的方法可以去阅读源码或查找对应的文档

这是对于单个参数 对于 多个参数我们该怎么做呢
如果映射器 Mapper接口 有多个输入参数,我们可以使用 参数类型为,util.Map的方法作为 SQL provider方 法。然后 映射器 Mapper接口 方法 所有 的输入参数将会 被放到 map中,以 param1,param2等等作 为 key,将输入参数按 序作为 value。你也可以 使用 0,1,2等作为 key值来 取的输入参数。——引自 java Persistence with MyBatis3

    //多参使用map
    @SelectProvider(type = UserMapperProvider.class, method = "findByNameAndAge")
    List<User> findByNameAndAge(String name, Integer age);
    public String findByNameAndAge(Map<String, Object> map) {

        String name = (String) map.get("param1");
        Integer age = (Integer) map.get("param2");

        return new SQL() {
            {
                SELECT("id, name, age");
                FROM("user");
                WHERE("name LIKE '%" + name + "%'");
                AND();
                WHERE("age = " + age);
            }
        }.toString();

    }

@InsertProvider,@UpdateProvider,@DeleteProvider注解使用类似于@SelectProvider这里就不再一一展开

如果 知道有知道生成工具的朋友可以留言告知

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值