MyBatis 與 Spring 整合

来源:https://www.cnblogs.com/wmyskxz/archive/2018/04/19/8879513.html
-Advertisement-
Play Games

MyBatis—Spring 項目 目前大部分的 Java 互聯網項目,都是用 Spring MVC + Spring + MyBatis 搭建平臺的。 使用 "Spring IoC" 可以有效的管理各類的 Java 資源,達到即插即拔的功能;通過 "Spring AOP" 框架,資料庫事務可以委托 ...


MyBatis—Spring 項目

目前大部分的 Java 互聯網項目,都是用 Spring MVC + Spring + MyBatis 搭建平臺的。

使用 Spring IoC 可以有效的管理各類的 Java 資源,達到即插即拔的功能;通過 Spring AOP 框架,資料庫事務可以委托給 Spring 管理,消除很大一部分的事務代碼,配合 MyBatis 的高靈活、可配置、可優化 SQL 等特性,完全可以構建高性能的大型網站。

毫無疑問,MyBatis 和 Spring 兩大框架已經成了 Java 互聯網技術主流框架組合,它們經受住了大數據量和大批量請求的考驗,在互聯網系統中得到了廣泛的應用。使用 MyBatis-Spring 使得業務層和模型層得到了更好的分離,與此同時,在 Spring 環境中使用 MyBatis 也更加簡單,節省了不少代碼,甚至可以不用 SqlSessionFactory、 SqlSession 等對象,因為 MyBatis-Spring 為我們封裝了它們。

摘自:《Java EE 互聯網輕量級框架整合開發》

第一步:創建測試工程

第一步,首先在 IDEA 中新建一個名為【MybatisAndSpring】的 WebProject 工程:

然後在【src】中創建 4 個空包:

  • cn.wmyskxz.dao(放置 DAO 數據交互層處理類)
  • cn.wmyskxz.mapper(放置 Mapper 代理介面)
  • cn.wmyskxz.pojo(放置 Java 實體類)
  • cn.wmyskxz.test(放置測試類)

接著新建源文件夾【config】,用於放置各種資源配置文件:

  • 在【config / mybatis】下創建一個空的名為 “SqlMapConfig.xml” 的 MyBatis 全局配置文件
  • 在【config / spring】下創建一個空的名為 “applicationContext.xml” 的 Spring 資源配置文件
  • 在【config / sqlmap】下創建一個空的名為 “UserMapper.xml” 的 Mapper 映射文件。
  • 在【config】下創建兩個 properties 屬性文件,分別為 “db.properties” 和 “log4j.properties”,用於資料庫連接和日誌系統參數設置。

再在【web】文件夾下新建一個【WEB-INF】預設安全文件夾,併在其下創建一個【classes】和【lib】,並將項目的輸出位置,改在【classes】下:

工程的完整初始結構如下:

第二步:引入依賴 jar 包

第二步,就是要準備項目的依賴 jar 包:

在【WEB-INF】文件夾下的【lib】文件夾中放置上面列舉的 jar 包,然後添加依賴。

第三步:編寫 Spring 配置文件

第三步,編寫 Spring 的配置文件:

  • 載入資料庫連接文件 “db.properties” 中的數據,建立數據源
  • 配置 sqlSessionFactory 會話工廠對象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 載入配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 配置數據源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 載入 MyBatis 的配置文件 -->
        <property name="configLocation" value="mybatis/SqlMapConfig.xml"/>
        <!-- 數據源 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>
  • 頭部的信息就是聲明 xml 文檔配置標簽的規則的限制與規範。
  • “context:property-placeholder” 配置是用於讀取工程中的靜態屬性文件,然後在其他配置中使用時,就可以採用 “${屬性名}” 的方式獲取該屬性文件中的配置參數值。
  • 配置了一個名為 “dataSrouce” 的 bean 的信息,實際上是連接資料庫的數據源。
  • 設置 sqlSessionFactory 的 bean 實現類為 MyBatis 與 Spring 整合 jar 包中的 SqlSessionFactoryBean 類,在其中只需要註入兩個參數:一個是 MyBatis 的全局配置文件,一個是上面配置的數據源 bean

