• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
打工人丶
博客园    首页    新随笔    联系   管理    订阅  订阅

tkMybatis使用详解

1. 什么是tkMybatis

tkMybatis:是基于 Mybatis 框架开发的一个工具,对底层 sql 进行了抽象封装,不需要考虑 sql 怎么写,只需要按照逻辑思维,遵循 tkmybatis 的语法即可实现数据库操作。




2. 入门使用

  1. 添加依赖
    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper-spring-boot-starter</artifactId>
        <version>2.1.5</version>
    </dependency>


  1. 创建 dao 层的 mapper 接口,每个接口都要继承 tk.mybatis.mapper.common.Mapper 接口。此接口的形式为 Mapper,带了个泛型,此泛型一般指的是对应的 pojo 或者 domain。
public interface HouseMapper extends Mapper<House> {

}


3. 实现增删改查

3.1 增加

InsertMapper 接口有一个方法 insert 方法,往数据库表插入一条记录,表有多少个字段,在 tkmybatis 生成的 insert sql 语句中就有多少个字段。

InsertSelectiveMapper 接口有一个方法 insertSelective,实体类参数中不为 null 的字段就会被考虑,在 tkmybatis 生成的 insert sql 语句中只会包含这些不为 null 的字段。


3.2 删除

DeleteByPrimaryKeyMapper接口有一个方法 deleteByPrimaryKey,顾名思义,以表的主键字段作为条件判断,进行删除。

DeleteMapper接口有一个方法 delete,参数就是数据库表对应的Java实体类,参数实体中哪些字段不为null,就会被作为删除sql语句的条件字段,且条件关系是 and,而不是 or。

  注意:在定义实体类时,每个成员变量的类型都应该是Java类,不能是基本类型,比如整型,应该用 Integer,而不是 int。
 
  如果用 int 的话,在没有给 int 成员变量赋值时,ava 会默认给它赋值为 0,由于 0 不是 null,所以会被 tkmybatis 当做是删除条件。

3.3 修改

UpdateByPrimaryKeyMapper 接口有一个方法 updateByPrimaryKey,根据主键字段准确地修改某一条记录。

UpdateByPrimaryKeySelectiveMapper 接口有一个方法 updateByPrimaryKeySelective,根据主键字段准确地修改某一条记录的部分字段(实体类参数的不为 null 的字段)。


3.4 查询

SelectMapper 接口有一个方法 select,参数实体类中哪些字段不为 null,就会被作为 select sql 语句中的条件字段,且字段之间的关系是 and。

    List<T> select(T var1);

SelectOneMapper 接口有一个方法 selectOne,与 select 方法一样,只是返回结果只能为空或者一个,如果有多个,则抛出异常。

    T selectOne(T var1);

SelectCountMapper 接口有一个方法 selectCount,查询满足条件的记录有多少条。

    int selectCount(T var1);

SelectAllMapper 接口有一个方法 selectAll,查询全表所有记录。

    List<T> selectAll();

SelectByPrimaryKeyMapper 接口有一个方法 selectByPrimaryKey,根据主键进行查询。

    T selectByPrimaryKey(Object var1);

ExistsWithPrimaryKeyMapper 接口有一个方法 existsWithPrimaryKey,根据主键查询某条记录是否存在。

    boolean existsWithPrimaryKey(Object var1);


4. 批量增删改查

4.1 批量增加

这两个功能有一个要求,那就是操作的数据库表必须有一个自增主键,因为它要求主键必须要有一个默认值,否则就抛出异常。

这两个接口是集成到 MySqlMapper 接口中了,所以 dao 层的 mapper 接口还要继承 MySqlMapper 接口才能使用批量插入功能。

public interface HouseMapper extends Mapper<House>, MySqlMapper<House> {

}

InsertListMapper 接口有一个方法 insertList,批量插入。
insert into table (所有字段,除了自增主键) values (?,..,?), ...,(?,...,?)


InsertUseGeneratedKeysMapper 接口有一个方法 insertUserGeneratedKeys,单个插入。


4.2 批量查询与批量删除

SelectByIdsMapper 接口有一个方法 selectByIds,按照多个主键 id 值进行查询,但是方法的参数是 String,那么主键id之间用逗号隔开就行。

  List<T> selectByIds(String var1);

DeleteByIdsMapper 接口有一个方法 deleteByIds,按照多个主键 id 值进行删除。

  int deleteByIds(String var1);


5. 自定义查询条件

上图接口都有一个共同点,就是需要 Example 对象作为方法的参数,Example 对象包含了我们各种自定义的查询条件,相当于 sql 语句中 where 部分的条件。


5.1 Example

Example 对象可以理解为 sql 语句层次的设置。

而 Example.criteria 对象可以理解为 sql 语句中的一个单一的条件表达式设置。

