1. 程式人生 > 實用技巧 >4、Spring整合MyBatis

4、Spring整合MyBatis

學習資源:動力節點的2020最新Spring框架教程【IDEA版】-Spring框架從入門到精通

目錄


1、整合原理分析

回顧 MyBatis 的使用步驟:

  1. 定義 dao 介面,StudentDao
  2. 定義 mapper 檔案,StudentDao.xml
  3. 定義 MyBatis 主配置檔案,mybatis-config.xml
  4. 建立 dao 的代理物件,StudentDao dao = sqlSession.getMapper(StudentDao.class);
    List\<Student>students = dao.selectAll();

MyBatis 操作資料庫流程的逆向分析:

  1. 使用 dao 物件
  2. 使用 sqlSession.getMapper(xxx.class) 獲取 dao 物件
  3. 使用 SqlSessionFactory.openSession() 獲取 sqlSession 物件
  4. 使用 SqlSessionFactoryBuilder().build(mybatis配置檔案) 獲取 SqlSessionFactory
    物件
  5. 讀取 mybatis 的主配置檔案,獲取建立有關物件需要用到的資訊
<!-- 這是操作資料庫需要用到的資訊 -->
<environments default="development">

    <environment id="development">
        <transactionManager type="JDBC"/>
        <!-- mybatis 預設的連線池效能較差,現在專案開發一般使用 druid 連線池 -->
        <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
</environments>

<mappers>
    <mapper resource="com/chen/dao/StudentDao.xml"/>
</mappers>

綜上,spring 整合 mybatis,就是讓 spring 通過 IoC 建立以下物件:

  1. druid 連線池物件,druid會根據資料庫 url 字首,自動識別並載入資料庫驅動
  2. SqlSessionFactory 物件
  3. dao 物件

一併交由 spring 容器同意管理,使得整合後,spring + mybatis = spring,成為一個整體。


2、整合入門例項

2.1、建立 maven 工程


2.2、加入 maven 依賴

  • spring 依賴
  • mybatis 依賴
  • mysql 依賴
  • spring 事務依賴
  • mybatis 和 spring 整合依賴,由 MyBatis 官方提供
<dependencies>
    <!-- 測試 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <!-- ioc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!-- 事務 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.5</version>
    </dependency>
    <!-- 整合 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.4</version>
    </dependency>
    <!-- mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
    <!-- 德魯伊連線池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.21</version>
    </dependency>
</dependencies>

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory><!--所在的目錄-->
            <includes><!--包括目錄下的.properties,.xml 檔案都會掃描到-->
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>8</source>
                <target>8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

2.3、建立實體類

package com.chen.pojo;

public class Student {
    //屬性名和列名一樣
    private Integer id;
    private String name;
    private String email;
    private Integer age;
    
    public Student(Integer id, String name, String email, Integer age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }
    // set ,get , toString
}

2.4、建立 dao 介面和 mapper 檔案

package com.chen.dao;

public interface StudentDao {

