SpringBoot整合TKmybatis

SpringBoot整合TKmybatisSpringBoot 整合 TKmybatis 前言 最近公司在用 tkmybatis 于是乎去看了一下 挺好用的 所以在这里记录一下其用法 一什么是 TKmybatis 就我个人的理解而言 tkmybatis 就是一个框架或者说工具 其在 mybatis 的基础上进行了再次封装 使得我们可以不用写简单而重复的 CRUD 代码 又一次解放了生产力 如果涉及到多表查询 需要自己写 sql 哦 因为 tkmybat

SpringBoot整合TKmybatis

前言:最近公司在用tkmybatis,于是乎去看了一下,挺好用的,所以在这里记录一下其用法。

一 什么是TKmybatis

  • 就我个人的理解而言,tkmybatis就是一个框架或者说工具,其在mybatis的基础上进行了再次封装。使得我们可以不用写简单而重复的CRUD代码,又一次解放了生产力。
  • 如果涉及到多表查询,需要自己写sql哦~ 因为tkmybatis不支持多表查询。

二 SpringBoot如何与TKmybatis整合

简单的说就是引入依赖,继承TKmybatis包的Mapper接口,配置扫描Mapper,对,主要就这,具体如下:

  1. 引入依赖
 <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> 

注意:其他的基本依赖我就不贴出来了,主要贴tkmybatis相关的。

  1. 基本的bean mapper service controller之类的我就不多说了,bean目录下只有一个实体类User,service和controller就是基本的业务层和控制层。关键在于mapper,mapper目录下创建一个UserMapper接口,继承Mapper(tk.mybatis.mapper.common.Mapper)
    目录结构如下:
    在这里插入图片描述
    User代码如下(注意看注释说明):






import lombok.Data; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; @Data //这是lombok,有它可以省去get set等代码 @Table(name = "t_user") //指定表名 public class User {     @Id //需要指定主键 @Column(name = "userId") //指定mysql用户表字段名,如果不指定,这里的驼峰命名默认对应数据库字段下划线分隔开 private Integer userId; private String username; private Integer age; } 

mapper比较简单,只有一个接口:

import tk.mybatis.mapper.common.Mapper; public interface UserMapper extends Mapper<User> { 
    } 

service层代码如下:

@Service public class UserServiceImpl implements IUserService { 
    //注意这里引入的UserMapper需要继承Mapper,就是上面的mapper @Autowired private UserMapper userMapper; @Override public int addUser(User user) { 
    return userMapper.insertSelective(user); } @Override public User findOneUser(User user) { 
    return userMapper.selectOne(user); } @Override public List<User> findUsers(User user) { 
    return userMapper.select(user); } @Override public int updateUser(User user) { 
    Example example = new Example(User.class); Example.Criteria criteria = example.createCriteria(); //根据主键Id进行更新 criteria.andEqualTo("userId", user.getUserId()); return userMapper.updateByPrimaryKeySelective(user); } @Override public int deleteUser(User user) { 
    return userMapper.delete(user); } } 

controller层就不贴了,就是与service对应的几个接口而已。

  1. 启动类需要添加@MapperScan("com.example.tkmybatis.mapper")注解,作用是扫描mapper,注意这个注解必须是tkmybatis包下的tk.mybatis.spring.annotation.MapperScan,千万不要搞错啦,不然会启动不起来。

到此,一个最简单最基本的SpringBoot整合TKmybatis就完成了,启动项目run起来。

简单对比总结:

  • 与传统的SpringBoot整合Mybatis相比,这里并没有写任何sql语句,连xml文件也没有;
  • 只需要继承Mapper接口即可实现基本的CRUD,很显然,这些工作Mapper都帮我们完成了,而Mapper接口又继承了 BaseMapper
    , ExampleMapper
    , RowBoundsMapper
    , Marker这些接口,那么Mapper具体有哪些方法呢,又分别有什么作用呢?

三 Mapper(tk.mybatis.mapper.common.Mapper)基本介绍

前面提到Mapper继承了几个接口,Mapper的方法都继承自这些接口,具体的方法介绍如下:

//条件删除,Object必须包含主键字段,但凡方法名包含PrimaryKey的,都要求参数包含主键字段 int deleteByPrimaryKey(Object o) //根据实体属性作为条件进行删除,个人建议用这个方法 int delete(Object o) //插入一条数据,null的属性也会保存,不会使用数据库默认值 int insert(Object o) //插入一条数据,null的属性不会保存,会使用数据库默认值,个人建议用这个方法 int insertSelective(Object o) //查询一个实体是否存在 boolean existsWithPrimaryKey(Object o) //顾名思义,查询全部结果 List<T> selectAll() //查询条件Object必须包含主键属性 Object selectByPrimaryKey(Object o) //顾名思义,查询数据条数 int selectCount(Object o) //条件查询,返回值是List List<T> select(Object o) //条件查询,返回值只能有一个,出现多个会抛异常 Object selectOne(Object o) //条件更新,条件必须包含主键字段,null属性也会被更新到数据库 int updateByPrimaryKey(Object o) //条件更新,条件必须包含主键字段,null属性不会被更新到数据库,个人建议使用这个方法 int updateByPrimaryKeySelective(Object o) //根据Example条件删除数据,关于example的介绍,后文会提到 int deleteByExample(Object o) //根据Example条件进行查询 List<T> selectByExample(Object o) //根据Example条件进行查询数据条数 int selectCountByExample(Object o) //根据Example条件查询,返回值只能有一个,查到多个会抛异常 Object selectOneByExample(Object o) //根据Example条件进行更新,null属性会被更新到数据库,第一个参数是实体列,第二个参数是Example int updateByExample(Object o, Object o2) //同上,区别在于null属性不会被更新到数据库 int updateByExampleSelective(Object o, Object o2) //Example条件分页查询,RowBounds 是分页参数 List<T> selectByExampleAndRowBounds(Object o, RowBounds rowBounds) //条件分页查询 List<T> selectByRowBounds(Object o, RowBounds rowBounds) 

