Spring Boot初步學習03

基於前文"Spring Boot初步學習02"(點擊前往查看),已經學習了Spring框架整合鏈接池的部分,鏈接池就是用於與數據庫鏈接的工具,那麼本文就繼續講解與數據庫交互的部分---整合Mybatis框架.java

Mybatis框架

MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,而且更名爲MyBatis 。2013年11月遷移到Github。spring

iBATIS一詞來源於「internet」和「abatis」的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAOs)sql

以上是百度中對於Mybatis框架的概述,在我理解來講,Mybatis框架是如今較爲優秀,使用較爲普遍的一個持久層框架,底層時基於JDBC去實現與數據庫的交互,而且在使用的過程當中,能夠靈活去編寫SQL語句,而且對於JDBC作了優化與封裝,框架較小型,但很適用.數據庫

現在項目中使用Mybatis框架時,一般是由Spring框架進行整合,去實現數據交互操做,接下來就來講一下在Spring Boot中如何整合Mybatis.apache

整合過程

使用過程

測試類<-->mybatis<-->JDBC<-->Driver<-->數據庫segmentfault

須要注意的是:環節之間都是耦合於接口的,這樣的設計更加靈活,更低耦合易維護修改.數組

建立項目

首先須要建立Spring Boot項目,建立過程可見Spring Boot快速入門案例.安全

固然若是已經有建立好的項目直接使用便可.springboot

添加Mybatis依賴

添加依賴時,主要參考官網 mybatis.org/spring ,在springboot菜單中找到啓動依賴,複製粘貼至pom.xml中mybatis

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

另外一種方式:右鍵項目中pom.xml-->spring-->Edit Starters-->搜索Mybatis,添加依賴.
但要注意:springboot並無爲mybatis指定版本,以這種方式添加依賴,須要本身指定版本.

簡單配置

Spring Boot特色就是零配置或簡單配置,在mybatis官網中,雖然提供了一些配置,可是也都是可選的,不配置也能夠正常運行,這裏建議配置幾點

#spring.mybatis
mybatis.configuration.default-statement-timeout=30
mybatis.configuration.map-underscore-to-camel-case=true
logging.level.com.cy=DEBUG

前兩個配置分別是:設置sql超時時間以及將數據庫中的user_name(這類下劃線命名)自動轉換爲userName(Java中的駝峯命名)
第三個配置是mybatis中的sql日誌的輸出:其中com.cy爲我項目中的根包.

到這裏關於mybatis與Springboot的整合就已經完成了,很方便簡單,後面是一些基礎業務的實現.

業務實現

基於單個ID進行刪除


建立數據層層接口

首先要建立數據層接口,代碼以下:

@Mapper
public interface GoodsDao {}

其中@Mapper註解是由Mybatis提供,描述數據層接口的的註解,用於告訴Spring框架此接口的實現由mybatis建立,並將其實現類對象存儲到spring容器,交由spring管理.

建立數據層業務方法

須要在數據層接口中,編寫實際運行的業務方法,代碼以下:

@Mapper
public interface GoodsDao {
    /**
     * 基於商品id執行刪除業務
     * @param id
     * @return 刪除的行數
     */ 
     @Delete("delete from tb_goods where id=#{id}")
     public int deleteById(Integer id);
}

這種業務方法的編寫模式,是將簡單的sql語句經過註解的形式進行定義,寫在方法上進行描述,可是複雜的sql語句仍是要寫在映射文件中(xml文件中).

建立測試類

首先須要說的是,在測試類中咱們聲明屬性時只經過@Autowired註解聲明接口(@Mapper描述的接口)不寫實現類,是因爲基於咱們已經將springboot和mybatis整合,實現類會由mybatis建立再交由spring框架進行依賴注入(DI),因此咱們只要"面向接口"便可,實際建立由框架替咱們操心.

另外,若是你想要去肯定框架建立的實現類到底是什麼呢?
能夠經過打樁(System.out.println(goodsDao.getClass().getName());)或是加斷點的方式獲得答案.

測試類代碼以下:

@SpringBootTest
public class GoodsDaoTests {
    @Autowired
    private GoodsDao goodsDao;
    @Test
    public void testDeleteById() {
        int rows = goodsDao.deleteById(10);
        System.out.println("rows="+rows);
    }
}

測試類是經過建立的實現類對象去調用@Mapper接口的業務方法,實現對數據庫的操做.

基於多個ID批量刪除


