前言 在前面的MyBatis部分內容中,我們已經可以獨立的基於MyBatis構建一個資料庫訪問層應用,但是在實際的項目開發中,我們的程式不會這麼簡單,層次也更加複雜,除了這裡說到的持久層,還有業務邏輯層、視圖層等等,隨著代碼量和需求複雜度逐漸增長,對象的創建、管理以及層與層之間的耦合度等等問題隨之而 ...
前言
在前面的MyBatis部分內容中,我們已經可以獨立的基於MyBatis構建一個資料庫訪問層應用,但是在實際的項目開發中,我們的程式不會這麼簡單,層次也更加複雜,除了這裡說到的持久層,還有業務邏輯層、視圖層等等,隨著代碼量和需求複雜度逐漸增長,對象的創建、管理以及層與層之間的耦合度等等問題隨之而來。Spring是目前比較流行的框架,它解決了諸多例如層次之間松耦合、幫助管理對象等問題。如果是有準備學習MyBatis的人,應該或多或少都學習過或者瞭解過Spring了,本篇要通過Spring集成MyBatis,首先要對Spring核心的概念IOC和AOP有個基本認識。
首先回顧下IOC,控制反轉(Inversion of Control,英文縮寫為IOC),前面講到的層與層之間的耦合問題在Spring中,即通過控制反轉解決的,那麼控制具體是控制什麼,反轉是怎樣反轉?我們在學習初期,創建對象用到最多的往往就是new語句,如果需要一個Person類的實例對象,我們就可以通過 Person p = new Person(); 獲取我們想要的,進一步引申,在我們的開發中,如果業務邏輯Service層需要一個持久層Dao的實例,那麼我們也可以在這個Service中直接new一個Dao實例,這樣就相當於是我們自己在控制這個對象的創建和管理等等,但實際上項目中引入Spring後,我們無需自己去創建對象,而是交由Spring創建和管理,控制反轉具體來看,應該是控制對象的創建、管理等等,這些職責的反轉,原來是我們的職責,現在反轉到了Spring容器那邊管理。另外說道IOC,往往還伴隨著一個DI(Dependency Injection)依賴註入的概念,前面為什麼要在一個層的類中創建(獲取)另一個類對象,是因為類與類之間的依賴,如果由我們主動在類中創建對象,會使得項目高耦合,靈活度大大降低。而通過依賴註入可以讓我們輕鬆獲取由容器創建和管理的對象,而不需要在程式中硬編碼創建對象,從而達到解耦程式。依賴註入,基於Java反射,是控制反轉的一種具體實現方式。
AOP(Aspect Oriented Programming)面向切麵編程,使用到Java中代理模式,是對面向對象編程的一種補充,而不是競爭或衝突,例如我們看待一段web項目訪問過程,首先訪問模塊A,隨之系統會記錄訪問日誌,然後訪問模塊B,系統也會隨之記錄訪問日誌,以面向對象的思維來看,從前到後,這是兩段完整的過程,每段過程中又包括我們的訪問和系統的日誌記錄兩種操作。但是換到這裡的切麵思維,我們每訪問一個模塊,系統都會隨之有記錄訪問日誌,把這個記錄日誌的動作以切麵抽取並封裝起來,可以減少系統的重覆代碼,降低模塊之間的耦合度,提高系統的可操作性和可維護性。常見應用有例如事務管理、日誌管理、安全控制等等。
Spring集成MyBatis
既然Spring容器能幫助我們創建和管理對象,那麼在這裡,不同於前面的獨立MyBatis程式,我們可以把那些獲取對象的過程按照Spring的方式做些修改。首先來回顧下前面我們做MyBatis單獨測試的方法代碼,示例如下:
@Test public void testCore() throws IOException { //直接實例SqlSessionFactoryBuilder對象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //MyBatis配置文件路徑 String path = "mybatis-config.xml"; //通過路徑獲取輸入流 Reader reader = Resources.getResourceAsReader(path); //通過reader構建sessionFactory SqlSessionFactory sessionFactory = builder.build(reader); //獲取SqlSession對象 SqlSession sqlSession = sessionFactory.openSession(); //獲取Mapper實例 DeptMapper mapper = sqlSession.getMapper(DeptMapper.class); Dept dept = mapper.selectById(10001); Company company = dept.getCompany(); //所屬公司 List<Emp> empList = dept.getEmpList(); //員工集合 System.out.println(dept); }
這裡的SqlSessionFactory、SqlSession、Mapper實例等對象都是由我們手動去自己創建,下麵正文開始通過Spring集成方式,我們可以免除這些創建對象的代碼。
資料庫環境MySql,工具Navicat for MySQL,創建一張Person表如下所示,並填入幾條測試數據
新建Maven項目,可以是普通Jar項目,簡單選quickstart那個,工程結構如下所示:
POM依賴可參考SSM框架開發web項目系列(一) 環境搭建篇
實體類Person
package com.mmm.pojo; public class Person { private Integer id; //主鍵 private String name; //姓名 private String gender; //性別 private Integer age; //年齡 private String ifIT; //是否從事IT行業 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getIfIT() { return ifIT; } public void setIfIT(String ifIT) { this.ifIT = ifIT; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", gender=" + gender + ", age=" + age + ", ifIT=" + ifIT + "]"; } }
mybatis-config.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> <!-- 這裡可以定義類的別名,在mapper.xml文件中應用會方便很多 --> <typeAliases> <typeAlias alias="psn" type="com.mmm.pojo.Person" /> </typeAliases