大概就这么些方法,都是默认实现好了的,简单地说就是crud。不同的地方就在于多了Example参数,区别在于其他参数都是等号查询。那么问题来了,如果我要查询年龄在某个区间或者名字以什么开头的数据,该怎么办呢?其实就是模糊查询通过Example可以实现模糊查询,通过设置RowBounds参数,可以实现数据分页查询

四 Example的使用

如下:

 Example example = new Example(User.class); Example.Criteria criteria = example.createCriteria(); //EqualTo表示等于 第一个参数是bean目录下实体类的属性 第二个参数是查询参数 criteria.andEqualTo("userId", user.getUserId()); //LessThan表示小于 LessThanOrEqualTo表示小于等于 criteria.andLessThan("age", user.getUserId()); //Like不言而喻,其实就是sql拼接 criteria.andLike("username", "%" + user.getUsername()); //还有between之类的我就不一一列举了,感兴趣的朋友可以都去试试... //还有一个分页查询的 设置两个参数即可,第一个参数是从哪个下标开始查询,第二个参数是查询多少条数据 其实就是limit userMapper.selectByExampleAndRowBounds(example, new RowBounds(0, 10)); 

五 自定义XML文件

前面有说过TKmybatis是处理单表查询的,涉及到多表查询的话,肯定还是要自己自定义xml文件写sql语句的。其实这个很简单,就和SpringBoot整合mybatis一样,在配置文件.properties或者.yml增加配置mybatis.mapper-locations=${"这里填写xml文件的路径"}就可以了,然后在UserMapper(针对本篇而言)接口里面增加相应的方法即可。

好了,大概的介绍就这么多。我也是刚开始接触,感兴趣的朋友可以去看看源码。

最后再提一点,因为上面的例子只有一个实体类User,所以我直接让其继承Mapper,然后在IUserService 接口写了很多方法。如果很多实体类的情况下,难道每个接口都要去写crud的抽象方法吗?就像这样:

public interface IUserService { 
    int addUser(User user); User findOneUser(User user); List<User> findUsers(User user); int updateUser(User user); int deleteUser(User user); } 

其实是完全没必要的,这些都可以不用写。

方法就是创建一个公用的IBaseService接口继承Mapper,然后通过一个抽象类实现BaseServiceImpl实现其所有方法,如下:

  • IBaseService
public interface IBaseService<T> extends Mapper<T> { 
    @Override int deleteByPrimaryKey(Object o); @Override int delete(T o); @Override int insert(T o); @Override int insertSelective(T o); @Override List<T> selectAll(); @Override T selectByPrimaryKey(Object o); @Override public int selectCount(T o); @Override public List<T> select(T o); @Override public T selectOne(T o); @Override public int updateByPrimaryKey(T o); @Override public int updateByPrimaryKeySelective(T o); @Override public int deleteByExample(Object o); @Override public List<T> selectByExample(Object o); @Override public int selectCountByExample(Object o); @Override public T selectOneByExample(Object o); @Override public int updateByExample(T o, Object o2); @Override public int updateByExampleSelective(T o, Object o2); @Override public List<T> selectByExampleAndRowBounds(Object o, RowBounds rowBounds); @Override public List<T> selectByRowBounds(T o, RowBounds rowBounds); } 
  • BaseServiceImpl
