1. 程式人生 > >SpringBoot第六篇:整合通用Mapper

SpringBoot第六篇:整合通用Mapper

作者:追夢1819
原文:https://www.cnblogs.com/yanfei1819/p/10876339.html
版權宣告:本文為博主原創文章,轉載請附上博文連結!

引言

  在以往的專案中,對於dao層的常規 CRUD 操作,我們通常使用 JPA、JDBC 時會做一個所謂的BaseDaoMapper 以減少程式碼量。而通用 Mapper 剛好是這一環節的替代品,程式碼更簡單,更優雅,也是 Mybatis 用的很廣泛的一個外掛。

  不過需要注意的一點是,通用 Mapper 支援單標操作,不支援通用的多表聯合查詢。


使用

  下面通過用增刪改查的簡單示例,演示 Mapper 的用法,本系列的demo都是按照 Java web 的專案架構來,所以還是按照 MVC的模式進行。不過注意,因為此處只是為了演示最基本的功能。為了防止捨本逐末,故程式碼作了最簡單的優化,只保留最基本的功能程式碼,實際業務程式碼可能會複雜得多。

  準備工作,初始化資料庫:

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 專案。

  首先,引入maven依賴(因為通用 Mapper 是建立在 Mybatis 的基礎上的,所以在引入 Mapper 之前,必須先引入Mybatis 依賴):

<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>

  然後,配置資料庫資訊:

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 省略
}

上述的註解:

  • @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

  此處列舉一些常用的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 無縫對接;二是程式碼量極少,無需配置;當然,更重要的是,已經有現成的輪子了,何必再重複去造輪子呢?


<全文完>



相關推薦

SpringBoot整合通用Mapper

作者:追夢1819 原文:https://www.cnblogs.com/yanfei1819/p/10876339.html 版權宣告:本文為博主原創文章,轉載請附上博文連結! 引言   在以往的專案中,對於dao層的常規 CRUD 操作,我們通常使用 JPA、JDBC 時會做一個所謂的BaseDaoMa

精通SpringBoot——整合Redis實現快取

專案中用到快取是很常見的事情, 快取能夠提升系統訪問的速度,減輕對資料庫的壓力等好處。今天我們來講講怎麼在spring boot 中整合redis 實現對資料庫查詢結果的快取。 首先第一步要做的就是在pom.xml檔案新增spring-boot-starter-data-redis。 要整合快取,必

SpringBoot整合JDBCTemplate

values 都是 ice upd ava docs cati cnblogs ble 作者:追夢1819 原文:https://www.cnblogs.com/yanfei1819/p/10868954.html 版權聲明:本文為博主原創文章,轉載請附上博文鏈接! 引言

SpringBoot整合Mybatis

作者:追夢1819 原文:https://www.cnblogs.com/yanfei1819/p/10869315.html 版權宣告:本文為博主原創文章,轉載請附上博文連結! 引言   ORM框架有很多,比如Mybatis、hibernate、JPA、JDBCTemplate等,各自有各自的優點。Myb

SpringBoot整合Mybatis-Plus

作者:追夢1819 原文:https://www.cnblogs.com/yanfei1819/p/10881666.html 版權宣告:本文為博主原創文章,轉載請附上博文連結! 引言   一看這個名字,就能看出與 MyBatis 有關。沒錯,它就是一款 MyBatis 的增強工具。   下面我們先介紹這款

SpringBoot整合Spring Data JPA

作者:追夢1819 原文:https://www.cnblogs.com/yanfei1819/p/10910059.html 版權宣告:本文為博主原創文章,轉載請附上博文連結! 前言   前面幾章,我們介紹了 JDBCTemplate、MyBatis 等 ORM 框架。下面我們來介紹極簡模式的 Sprin

Spring Boot整合Swagger2構建RESTful API文件

由於Spring Boot有快速開發、便捷部署等特性,所以很大一部分Spring Boot的使用者會用來構建RESTfulAPI。而我們構建RESTfulAPI的目的通常都是由於多終端的原因,這些終端會共用很多底層業務邏輯,因此我們會抽象出這樣一層來同時服務於多個移動端或者Web前端。