第四步:編寫 MyBatis 配置文件

第四步,在【mybatis】包下編寫 MyBatis 的全局配置文件 SqlMapConfig.xml :

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- settings -->
    <settings>
        <!-- 打開延遲載入的開關 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 將積極載入改為消極載入(即按需載入) -->
        <setting name="aggressiveLazyLoading" value="false"/>
        <!-- 打開全局緩存開關(二級緩存)預設值就是 true -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <!-- 別名定義 -->
    <typeAliases>
        <package name="cn.wmyskxz.pojo"/>
    </typeAliases>

    <!-- 載入映射文件 -->
    <mappers>
        <!-- 通過 resource 方法一次載入一個映射文件 -->
        <mapper resource="sqlmap/UserMapper.xml"/>
        <!-- 批量載入mapper -->
        <package name="cn.wmyskxz.mapper"/>
    </mappers>
</configuration>

在該配置文件中:

  • 通過 settings 配置了一些延遲載入和緩存的開關信息
  • typeAliases 中設置了一個 package 的別名掃描路徑,在該路徑下的 Java 實體類都可以擁有一個別名(即首字母小寫的類名)
  • 在 mappers 配置中,使用 mapper 標簽配置了即將要載入的 Mapper 映射文件的資源路徑,當然也可以使用 package 標簽,配置 mapper 代理介面所在的包名,以批量載入 mapper 代理對象。
  • 註意: 有了 Spring 托管數據源,在 MyBatis 配置文件中僅僅需要關註性能化配置。

第五步:編寫 Mapper 以及其他配置文件

第五步,編寫 Mapper 映射文件,這裡依然定義 Mapper 映射文件的名字為 “UserMapper.xml” (與 SqlMapConfig.xml 中配置一致),為了測試效果,只配置了一個查詢類 SQL 映射:

<?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="test">
    <select id="findUserById" parameterType="_int" resultType="user">
    SELECT * FROM USER WHERE id = #{id}
</select>
</mapper>

在該配置中,輸出參數的映射為 “user” ,這是因為之前在 SqlMapConfig.xml 中配置了 “cn.wmyskxz.pojo” 包下的實體類使用別名(即首字母小寫的類名),所以這裡只需在 “cn.wmyskxz.pojo” 包下,創建 “finduserById” 對應的 Java 實體類 User:

package cn.wmyskxz.pojo;

import java.io.Serializable;

public class User implements Serializable {
    private int id;
    private String username;

    /* getter and setter */
}
  • 實現 Serializable 介面是為之後使用 Mapper 動態代理做準備,這裡沒有使用動態代理。

在資料庫資源 “db.properties” 中配置了資料庫的連接信息,以 “key=value” 的形式配置,String 正是使用 “${}” 獲取其中 key 對應的 value 配置的:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

另外日誌配置和之前的配置一樣,我就直接黏貼了:

# Global logging configuration
# 在開發環境下日誌級別要設置成 DEBUG ,生產環境設為 INFO 或 ERROR
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

第六步:編寫 DAO 層

第六步,進行資料庫交互(Data Access Object)層的編寫。

由於該項目只對 User 用戶查詢,所以 DAO 層就只有一個類,在 “cn.wmyskxz” 包下創建 DAO 層的 interface 介面,其中定義了 findUserById 方法,參數為用戶的 id 值(int 類型):

package cn.wmyskxz.dao;

import cn.wmyskxz.pojo.User;

public interface UserDAO {

    // 根據 id 查詢用戶信息
    public User findUserById(int id) throws Exception;
}

然後在同一個包下創建 UserDAO 介面的實現類 UserDAOImpl:

package cn.wmyskxz.dao;

import cn.wmyskxz.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

public class UserDAOImpl extends SqlSessionDaoSupport implements UserDAO {

