SpringBoot 快速整合Mybatis(去XML化+註解進階)

序言:使用MyBatis3提供的註解可以逐步取代XML,例如使用@Select註解直接編寫SQL完成數據查詢,使用@SelectProvider高級註解還可以編寫動態SQL,以應對複雜的業務需求。

一. 基礎註解

MyBatis 主要提供了以下CRUD註解:

  • @Select
  • @Insert
  • @Update
  • @Delete

增刪改查佔據了絕大部分的業務操作,掌握這些基礎註解的使用還是很有必要的,例如下面這段代碼無需XML即可完成數據查詢:

@Mappernpublic interface UserMapper {n @Select("select * from t_user")n List<User> list();n}n

使用過Hibernate的同學可能會好奇,這裡為什麼沒有配置映射關係也能完成屬性注入?在傳統項目中使用過Mybatis的童鞋可能很快就反應過來,是因為在配置文件中開啟了全局駝峰映射,SpringBoot中同樣能夠做到,並且更為簡單快捷。

雖然開啟了全局駝峰映射,但你可能還會質疑,如果不符合下劃線轉駝峰規則的欄位,拿查詢回來的實體對象屬性將獲取為null,比如上述User對象屬性mobileNum和對應的資料庫欄位phoneNum,則查詢結果為:

[n {n "userId": "1",n "username": "admin",n "password": "admin",n "mobileNum": nulln },n {n "userId": "2",n "username": "roots",n "password": "roots",n "mobileNum": nulln }n]n

為了解決對象屬性和欄位駝峰不一致的問題,我們可以使用映射註解@Results來指定映射關係。

二. 映射註解

Mybatis主要提供這些映射註解:

  • @Results 用於填寫結果集的多個欄位的映射關係.
  • @Result 用於填寫結果集的單個欄位的映射關係.
  • @ResultMap 根據ID關聯XML裡面<resultMap>.

例如上面的list方法,我們可以在查詢SQL的基礎上,指定返回的結果集的映射關係,其中property表示實體對象的屬性名,column表示對應的資料庫欄位名。

@Results({n @Result(property = "userId", column = "USER_ID"),n @Result(property = "username", column = "USERNAME"),n @Result(property = "password", column = "PASSWORD"),n @Result(property = "mobileNum", column = "PHONE_NUM")n })n @Select("select * from t_user")n List<User> list();n

查詢結果如下,:

[n {n "userId": "1",n "username": "admin",n "password": "admin",n "mobileNum": "15011791234"n },n {n "userId": "2",n "username": "roots",n "password": "roots",n "mobileNum": "18812342017"n }n]n

為了方便演示和免除手工編寫映射關係的煩惱,這裡提供了一個快速生成映射結果集的方法,具體內容如下:

/**n * 1.用於獲取結果集的映射關係n */n public static String getResultsStr(Class origin) {n StringBuilder stringBuilder = new StringBuilder();n stringBuilder.append("@Results({n");n for (Field field : origin.getDeclaredFields()) {n String property = field.getName();n //映射關係:對象屬性(駝峰)->資料庫欄位(下劃線)n String column = new PropertyNamingStrategy.SnakeCaseStrategy().translate(field.getName()).toUpperCase();n stringBuilder.append(String.format("@Result(property = "%s", column = "%s"),n", property, column));n }n stringBuilder.append("})");n return stringBuilder.toString();n }n

在當前Main方法執行效果如下:然後我們將控制台這段列印信息複製到介面方法上即可。

三. 高級註解

MyBatis-3 主要提供了以下CRUD的高級註解:

  • @SelectProvider
  • @InsertProvider
  • @UpdateProvider
  • @DeleteProvider

見名知意,這些高級註解主要用於動態SQL,這裡以@SelectProvider 為例,主要包含兩個註解屬性,其中type表示工具類,method 表示工具類的某個方法,用於返回具體的SQL。

@Mappernpublic interface UserMapper {n @SelectProvider(type = UserSqlProvider.class, method = "list222")n List<User> list2();n}n

工具類代碼如下:

public class UserSqlProvider {n public String list222() {n return "select * from t_user ;n }n

四. 詳細教程

對上述註解有所了解之後,我們以具體項目案例來進一步鞏固這些註解的實際使用。

具體步驟

1. 引入依賴

為了方便演示,首選搭建Web環境,另外資料庫選擇Mysql 5.5+。

<dependencies>n <dependency> <!--添加Web依賴 -->n <groupId>org.springframework.boot</groupId>n <artifactId>spring-boot-starter-web</artifactId>n </dependency>n <dependency> <!--添加Mybatis依賴 -->n <groupId>org.mybatis.spring.boot</groupId>n <artifactId>mybatis-spring-boot-starter</artifactId>n <version>1.3.1</version>n </dependency>n <dependency><!--添加MySQL驅動依賴 -->n <groupId>mysql</groupId>n <artifactId>mysql-connector-java</artifactId>n <scope>runtime</scope>n </dependency>n <dependency><!--添加Test依賴 -->n <groupId>org.springframework.boot</groupId>n <artifactId>spring-boot-starter-test</artifactId>n <scope>test</scope>n </dependency>n </dependencies>n

2. 添加配置

這裡主要是添加數據源,配置駝峰映射和開啟SQL日誌的控制台列印。在項目的資源目錄中,添加 application.yml 配置如下:

spring:n datasource:n #連接MySQLn url: jdbc:mysql://localhost:3306/socks?useSSL=falsen username: rootn password: rootn driver-class-name: com.mysql.jdbc.Drivernnmybatis:n configuration:n #配置項:開啟下劃線到駝峰的自動轉換. 作用:將資料庫欄位根據駝峰規則自動注入到對象屬性。n map-underscore-to-camel-case: truennlogging:n level:n #列印SQL信息n com.hehe.mapper: debugn

3. 編寫數據層代碼

這裡以我們熟悉的用戶信息為例,編寫UserMapper介面和本案例使用的UserSqlProvider。

3.1 UserMapper

添加UserMapper介面用於數據查詢:

package com.hehe.mapper;n@Mappernpublic interface UserMapper {n /**n * 方式1:使用註解編寫SQL。n */n @Select("select * from t_user")n List<User> list();nn /**n * 方式2:使用註解指定某個工具類的方法來動態編寫SQL.n */n @SelectProvider(type = UserSqlProvider.class, method = "listByUsername")n List<User> listByUsername(String username);nn /**n * 延伸:上述兩種方式都可以附加@Results註解來指定結果集的映射關係.n *n * PS:如果符合下劃線轉駝峰的匹配項可以直接省略不寫。n */n @Results({n @Result(property = "userId", column = "USER_ID"),n @Result(property = "username", column = "USERNAME"),n @Result(property = "password", column = "PASSWORD"),n @Result(property = "mobileNum", column = "PHONE_NUM")n })n @Select("select * from t_user")n List<User> listSample();nn /**n * 延伸:無論什麼方式,如果涉及多個參數,則必須加上@Param註解,否則無法使用EL表達式獲取參數。n */n @Select("select * from t_user where username like #{username} and password like #{password}")n User get(@Param("username") String username, @Param("password") String password);nn @SelectProvider(type = UserSqlProvider.class, method = "getBadUser")n User getBadUser(@Param("username") String username, @Param("password") String password);nn}n

3.2 UserSqlProvider

添加UserSqlProvider,用於生成SQL的工具類 。

package com.hehe.mapper;nn/**n * 主要用途:根據複雜的業務需求來動態生成SQL.n * <p>n * 目標:使用Java工具類來替代傳統的XML文件.(例如:UserSqlProvider.java <-- UserMapper.xml)n */npublic class UserSqlProvider {n /**n * 方式1:在工具類的方法里,可以自己手工編寫SQL。n */n public String listByUsername(String username) {n return "select * from t_user where username =#{username}";n }nn /**n * 方式2:也可以根據官方提供的API來編寫動態SQL。n */n public String getBadUser(@Param("username") String username, @Param("password") String password) {n return new SQL() {{n SELECT("*");n FROM("t_user");n if (username != null && password != null) {n WHERE("username like #{username} and password like #{password}");n } else {n WHERE("1=2");n }n }}.toString();n }n}n

3.3 實體類User

添加實體類User

public class User {n private String userId;n private String username;n private String password;n private String mobileNum;n //Getters & Settersn}n

3.4 添加資料庫記錄

打開Navicat 查詢窗口,然後只需下面這段腳本。

USE `SOCKS`;nDROP TABLE IF EXISTS `t_user`;nCREATE TABLE `t_user` (n `USER_ID` varchar(50) ,n `USERNAME` varchar(50) ,n `PASSWORD` varchar(50) ,n `PHONE_NUM` varchar(15) n) ;nnINSERT INTO `t_user` VALUES (1, admin, admin,15011791234);nINSERT INTO `t_user` VALUES (2, roots, roots,18812342017);n

4. 編寫控制層代碼

package com.hehe.controller;nn@RestControllern@RequestMapping("/user/*")npublic class UserController {nn @SuppressWarnings("all")n @Autowiredn UserMapper userMapper;nn @GetMapping("list")n public List<User> list() {n return userMapper.list();n }nn @GetMapping("list/{username}")n public List<User> listByUsername(@PathVariable("username") String username) {n return userMapper.listByUsername(username);n }nn @GetMapping("get/{username}/{password}")n public User get(@PathVariable("username") String username, @PathVariable("password") String password) {n return userMapper.get(username, password);n }nn @GetMapping("get/bad/{username}/{password}")n public User getBadUser(@PathVariable("username") String username, @PathVariable("password") String password) {n return userMapper.getBadUser(username, password);n }nn}n

5. 啟動和測試

啟動工程後,訪問 localhost:8080/user/lis 可以查看用戶列表如下:

訪問 localhost:8080/user/lis 可以查詢用戶名為admin的信息:

五. 源碼和文檔

源碼地址:SpringBoot-MyBatis-Annotation

官方文檔:Mybatis3-中文手冊

原文作者:yizhiwazi

原文鏈接:SpringBoot 快速整合Mybatis(去XML化+註解進階)

版權說明:本文由APPx小程序生成工具(http://appx.dreawer.com )簽約博主供稿,版權歸作者所有,轉載請註明,有什麼問題,請聯繫我們,謝謝!

推薦閱讀:

為什麼XML這麼笨重的數據結構仍在廣泛應用?
為什麼都反對 XML 而支持使用 JSON?
XML到底是幹什麼的?
關於能否基於XML重新實現TeX?

TAG:Spring | SpringBoot | XML |