上文中也有提到複雜的sql語句仍是要寫在映射文件中(xml文件中)利用動態SQL進行映射的,這個案例就要實際操做一下.

建立xml映射文件

首先建立xml映射文件,springboot項目中有嚴格的目錄分類,須要將xml文件放在src/main/resource目錄下,咱們能夠再建立mapper/goods目錄,而後將咱們的GoodsMapper.xml映射文件放入其中.

在映射文件中,首先須要添加官網中給出的頭標籤:

<?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>標籤並在其中添加sql標籤及其語句,此案例是根據ID批量刪除,代碼以下:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">
      <delete id="deleteObjects">
          delete from tb_goods where id in 
        <foreach collection="ids" open="("
              item="id" separator="," close=")">
              #{id}        
        </foreach>
    </delete>
</mapper>

建立接口方法

在@Mapper接口中定義批量刪除多個元素的方法,代碼以下:

@Mapper
public interface GoodsDao {
/**
     * 基於多個商品id刪除
     * @param ids
     * @return 刪除的行數
     */
    public int deleteObjects(@Param("ids")Integer... ids);
}

方法中傳參爲"(@Param("ids")Integer... ids)",這是可變參數,能夠理解爲一類特殊的數組,能夠傳入0/1/2...n個數均可.通常最新版本的mybatis能夠不加"@Param("ids")"這部分.

注意:xml文件中的namespace與接口的全限定類名對應,SQL標籤的ID要與對應的接口方法名對應.

配置映射文件

如今咱們已經寫好了映射文件,以及接口方法,可若是有多個xml文件,spring框架如何知道那個是咱們要它進行管理的呢?

就須要在application.properties配置文件中添加配置以下:

mybatis.mapper-locations=classpath:/mapper/*/*.xml

"*"爲通配符,意味全部的,咱們的xml映射文件路徑是在根目錄下的mapper/goods/GoodsMapper.xml,就在配置的範圍內.

建立測試類

在src/test/java目錄下編寫測試類,代碼以下:

@SpringBootTest
public class GoodsDaoTests {
    @Autowired
    private GoodsDao goodsDao;
    @Test
    public void testDeleteObjects() {
        int rows = goodsDao.deleteObjects(6,7,8,9);
        System.out.println("rows="+rows);
    }
}

底層的執行順序是:
測試方法執行時,咱們調用接口實現類的方法,實現類內部會檢測接口方法上是否有定義sql映射;假如沒有會基於接口類全名找到對應的配置的映射文件,而後再基於方法名找到對應映射文件中的標籤,進而獲取sql映射.

加強SQL語句可靠性

以上已經完成了咱們的要求,可是在xml映射文件中寫複雜SQL語句時,咱們須要增強SQL語句的可靠性,尤爲是刪除語句,在對數據庫進行操做時,刪除語句永遠是咱們最須要當心的!

咱們須要考慮到傳入各類數據的狀況,如上文所寫的:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">
      <delete id="deleteObjects">
          delete from tb_goods where id in 
          <foreach collection="ids" open="("
              item="id" separator="," close=")">
              #{id}        
          </foreach>
    </delete>
</mapper>

當咱們若是什麼都不傳時,SQL語句就變爲:delete from tb_goods where id in ;這樣就會報錯,因此咱們能夠添加動態SQL完善!以下:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">
      <delete id="deleteObjects">
          delete from tb_goods
            <if test="ids!=null and ids.length>0">
                where id in
                <foreach collection="ids" open="("
                        item="id" separator="," close=")">
                    #{id}        
                </foreach>
            </if>
    </delete>
</mapper>

加入<if>標籤進行判斷,排除了傳入null的狀況,可是又發現ids不爲null時能夠正常執行,但若是ids爲null,沒進入判斷,SQL語句是沒有語法問題,可是執行就變爲:delete from tb_goods,刪除整個表,在工做中這就是鑄成大錯了!因此還須要進一步改進,以下再加入<where>標籤:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">
    <delete id="deleteObjects">
        delete from tb_goods
        <where>
            <if test="ids!=null and ids.length>0">
                id in <!-- (1,2,3,4) -->
                <foreach collection="ids" open="("
                        item="id" separator="," close=")">
                    #{id}        
                </foreach>
            </if>
            or 1=2
        </where>
    </delete>
  </mapper>

這樣就解決了全部狀況能夠安全使用了.

相關文章
相關標籤/搜索