SpringBoot整合TKmybatis

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<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,就这么多了…
感兴趣的朋友可以去看看源码~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章