做者:追夢1819
原文:https://www.cnblogs.com/yanfei1819/p/10876339.html
版權聲明:本文爲博主原創文章,轉載請附上博文連接!
html
在以往的項目中,對於dao層的常規 CRUD 操做,咱們一般使用 JPA、JDBC 時會作一個所謂的 BaseDaoMapper 以減小代碼量。而通用 Mapper 恰好是這一環節的替代品,代碼更簡單,更優雅,也是 Mybatis 用的很普遍的一個插件。java
不過須要注意的一點是,通用 Mapper 支持單表操做,不支持通用的多表聯合查詢。mysql
下面經過用增刪改查的簡單示例,演示 Mapper 的用法,本系列的demo都是按照 Java web 的項目架構來,因此仍是按照 MVC 的模式進行。不過注意,由於此處只是爲了演示最基本的功能。爲了防止捨本逐末,故代碼做了最簡單的優化,只保留最基本的功能代碼,實際業務代碼可能會複雜得多。git
準備工做,初始化數據庫:github
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `age` int(3) NOT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 50 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (14, 'admin', 21); INSERT INTO `user` VALUES (48, 'teacher', 20); INSERT INTO `user` VALUES (49, 'student', 22); SET FOREIGN_KEY_CHECKS = 1;
建立 SpringBoot 項目。web
首先,引入maven依賴(由於通用 Mapper 是創建在 Mybatis 的基礎上的,因此在引入 Mapper 以前,必須先引入Mybatis 依賴):spring
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency>
而後,配置數據庫信息:sql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://192.168.1.88:3306/test?serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=pass123
下一步,建立實體類以做數據庫映射:數據庫
package com.yanfei1819.mybatismapperdemo.entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; /** * Created by 追夢1819 on 2019-05-07. */ @Table(name = "user") public class User { @Id @GeneratedValue(generator = "JDBC") // 自增字段 private Long id; private String name; private int age; // set/get 省略 }
上述的註解:apache
@Table(name = "user")
映射數據表名
@Id
主鍵id
@GeneratedValue(generator = "JDBC")
自增字段
這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(好比:像 MySQL 和 SQL Server 這樣的關係數據庫管理系統的自動遞增字段)。 這種狀況對應的xml相似下面這樣:
<insert id="insertAuthor" useGeneratedKeys="true" keyProperty="id"> insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio}) </insert>
若是表字段與實體類屬性不一致,能夠用註解
再下一步,建立代理接口:
package com.yanfei1819.mybatismapperdemo.dao; import com.yanfei1819.mybatismapperdemo.entity.User; import tk.mybatis.mapper.common.Mapper; /** * Created by 追夢1819 on 2019-05-07. */ @org.apache.ibatis.annotations.Mapper public interface UserMapper extends Mapper<User> { }
該接口就是通用 Mapper 的核心部分。該接口繼承 Mapper。
再者,建立service層接口和實現類:
package com.yanfei1819.mybatismapperdemo.service; import com.yanfei1819.mybatismapperdemo.entity.User; import java.util.List; /** * Created by 追夢1819 on 2019-05-07. */ public interface UserService { int insertUser(User user); int updateUser(User user); int deleteUser(Long id); List<User> listUsers(); User getUserById(Long id); }
實現類:
package com.yanfei1819.mybatismapperdemo.service.impl; import com.yanfei1819.mybatismapperdemo.dao.UserMapper; import com.yanfei1819.mybatismapperdemo.entity.User; import com.yanfei1819.mybatismapperdemo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * Created by 追夢1819 on 2019-05-07. */ @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public int insertUser(User user) { return userMapper.insert(user); } @Override public int updateUser(User user) { return userMapper.updateByPrimaryKey(user); } @Override public int deleteUser(Long id) { return userMapper.deleteByPrimaryKey(id); } @Override public List<User> listUsers() { return userMapper.selectAll(); } @Override public User getUserById(Long id) { return userMapper.selectByPrimaryKey(id); } }
最後,建立controller層:
package com.yanfei1819.mybatismapperdemo.web.controller; import com.yanfei1819.mybatismapperdemo.entity.User; import com.yanfei1819.mybatismapperdemo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * Created by 追夢1819 on 2019-05-07. */ @RestController public class UserController { @Autowired private UserService service; @GetMapping("/listUsers") public List<User> listUser(){ return service.listUsers(); } @GetMapping("/getUserById/{id}") public User getUserById(@PathVariable Long id){ return service.getUserById(id); } @PostMapping("/insertUser") public int insertUser(User user){ return service.insertUser(user); } @PostMapping("/updateUser") public int updateUser(User user){ return service.updateUser(user); } @GetMapping("/deleteUser/{id}") public int deleteUser(@PathVariable Long id){ return service.deleteUser(id); } }
啓動類是:
package com.yanfei1819.mybatismapperdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; //import tk.mybatis.spring.annotation.MapperScan; // 注意此處引入的jar @SpringBootApplication //@MapperScan("com.yanfei1819.mybatismapperdemo.db") public class MybatisMapperDemoApplication { public static void main(String[] args) { SpringApplication.run(MybatisMapperDemoApplication.class, args); } }
要注意一點, UserMapper 接口中的 @org.apache.ibatis.annotations.Mapper
註解能夠被啓動類中的註解 @MapperScan(value = {"com.yanfei1819.mybatismapperdemo.db.*"})
代替。
可是這裏要注意一個坑,使用了通用 Mapper 的導入的 @MapperScan
的jar包,再也不是 import org.mybatis.spring.annotation.MapperScan;
,而是 import tk.mybatis.spring.annotation.MapperScan;
,否則會報錯。
啓動項目,可測試結果。
此處列舉一些經常使用的API:
增
int insert(T record);
保存一個實體,null的屬性也會保存,不會使用數據庫默認值
int insertSelective(T record);
保存一個實體,null的屬性不會保存,會使用數據庫默認值
查
List<T> selectAll();
查詢所有結果
T selectByPrimaryKey(Object key);
根據主鍵字段進行查詢,方法參數必須包含完整的主鍵屬性,查詢條件使用等號
List<T> selectByExample(Object example);
根據Example條件進行查詢
List<T> select(T record);
根據實體中的屬性值進行查詢,查詢條件使用等號
T selectOne(T record);
根據實體中的屬性進行查詢,只能有一個返回值,有多個結果是拋出異常,查詢條件使用等號
int selectCount(T record);
根據實體中的屬性查詢總數,查詢條件使用等號
改
int updateByPrimaryKey(T record);
根據主鍵更新實體所有字段,null值會被更新
int updateByExample(@Param("record") T record, @Param("example") Object example);
根據Example條件更新實體record
包含的所有屬性,null值會被更新
int updateByPrimaryKeySelective(T record);
根據主鍵更新屬性不爲null的值
刪
int deleteByPrimaryKey(Object key);
根據主鍵字段進行刪除,方法參數必須包含完整的主鍵屬性
int delete(T record);
根據實體屬性做爲條件進行刪除,查詢條件使用等號
int deleteByExample(Object example);
根據Example條件刪除數據
文檔一:https://mapperhelper.github.io/docs
文檔二:https://github.com/abel533/Mapper
項目中常規的增刪改查是避免不了的,並且邏輯幾乎不變。若是每個增刪改查都寫一個方法,那冗餘代碼想必很多。即便是代碼生成器生成代碼【參考本人博客:SpringBoot第八篇:整合 MyBatis-Generator】,也是不利於代碼的拓展的。
針對這個問題,有不少解決方案,甚至本身封裝一個通用方法,也何嘗不可(本人工做初期,項目中所用的基本都是這種解決方案)。不過在多方案中,我的仍是比較喜歡通用 Mapper,一是它與 MyBatis 無縫對接;二是代碼量極少,無需配置;固然,更重要的是,已經有現成的輪子了,何須再重複去造輪子呢?
源碼:個人GitHub
<全文完>