    @Override
    public User findUserById(int id) throws Exception {
        // 繼承 SqlSessionDaoSupport 類,通過 this.getSqlSession() 得到 sqlSession
        SqlSession sqlSession = this.getSqlSession();
        User user = sqlSession.selectOne("test.findUserById", id);
        return user;
    }
}
  • 有幾點解釋:
  • UserDAOImpl 不僅實現了 UserDAO 介面,而且繼承了 SqlSessionDaoSupport 類。
  • SqlSessionDaoSupport 類是 MyBatis 與 Spring 整合的 jar 包中提供的,在該類中已經包含了 sqlSessionFactory 對象作為其成員變數,而且對外提供 get 和 set 方法,方便 Spring 從外部註入 sqlSessionFactory 對象。
  • UserDAOImpl 類要成功獲取 sqlSessionFactory 對象,還需要在 Spring 配置文件 applicationContext.xml 中添加 userDAO 的 bean 配置,將其中定義的 sqlSessionFactory 對象當做參數註入進去,這樣 UserDAOImpl 繼承 SqlSessionDaoSupport 類才會起到作用:
<!-- 原始 DAO 介面 -->
<bean id="userDAO" class="cn.wmyskxz.dao.UserDAOImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
  • 註意: DAO 實現類繼承了 SqlSessionDaoSupport 父類後,就無須自己定義獲取 SqlSession 會話實例類方法了,該父類會預設載入數據源信息並提供獲取 SqlSession 類的方法。

第七步:編寫 Service 測試類

在 “cn.wmyskxz.test” 包下創建【UserServiceTest】測試類:

package cn.wmyskxz.test;

import cn.wmyskxz.dao.UserDAO;
import cn.wmyskxz.pojo.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    private ApplicationContext applicationContext;

    // 在執行測試方法之前首先獲取 Spring 配置文件對象
    // 註解@Before在執行本類所有測試方法之前先調用這個方法
    @Before
    public void setup() throws Exception {
        applicationContext = new
                ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
    }

    @Test
    public void testFindUserById() throws Exception {
        // 通過配置資源對象獲取 userDAO 對象
        UserDAO userDAO = (UserDAO) applicationContext.getBean("userDAO");
        // 調用 UserDAO 的方法
        User user = userDAO.findUserById(1);
        // 輸出用戶信息
        System.out.println(user.getId() + ":" + user.getUsername());
    }
}

運行測試方法,輸出結果如下:


動態代理 + 註解實現

上面的實常式序並沒有使用 Mapper 動態代理和註解來完成,下麵我們就來試試如何用動態代理和註解:

第一步:編寫 UserQueryMapper

在【mapper】下新建一個【UserQueryMapper】代理介面,並使用註解:

package cn.wmyskxz.mapper;

import cn.wmyskxz.pojo.User;
import org.apache.ibatis.annotations.Select;

public interface UserQueryMapper {

    @Select("SELECT * FROM USER WHERE id = #{id}")
    public User findUserById(int id) throws Exception;
}
  • 註意: 在預設情況下,該 bean 的名字為 userQueryMapper(即首字母小寫)

現在有了代理類,我們需要通知 Spring 在這裡來掃描到該類,Mapper 掃描配置對象需要用專門的掃描器:

<!-- Mapper 掃描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 掃描 cn.wmyskxz.mapper 包下的組件 -->
    <property name="basePackage" value="cn.wmyskxz.mapper"/>
</bean>

第二步:編寫測試類

這一次我們獲取的不再是 userDAO 對象,而是定義的 Mapper 代理對象 userQueryMapper:

package cn.wmyskxz.test;

import cn.wmyskxz.mapper.UserQueryMapper;
import cn.wmyskxz.pojo.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    private ApplicationContext applicationContext;

    // 在執行測試方法之前首先獲取 Spring 配置文件對象
    // 註解@Before在執行本類所有測試方法之前先調用這個方法
    @Before
    public void setup() throws Exception {
        applicationContext = new
                ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
    }

    @Test
    public void testFindUserById() throws Exception {
        // 通過配置資源對象獲取 userDAO 對象
        UserQueryMapper userQueryMapper = (UserQueryMapper) applicationContext.getBean("userQueryMapper");
        // 調用 UserDAO 的方法
        User user = userQueryMapper.findUserById(1);
        // 輸出用戶信息
        System.out.println(user.getId() + ":" + user.getUsername());
    }
}

