SSM框架開發web項目系列(五) Spring集成MyBatis

  前言

  在前面的MyBatis部份內容中,咱們已經能夠獨立的基於MyBatis構建一個數據庫訪問層應用,可是在實際的項目開發中,咱們的程序不會這麼簡單,層次也更加複雜,除了這裏說到的持久層,還有業務邏輯層、視圖層等等,隨着代碼量和需求複雜度逐漸增加,對象的建立、管理以及層與層之間的耦合度等等問題隨之而來。Spring是目前比較流行的框架,它解決了諸多例如層次之間鬆耦合、幫助管理對象等問題。若是是有準備學習MyBatis的人,應該或多或少都學習過或者瞭解過Spring了,本篇要經過Spring集成MyBatis,首先要對Spring核心的概念IOC和AOP有個基本認識。html

  首先回顧下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反射,是控制反轉的一種具體實現方式。java

  AOP(Aspect Oriented Programming)面向切面編程,使用到Java中代理模式,是對面向對象編程的一種補充,而不是競爭或衝突,例如咱們看待一段web項目訪問過程,首先訪問模塊A,隨之系統會記錄訪問日誌,而後訪問模塊B,系統也會隨之記錄訪問日誌,以面向對象的思惟來看,從前到後,這是兩段完整的過程,每段過程當中又包括咱們的訪問和系統的日誌記錄兩種操做。可是換到這裏的切面思惟,咱們每訪問一個模塊,系統都會隨之有記錄訪問日誌,把這個記錄日誌的動做以切面抽取並封裝起來,能夠減小系統的重複代碼,下降模塊之間的耦合度,提升系統的可操做性和可維護性。常見應用有例如事務管理、日誌管理、安全控制等等。mysql

  Spring集成MyBatis

  既然Spring容器能幫助咱們建立和管理對象,那麼在這裏,不一樣於前面的獨立MyBatis程序,咱們能夠把那些獲取對象的過程按照Spring的方式作些修改。首先來回顧下前面咱們作MyBatis單獨測試的方法代碼,示例以下:web

@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集成方式,咱們能夠免除這些建立對象的代碼。spring

  數據庫環境MySql,工具Navicat for MySQL,建立一張Person表以下所示,並填入幾條測試數據sql

  新建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>
    <!-- 這裏的環境配置中事務管理器和數據源分別在Spring配置文件中去配置,因此本來這裏的部分就能夠不寫了 -->
    <!-- <environments default="envir">
        <environment id="envir">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://192.168.0.100:3306/ssm?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="abc123"/>
            </dataSource>
        </environment>
    </environments> -->
    <!-- 經過在Spring集成MyBatis配置文件中SqlSessionFactoryBean中的mapperLocations屬性配置實現sql映射xml文件的掃描,因此下面的mappers在這裏也能夠不寫了-->
    <!-- <mappers>
        <mapper resource="com/mmm/mapper/personMapper.xml"/>
    </mappers> -->
</configuration>

  application-root.xml

<?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:p="http://www.springframework.org/schema/p"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd
                        http://www.springframework.org/schema/aop    
                        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                        http://www.springframework.org/schema/tx    
                        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">  
                        
    <!-- 引入jdbc參數配置 --> 
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- Spring會自動掃描base-package指定包下面添加了@Component @Service等註解的類並將其實例化 -->
    <context:component-scan base-package="com.mmm" />
    
    <!-- 配置數據源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    
    <!-- spring和MyBatis整合 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自動掃描mapping.xml文件 -->  
        <property name="mapperLocations" value="classpath:com/mmm/mapper/*.xml"></property>  
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    </bean>  
  
    <!-- DAO接口所在包名,Spring會自動查找其下的類 -->  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.mmm.mapper" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
    </bean>
    
    <!-- 配置事務管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>
     
     <!-- <bean id="personMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
         <property name="mapperInterface" value="com.mmm.mapper.PersonMapper" />
         <property name="sqlSessionFactory" ref="sqlSessionFactory" />
     </bean> -->
</beans>

  jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/ssm
jdbc.username=root
jdbc.password=123456

  PersonMapper.java

package com.mmm.mapper;

import java.util.List;

import com.mmm.pojo.Person;

public interface PersonMapper {
    
    //查找全部Person對象
    List<Person> selectAll();
    
}

  personMapper.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 namespace="com.mmm.mapper.PersonMapper">
    <resultMap type="psn" id="personResultMap">
        <id column="ID" property="id" />
        <result column="NAME" property="name" />
        <result column="GENDER" property="gender" />
        <result column="AGE" property="age" />
        <result column="IF_IT" property="ifIT" />
    </resultMap>
    
    <select id="selectAll" resultMap="personResultMap">
        select * from person
    </select>
    
</mapper>

   最後咱們的測試方法就不用像以前那樣建立一連串的對象,能夠經過以下方式:安全

package com.mmm.test;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mmm.mapper.PersonMapper;
import com.mmm.pojo.Person;

public class TestSpringMbs {
    
    @SuppressWarnings("resource")
    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("application-root.xml");
        PersonMapper personMapper = (PersonMapper) context.getBean("personMapper");
        List<Person> list = personMapper.selectAll();
        for(Person p:list) {
            System.out.println(p);
        }

    }
    
}

  最後運行一下測試方法,能夠看到以下結果,獲取到數據庫Person表所有記錄,即成功運行session

  小結

  這裏經過Spring集成MyBatis的一個很基礎的示例,咱們能對Spring集成ORM框架的大體過程有個基本認識,不只僅是MyBatis,相似Hibernate、JPA那塊在Spring集成過程當中核心步驟大體也包涵了本文中的部分。框架會變,可是有些系統的硬性需求不會變,就比如這裏的持久層,你要訪問數據庫,不管你用MyBatis,仍是Hibernate,甚至是原生的JDBC,數據庫的訪問帳號密碼,只不過一步步封裝到了框架中的數據源;咱們的更新提交回退等等,在框架中演化成事務管理。理清這些硬性需求並跟隨者去學習,每每能更順暢的記住和理解。而不是說你學了半天MyBatis,以爲數據庫操做什麼都沒問題了,而後忽然換個Hibernate,感受一片迷茫,認清這些核心的概念,每每能幫助咱們快速的觸類旁通學習新知識。

相關文章
相關標籤/搜索