1. 程式人生 > >一起來學 SpringBoot 2.x | 第七篇:整合 Mybatis

一起來學 SpringBoot 2.x | 第七篇:整合 Mybatis

點選上方“芋道原始碼”,選擇“置頂公眾號”

技術文章第一時間送達!

原始碼精品專欄

 

摘要: 原創出處 http://blog.battcn.com/2018/05/09/springboot/v2-orm-mybatis/ 「唐亞峰」歡迎轉載,保留摘要,謝謝!

  • ORM對比圖

  • 匯入依賴

  • 連線資料庫

  • 注意注意

  • 具體編碼

    • 表結構

    • 實體類

    • 持久層

    • 測試

  • 總結

  • 說點什麼

SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程

MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映,幾乎避免了所有的 JDBC 程式碼和手動設定引數以及獲取結果集,使用簡單的 XML 或註解來配置和對映原生資訊,將介面和 Java 的 POJOs(Plain Old Java Objects,普通的 Java物件)對映成資料庫中的記錄,在國內可謂是佔據了半壁江山……

ORM對比圖

以下針對Spring JDBC、Spring Data Jpa、Mybatis三款框架做了個粗略的對比。一般應用的效能瓶頸並不是在於ORM,所以這三個框架技術選型應該考慮專案的場景、團隊的技能掌握情況、開發週期(開發效率)…

框架對比Spring JDBCSpring Data JpaMybatis
效能效能最好效能最差居中
程式碼量
學習成本居中
推薦指數❤❤❤❤❤❤❤❤❤❤❤❤❤

個人觀點

拋開學習成本而言,對於業務簡單的中小型專案中使用Spring Data Jpa 開發無異於是最快速的。但是鑑於國內市場環境而言,掌握Mybatis無異於是佳的選擇,低學習成本和動態SQL解耦的特點使得更容易被人們所接受。對於業務複雜且對效能要求較高的專案來說Mybatis

往往能更好的勝任,可以自己進行SQL優化,同時更讓我喜歡的是Mybatis分頁外掛與通用Mapper(單表CURD無需自己手寫)有了這兩款外掛的支援,還有什麼理由拒絕Mybatis

匯入依賴

在 pom.xml 中新增 Mybatis 的依賴包mybatis-spring-boot-starter,該包擁有自動裝配的特點

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>

    <version>1.3.2</version>
</dependency>
<!-- MYSQL包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 預設就內嵌了Tomcat 容器,如需要更換容器也極其簡單-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 測試包,當我們使用 mvn package 的時候該包並不會被打入,因為它的生命週期只在 test 之內-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

連線資料庫

SpringDataJpa、Spring JDBC一樣,需要在application.properties中新增資料來源的配置,同時也需要新增對mybatis的配置

spring.datasource.url=jdbc:mysql://localhost:3306/chapter6?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
spring.datasource.password=root
spring.datasource.username=root
# 注意注意
mybatis.mapper-locations=classpath:com/battcn/mapper/*.xml
#mybatis.mapper-locations=classpath:mapper/*.xml        #這種方式需要自己在resources目錄下建立mapper目錄然後存放xml
mybatis.type-aliases-package=com.battcn.entity
# 駝峰命名規範 如:資料庫欄位是  order_id 那麼 實體欄位就要寫成 orderId
mybatis.configuration.map-underscore-to-camel-case=true

mybatis.configuration.map-underscore-to-camel-case是一個非常好的配置項,合理的命名規範可以讓我們省略很多不必要的麻煩,比如xx-mapper.xml中的resultMap的對映可以省略掉了

注意事項

由於 mybatis.mapper-locations=classpath:com/battcn/mapper/*.xml配置的在java package中,而Spring Boot預設只打入java package -> *.java,所以我們需要給pom.xml檔案新增如下內容

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

具體編碼

完成基本配置後,接下來進行具體的編碼操作。

表結構

建立一張 t_user 的表

CREATE TABLE `t_user` (
  `id` int(8NOT NULL AUTO_INCREMENT COMMENT '主鍵自增',
  `username` varchar(50NOT NULL COMMENT '使用者名稱',
  `password` varchar(50NOT NULL COMMENT '密碼',
  PRIMARY KEY (`id`)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者表';

實體類

package com.battcn.entity;

import java.io.Serializable;

/**
 * @author Levin
 * @since 2018/5/9 0007
 */

public class User implements Serializable {

    private static final long serialVersionUID = 8655851615465363473L;

    private Long id;
    private String username;
    private String password;
    // TODO  省略get set
}

持久層

這裡提供了兩種方式操作介面,第一種帶@Select註解的是Mybatis3.x提供的新特性,同理它還有@Update、@Delete、@Insert等等一系列註解,第二種就是傳統方式了,寫個介面對映,然後在XML中寫上我們的SQL語句…

UserMapper

package com.battcn.mapper;

import com.battcn.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * t_user 操作:演示兩種方式
 * <p>第一種是基於mybatis3.x版本後提供的註解方式<p/>
 * <p>第二種是早期寫法,將SQL寫在 XML 中<p/>
 *
 * @author Levin
 * @since 2018/5/7 0007
 */

@Mapper
public interface UserMapper {

    /**
     * 根據使用者名稱查詢使用者結果集
     *
     * @param username 使用者名稱
     * @return 查詢結果
     */

    @Select("SELECT * FROM t_user WHERE username = #{username}")
    List<User> findByUsername(@Param("username") String username);


    /**
     * 儲存使用者資訊
     *
     * @param user 使用者資訊
     * @return 成功 1 失敗 0
     */

    int insert(User user);
}

UserMapper 對映檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.battcn.mapper.UserMapper">

  <insert id="insert" parameterType="com.battcn.entity.User">
    INSERT INTO `t_user`(`username`,`password`) VALUES (#{username},#{password})
  </insert>

</mapper>

測試

完成資料訪問層介面後,最後編寫一個junit測試類來檢驗程式碼的正確性。

package com.battcn;

import com.battcn.entity.User;
import com.battcn.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * @author Levin
 */

@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter6ApplicationTests {

    private static final Logger log = LoggerFactory.getLogger(Chapter6ApplicationTests.class);

    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1() throws Exception {
        final int row1 = userMapper.insert(new User("u1""p1"));
        log.info("[新增結果] - [{}]", row1);
        final int row2 = userMapper.insert(new User("u2""p2"));
        log.info("[新增結果] - [{}]", row2);
        final int row3 = userMapper.insert(new User("u1""p3"));
        log.info("[新增結果] - [{}]", row3);
        final List<User> u1 = userMapper.findByUsername("u1");
        log.info("[根據使用者名稱查詢] - [{}]", u1);
    }
}

總結

更多Mybatis