運行測試方法,得到正確結果:

可以看到,查詢結果和之前非 Mapper 代理的查詢結果一樣。

  • 原理: 在 applicationContext.xml 配置文件中配置的 mapper 批量掃描器類,會從 mapper 包中掃描出 Mapper 介面,自動創建代理對象並且在 Spring 容器中註入。自動掃描出來的 Mapper 的 bean 的 id 為 mapper 類名(首字母小寫),所以這裡獲取的就是名為 “userQueryMapper” 的 mapper 代理對象。

參考資料:

  • 《Java EE 互聯網輕量級框架整合開發》
  • 《Spring MVC + MyBatis開發從入門到項目實戰》
  • 全能的百度和萬能的大腦

歡迎轉載,轉載請註明出處!
@我沒有三顆心臟
CSDN博客:http://blog.csdn.net/qq939419061
簡書:http://www.jianshu.com/u/a40d61a49221


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 71,談談你對Struts的理解。 1. struts是一個按MVC模式設計的Web層框架,其實它就是一個Servlet,這個Servlet名為ActionServlet,或是ActionServlet的子類。我們可以在web.xml文件中將符合某種特征的所有請求交給這個Servlet處理,這個Se ...
  • 最近區塊鏈技術突然爆火,身邊做技術的朋友茶餘飯後不談點區塊鏈什麼的都被認為是跟不上時代了,為啥會這樣了? 這其實跟比特幣價格去年的突飛猛進是分不開的,比特幣價格從去年初不到一千美金到今年初最高接近兩萬美金,賺錢效應已經足夠博取大家眼球了,吃瓜群眾對比特幣價格一年上漲20倍早已目瞪狗呆,個個備足錢袋, ...
  • 1.安裝Java環境 安裝了Java環境直接下一步,沒有安裝的話:http://www.cnblogs.com/i-tao/p/8587279.html 2.安裝Eclipse開發工具 安裝了Eclipse直接下一步,沒有安裝直接去官網下載Eclipse:https://www.eclipse.or ...
  • 原文地址:http://hadihariri.com/2014/06/24/no-tabs-in-intellij-idea/ I often come across people complaining about some odd behaviour when it comes to edito ...
  • @ResponseBody 在返回的數據不是html標簽的頁面,而是其他某種格式的數據時(如json、xml等)使用; 不在springMvc中配置json的處理的話,我們通常會在Controller層中獲取到數據之後進行類型轉化,將數據轉成json字元串,比如調用fastjson進行轉化,如下 這 ...
  • 手把手教你寫網路爬蟲(4) 作者:拓海 摘要:從零開始寫爬蟲,初學者的速成指南! 封面: 上期我們理性的分析了為什麼要學習Scrapy,理由只有一個,那就是免費,一分錢都不用花! 咦?怎麼有人扔西紅柿?好吧,我承認電視看多了。不過今天是沒得看了,為了趕稿,又是一個不眠夜。。。言歸正傳,我們將在這一期 ...
  • 在進行網頁數據抓取時我們要先安裝一個模塊 requests 通過終端安裝如下圖 因為我之前安裝過了,所以不會顯示安裝進度條,安裝也非常簡單,如果你配置好環境變數的話,你只需要執行以下命令 如果提示要升級,就按下麵升級pip 安裝完模塊後我們正式開始進行數據爬取 先說一下requests的用法,導入這 ...
  • 用for迴圈對無序數組進行排序輸出。 public class BubbleSort{ public static void main (String [] args){ int a[] = {21,9,45,17,33,72,50,12,41,39}; for (int i=a.length; - ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...