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,就這麼多了…
感興趣的朋友可以去看看源碼~

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