使用:

    先创建 Example 对象,再创建 Example.criteria 对象,借助这两个对象,可以灵活地设置各种条件。

    一个 example 包含了若干个 criteria ,每个 criteria 就是 sql 语句中条件部分的一个括号部分(没有嵌套)。
    比如 (id = 5),criteria 包含了一个方法 void setAndOr(String andOr),它的意思相当于在括号前面加上 and 还是 or。

    比如执行了方法 setAndOr("and"),那么 criteria 相当于 and (id = 5),而 example 就把这些 criteria 拼凑起了,比如 example 包含了 2 个 criteria,分别是 (id = 5) 和 and (name = "张三"),那么此 example 的效果就是 (id = 5) and (name = "张三")。

例:
    @Test
    public void testExample1() {
        Example example = new Example(UserEntity.class);
        example.createCriteria().andGreaterThan("useName", "张");
        userMapper.selectByExample(example);
    }

    ==>  Preparing: SELECT id,user_name,sex,age,address,phone FROM t_user WHERE ( ( user_name > ? ) ) 
    ==> Parameters: 张(String)


例:
    where (age > 18 and sex = 1) or ( age < 30 and sex = 0)
    
    @Test
    public void testCriteria1() {
        Example example = new Example(UserEntity.class);
        // 新增条件1
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andGreaterThan("age", 18).andEqualTo("sex", 1);
        // 新增条件2
        Example.Criteria criteria2 = example.createCriteria();
        criteria2.andLessThan("age", 30).andEqualTo("sex", 0);

        // 设计不是很合理,example不应该代表criteria1与criteria2进行逻辑OR
        example.or(criteria2);
        userMapper.selectByExample(example);
    }

    ==>  Preparing: SELECT id,user_name,sex,age,address,phone FROM t_user WHERE ( ( age > ? and sex = ? ) or ( age < ? and sex = ? ) ) 
    ==> Parameters: 18(Integer), 1(Integer), 30(Integer), 0(Integer)


例:sql排序、去重、设置select字段

    @Test
    public void testExample() {
        Example example = new Example(UserEntity.class);
        // 设置排序字段
        example.orderBy("age").asc().orderBy("useName").desc();
        // 设置去重
        example.setDistinct(true);
        // 设置select 子句的字段
        example.selectProperties("age", "useName");

        userMapper.selectByExample(example);
    }

    ==>  Preparing: SELECT distinct age , user_name FROM t_user order by age ASC,user_name DESC 
    ==> Parameters: 


例:分页查询
通过RowBounds来实现分页查询,指定开始和分页大小。

    public Result getPageByEvent(Paging paging, String eventId) {
        // 这是分页
        RowBounds rowBounds = new RowBounds(paging.getPageNum(), paging.getPageSize());
        // new一个Example
        Example example = new Example(Prize.class);
        // 排序
        example.orderBy("singleCont").asc();
        // 添加条件
        Example.Criteria criteria = example.createCriteria();
        // 前面 一个参数对应实体类的 属性,后一个对应 要传的值
        criteria.andEqualTo("eventId", eventId);
        List<Prize> prizes = prizeMapper.selectByExampleAndRowBounds(example, rowBounds);
        return Result.success(new PageInfo<Prize>(prizes));
    }

    SELECT prize FROM t_prize order by ? LIMIT ?, ?
    ==> Parameters: singleCont(String), 1(Integer), 10(Integer)


上表的方法都是“与”关系,即 and。 同样的,有相应的 “或” 关系,即 or。比如 orAllEqualTo、orGreaterThan 等等,都是将方法名中的 “and” 换成 “or”。


那 criteria 能否嵌套呢?能否有更方便的使用方式呢?回答:能,有。如下表:


Example 类包含的方法总结如下表:





6. tkMybatis常用注解

6.1 @Id注解

通用Mapper在执行xxxByPrimaryKey(param)方法时,有两种情况。

    情况一:没有使用@Id注解明确指定主键字段。
  
        select emp_id,emp_name,emp_salary from t_employee where emp_id = ? and emp_name = ? and emp_salary = ?

        // 之所以会生成上面这样的where子句是因为tk将实体类中的所有字段都拿来放在一起作为联合主键查询。


    情况二:使用@Id注解明确标记和数据库表中主键字段对应的实体类属性。

        select emp_id,emp_name,emp_salary from t_employee where emp_id = ?


6.2 @GeneratedValue注解

作用:让通用Mapper在执行insert操作之后将数据库自动生成的主键值回写到实体类对象中。

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer empId;

6.3 @Transient注解

作用:用于标记不与数据库表字段对应的实体类字段。

    @Transient
    private String otherThings; // 非数据库表中字段
posted @ 2022-04-25 21:45  &emsp;不将就鸭  阅读(5011)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3