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