SpringBoot整合TKmybatis
前言:最近公司在用tkmybatis,于是乎去看了一下,挺好用的,所以在这里记录一下其用法。
一 什么是TKmybatis
- 就我个人的理解而言,tkmybatis就是一个框架或者说工具,其在mybatis的基础上进行了再次封装。使得我们可以不用写简单而重复的CRUD代码,又一次解放了生产力。
- 如果涉及到多表查询,需要自己写sql哦~ 因为tkmybatis不支持多表查询。
二 SpringBoot如何与TKmybatis整合
简单的说就是引入依赖,继承TKmybatis包的Mapper接口,配置扫描Mapper,对,主要就这,具体如下:
- 引入依赖
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
注意:其他的基本依赖我就不贴出来了,主要贴tkmybatis相关的。
- 基本的
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对应的几个接口而已。
- 启动类需要添加
@MapperScan("com.example.tkmybatis.mapper")
注解,作用是扫描mapper,注意这个注解必须是tkmybatis包下的tk.mybatis.spring.annotation.MapperScan
,千万不要搞错啦,不然会启动不起来。
到此,一个最简单最基本的SpringBoot整合TKmybatis就完成了,启动项目run起来。
简单对比总结:
- 与传统的SpringBoot整合Mybatis相比,这里并没有写任何sql语句,连xml文件也没有;
- 只需要继承
Mapper
接口即可实现基本的CRUD,很显然,这些工作Mapper都帮我们完成了,而Mapper接口又继承了BaseMapper<T>
,ExampleMapper<T>
,RowBoundsMapper<T>
,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);
}
}
OK,就这么多了…
感兴趣的朋友可以去看看源码~