public abstract class BaseServiceImpl<T> implements IBaseService<T> { 
    @Autowired private Mapper<T> mapper; @Override public int deleteByPrimaryKey(Object o) { 
    return mapper.deleteByPrimaryKey(o); } @Override public int delete(T t) { 
    return mapper.delete(t); } @Override public int insert(T t) { 
    return mapper.insert(t); } @Override public int insertSelective(T t) { 
    return mapper.insertSelective(t); } @Override public List<T> selectAll() { 
    return mapper.selectAll(); } @Override public int selectCount(T t) { 
    return mapper.selectCount(t); } @Override public List<T> select(T t) { 
    return mapper.select(t); } @Override public T selectOne(T t) { 
    return mapper.selectOne(t); } @Override public int updateByPrimaryKey(T t) { 
    return mapper.updateByPrimaryKey(t); } @Override public int updateByPrimaryKeySelective(T t) { 
    return mapper.updateByPrimaryKeySelective(t); } @Override public int deleteByExample(Object t) { 
    return mapper.deleteByExample(t); } @Override public List<T> selectByExample(Object t) { 
    return mapper.selectByExample(t); } @Override public int selectCountByExample(Object t) { 
    return mapper.selectCountByExample(t); } @Override public T selectOneByExample(Object o) { 
    return mapper.selectOneByExample(o); } @Override public int updateByExample(T t, Object o) { 
    return mapper.updateByExample(t, o); } @Override public int updateByExampleSelective(T t, Object o) { 
    return mapper.updateByExampleSelective(t, o); } @Override public List<T> selectByExampleAndRowBounds(Object o, RowBounds rowBounds) { 
    return mapper.selectByExampleAndRowBounds(o, rowBounds); } @Override public List<T> selectByRowBounds(T t, RowBounds rowBounds) { 
    return mapper.selectByRowBounds(t, rowBounds); } @Override public boolean existsWithPrimaryKey(Object o) { 
    return mapper.existsWithPrimaryKey(o); } @Override public T selectByPrimaryKey(Object o) { 
    return mapper.selectByPrimaryKey(o); } } 

如此的话,IUserService里面只需要写自己自定义的xml方法即可,修改之后的service层代码如下:

  • IUservice
public interface IUserService extends IBaseService<User> { 
    } 
  • UserServiceImpl
@Service public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService { 
    } 

controller层还稍作改变,如下:

@RestController public class UserController { 
    @Autowired private IUserService userService; @PostMapping("getOne") public User getOne(User user) { 
    return userService.selectOne(user); } @PostMapping("getAll") public List<User> getAll(User user) { 
    return userService.select(user); } @PostMapping("addUser") public int addUser(User user) { 
    return userService.insertSelective(user); } @PostMapping("updateUser") public int updateUser(User user) { 
    return userService.updateByPrimaryKeySelective(user); } @PostMapping("deleteUser") public int deleteUser(User user) { 
    return userService.delete(user); } } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228995.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午5:43
下一篇 2026年3月16日 下午5:43


相关推荐

  • 层次聚类算法的实现

    层次聚类算法的实现目录 1 作者介绍 2 层次聚类算法介绍 2 1 层次聚类算法原理 2 2 层次聚类算法步骤 2 3 层次聚类算法分类 3 层次聚类算法实现 代码如下 3 1 相关包导入 3 2 生成测试数据集 3 3 层次聚类实现 amp 画出树状图 3 4 获取聚类结果 3 5 对比不同方法聚类效果 4 参考链接 1 作者介绍杨金花 女 西安工程大学电子信息学院 21 级研究生研究方向 基于学习方法的运动目标检测电子邮件 com2 层次聚类算法介绍 2 1 层次聚类算法原理聚类就是对大量未知标注的数据集

    2026年3月18日
    1
  • oracle 创建emp表,dept表

    oracle 创建emp表,dept表废话不多说直接上SQL/*创建empz表*/CREATETABLEEMP(EMPNONUMBER(4)NOTNULL,ENAMEVARCHAR2(10),JOBVARCHAR2(9),MGRNUMBER(4),HIREDATEDATE,SALNUMBER(7,2),COMMNUMBER(7,2),DEPTNONUMBER(2));/*emp表添加数据*/INSERTINTOEMPVALUES(7369,’SMITH’,’CLE..

    2022年5月12日
    59
  • 删除表中重复数据「建议收藏」

    删除表中重复数据「建议收藏」删除表中重复数据

    2022年4月24日
    39
  • django的drf框架的优点_一个类要具有可序列化

    django的drf框架的优点_一个类要具有可序列化前言上一篇文章我们讲述了序列化,这篇就带大家一起来实现以下序列化Serializer我们使用序列化类Serializer,我们来看下源码结构,这里推荐使用pycharm左边导航栏的Structu

    2022年7月31日
    9
  • 通俗易懂的RNN

    通俗易懂的RNNRNN LSTM GRURNN 循环核介绍 参数时间共享 循环层提取时间信息 功能快捷键合理的创建标题 有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中 居左 居右 SmartyPants 创建一个自定义列表如何创建一个注脚注释也是必不可少的 KaTeX 数学公式新的甘特图功能 丰富你的文章 UML 图表 FLowchart 流程图导出与导入导出导入 RNNRNN RecurrentNeu 是一类用于处理序列数据的神经网络 首先我

    2026年3月26日
    2
  • xmind真正有用的几个快捷键(私人总结)

    xmind真正有用的几个快捷键(私人总结)自己总结的常用并且有用的快捷键,不是百度来的,自己一个个地摸索出来的:Ctrl+Shift+L快捷键助手Ctrl+Home返回中心主题Enter插入主题Tab插入子主题F2编辑主题F3添加/编辑标签F4添加/编辑备注F6下钻Shift+F6上钻Delete删除Ctrl+]插入摘要Ctrl+I插入图片Ctrl+Shift+H

    2022年5月27日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号