SpringBoot統一異常處理

一、什麼是異常處理 異常(Exception)是程式在執行時可能出現的會導致程式執行終止的錯誤。這種錯誤是不能通過編譯系統檢查出來的,如果不進行異常處理,程式將中斷無法提供服務。 二、如何使用Spring Boot異常處理 案例: 獲取某個女生的年齡並判斷小於10,返

Spring Boot 基礎系列教程 | 整合MyBatis

推薦 Spring Boot/Cloud 視訊: 最近專案原因可能會繼續開始使用MyBatis,已經習慣於spring-data的風格,再回頭看xml的對映配置總覺得不是特別舒服,介面定義與對映離散在不同檔案中,使得閱讀起來並不是特別方便。 Spring中整合

Spring Cloud spring cloud 整合 配置檔案以及 mybatis

在上幾篇 專案的基礎上來修改服務程式碼。 首先修改,service-hi 專案(服務提供方),pom.xml檔案如下 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave

一起來學 SpringBoot 2.x | 整合 Mybatis

點選上方“芋道原始碼”,選擇“置頂公眾號”技術文章第一時間送達!原始碼精品專欄 摘要: 原創出處

易筋SpringBoot 2.1 | JdbcTemplate訪問MySQL

寫作時間:2019-01-03 Spring Boot: 2.1 ,JDK: 1.8, IDE: IntelliJ IDEA, MySQL 8.0.13 說明 資料需要持久化儲存,無論是客戶端的SQLLITE,還是服務端的MySQL。這裡記錄最原始的訪問資料庫方式,JdbcTempl

SpringBoot 2.X課程學習 | 挖掘配置檔案的祕密

  一、兩種配置檔案獲取值的方式         因為普遍屬性

Django之路完善博客

也會 過程 object 通過 打包 但是 項目目錄 添加 實現 博客頁面設計 博客頁面概要 博客主頁面 博客文章內容頁面 博客撰寫頁面 博客主頁面 主頁面內容 文章標題列表,超鏈接 發表博客按鈕(超鏈接) 列表編寫思路 取出數據庫中所有文章

配置Docker容器加速器

systemctl 國內 mon doc 一個 com shadow text 命令 背景說明 鑒於國內網絡穩定問題,到國外站點拉取docker鏡像十分緩慢,故需要配置國內鏡像以便提高鏡像下載速度。 1.使用這個url地址https://account.daocloud.i

Jmeter Ftp服務器的連接

alt file 服務器 添加 ima nbsp 線程 mage 分享圖片 如上圖: 創建一個---線程組----點擊配置元件---添加FTP請求缺省值; IP:為你的FTP服務的IP remote file:為你FTP服務上的一個文件; Localfile

ES6之路數組的擴展

最好 布爾 return lte 效果 不一致 List 集合 define index 擴展運算符 擴展運算符(spread)是三個點(...)。它好比 rest 參數的逆運算,將一個數組轉為用逗號分隔的參數序列。 1 console.log(...[1, 2, 3])

匯編基礎指令講解

錯誤 info 其他 不能 mov指令 位或 簡單的 圖解 strong 目錄 基礎匯編代碼 LDR(load) STR(store) B MOV(move) LDR(註意跟讀內存的LDR不一樣,格式不同) add(加) sub(減) BL(branch and Link

史上最簡單的SpringCloud教程 | 分布式配置中心(Spring Cloud Config)(Finchley版本)

prope shu 由於 ext master strip div 文件配置 rap 在上一篇文章講述zuul的時候,已經提到過,使用配置服務來保存各個服務的配置文件。它就是Spring Cloud Config。 在分布式系統中,由於服務數量巨多,為了方便服務配置文件統

史上最簡單的SpringCloud教程 | 分布式配置中心(Spring Cloud Config)

tex down 代碼 多少 erl ogr 管理 變量 實時 最新Finchley版本:https://www.fangzhipeng.com/springcloud/2018/08/30/sc-f6-config/或者http://blog.csdn.net/fore