    int insertStudent(Student student)
    List<Student> selectStudents();
}
<?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.chen.dao.StudentDao">
    
    <insert id="insertStudent">
    	insert into student values(#{id}, #{name}, #{email}, #{age})
    </insert>
    
    <select id="selectStudents" resultType="student">
        select id, name, email, age from student
    </select>
    
</mapper>

2.5、建立 mybatis 主配置檔案

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>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    
    <!--  給每一個pojo單獨起別名  -->
    <typeAliases>
        <package name="com.chen.pojo"/>
    </typeAliases>

    <!-- sql對映檔案的位置 -->
    <mappers>
        <mapper resource="com/chen/dao/StudentDao.xml"/>
    </mappers>

</configuration>

2.5、建立 service 介面和實現類

service 類就是呼叫 dao 來完成資料庫資料的修改,所以其內部會私有化一個 dao 的物件

package com.chen.service;

public interface StudentService {

    int addStudent(Student student);
    List<Student> queryAllStudents();
}
package com.chen.service.impl;

public class StudentServiceImpl implements StudentService {

    private StudentDao dao;

    @Override
    public int addStudent(Student student) {
		dao.insertStudent(sutdent);
        return 0;
    }

    @Override
    public List<Student> queryAllStudents() {
        List<Student> students = dao.selectStudents();
        return students;
    }
}

2.7、建立 spring 配置檔案

applicationContext.xml,建立 mybatis 的物件

  • 資料庫連線池物件(資料來源):通過配置檔案建立 druid 資料連線池物件
    • 通常你需要配置url、username、password,maxActive 這四項。
    • Druid會自動跟 url 識別驅動類名,如果連線的資料庫非常見資料庫,配置屬性 driverClassName
# url=jdbc_url
# username=jdbc_user
# password=jdbc_password

使用 druid,直接用 username 作為mysql訪問使用者名稱稱,會與windows當前使用者名稱衝突,所以將所有屬性名附上字首

jdbc.url=jdbc:mysql://localhost:3306/ssm?useSSL=true&useUnicode=true&characterEncoding=UTF-8
#使用者名稱
jdbc.username=root
#使用者密碼
jdbc.password=
#新版本的MySQL8驅動
jdbc.driver=com.mysql.cj.jdbc.Driver
<!-- 載入屬性配置檔案中的資料庫屬性的值 -->
<context:property-placeholder location="classpath:druid.properties"/>

<!-- 官方參考配置 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 
    <!--這三項必須配置,用於連線資料庫 -->
    <!-- set注入給 druid資料來源提供連線資料庫的資訊 -->
    <property name="url" value="${jdbc_url}" />
    <property name="username" value="${jdbc_user}" />
    <property name="password" value="${jdbc_password}" />
    
    <!-- 
		druid 會根據 url 字首自動識別並載入資料庫驅動
		mysql8.0的驅動是下面這個
	-->
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>

    <property name="filters" value="stat" />

    <property name="maxActive" value="20" />
    <property name="initialSize" value="1" />
    <property name="maxWait" value="60000" />
    <property name="minIdle" value="1" />

    <property name="timeBetweenEvictionRunsMillis" value="60000" />
    <property name="minEvictableIdleTimeMillis" value="300000" />

    <property name="testWhileIdle" value="true" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />

    <property name="poolPreparedStatements" value="true" />
    <property name="maxOpenPreparedStatements" value="20" />

    <property name="asyncInit" value="true" />
</bean>
  • SqlSessionFactory 物件
    在配置檔案中宣告,這裡宣告建立的是 mybatis 中提供的 SqlSessionFactoryBean 類的物件,在這個物件的內部會建立SqlSessionFactory
    SqlSessionFactory 原來通過讀取 mybatis-config.xml 中的資料來源資訊mapper資訊,才可以獲取到 dao 物件,因此這裡需要給 SqlSessionFactoryBean 物件注入這些資訊。
<!-- 建立這個物件,用於建立 SqlSessionFactory 物件-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- set 注入 -->
    <!-- 資料來源資訊,就是上面那個 druid -->
    <property name="dataSource" ref="datsource"/>
    <!-- mybatis 配置檔案的位置,用於獲取 mapper資訊 -->
    <property name="configLocation" value="classpath:mybatic-config.xml"/>
</bean>
  • dao 物件
    建立 dao 物件,使用 sqlSession.getMapper(xxxDao.class) ,而 SqlSession 要由 SqlSessionFactory 來建立。
    我們在容器中建立MapperScannerConfigurer 物件,該物件會在呼叫 getMapper() 生成 mybatis-config.xml 中註冊的所有 dao 介面的代理物件。
    dao 物件的預設名稱是 dao介面名首字母小寫。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    <!-- MapperScannerConfigurer 會掃描包中的所有介面,並執行getMapper()創建出所有的dao代理物件,新增到容器中 -->
    <property name="basePackage" value="com.chen.dao,com.chen.dao2"/>
<bean/>
  • service 物件:

因為前面已經在容器中建立了 dao 的物件,所以向 service 類的物件的 dao 屬性賦值,直接從容器中"拿"即可。

<bean id="studentService" class="com.chen.service.impl.StudentServiceImpl">
    <property name="studentDao" ref="studentDao"/>
</bean>

2.8、測試

@Test
public void test(){
    
    String resource = "applicationContext.xml";
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(resource);
    StudentService stuService = (StudentService) context.getBean("studentService");
    int rows = stuService.addStudent(new Student(1006, "馬飛", "[email protected]", 29));
    List<Student> students = stuService.queryAllStudents();
}