1. 程式人生 > >MyBatis的兩種開發模式

MyBatis的兩種開發模式

之前簡單介紹了 MyBatis 持久層框架對於資料的持久化操作。這一篇是對上篇的補充,介紹幾個相關的知識點。

MyBatis 架構

在這裡插入圖片描述

  1. mybatis配置
    SqlMapConfig.xml,此檔案作為mybatis的全域性配置檔案,配置了mybatis的執行環境等資訊。
    mapper.xml檔案即sql對映檔案,檔案中配置了操作資料庫的sql語句。此檔案需要在SqlMapConfig.xml中載入。
  2. 通過mybatis環境等配置資訊構造SqlSessionFactory即會話工廠
  3. 由會話工廠建立sqlSession即會話,操作資料庫需要通過sqlSession進行。
  4. mybatis底層自定義了Executor執行器介面操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是快取執行器。
  5. Mapped Statement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊及sql對映資訊等。mapper.xml檔案中一個sql對應一個Mapped Statement物件,sql的id即是Mapped statement的id。
  6. Mapped Statement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql前將輸入的java物件對映至sql中,輸入引數對映就是jdbc程式設計中對preparedStatement設定引數。
  7. Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql後將輸出結果對映至java物件中,輸出結果對映過程相當於jdbc程式設計中對結果的解析處理過程。

原始的Dao開發

原始Dao開發方法需要程式設計師編寫Dao介面和Dao實現類。
Dao

public interface UserDao {
    public User findUserByIdTest(Integer id);
}

DaoImpl

public class UserDaoImpl implements UserDao {
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    public User findUserByIdTest(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession.selectOne("userMapper.findUserById",id );
    }
}

編寫對映檔案User.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="userMapper">
 
    <select id="findUserById" parameterType="int" resultType="main.java.bean.User">
            select * from user where id = #{id}/*#佔位符裡面隨便用*/
    </select>

測試類----充當Service層的角色

public class UserDaoImplTest {

    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void before() {
        String resource = "main/resources/mybatis-config.xml";
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }
    @Test
    public void testDao(){
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        User user = userDao.findUserByIdTest(1);
        System.out.println(user);
        
    }
}

配置檔案 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>
    <properties resource="main/resources/jdbc.properties"/>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.DriverClassName}" />
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- Mapper的位置  Mapper.xml 寫Sql語句的檔案的位置 -->
    <mappers>
        <mapper resource="main/resources/mapper/User.xml"/>
    </mappers>
</configuration>

原始Dao開發中存在以下問題:

  • Dao方法體存在重複程式碼:通過SqlSessionFactory建立SqlSession,呼叫SqlSession的資料庫操作方法
  • 呼叫sqlSession的資料庫操作方法需要指定statement的id,這裡存在硬編碼,不得於開發維護。

Mapper動態代理方式

Mapper介面開發方法只需要編寫Mapper介面,由Mybatis框架根據介面定義建立介面的動態代理物件,代理物件的方法體同上邊Dao介面實現類方法。

Mapper介面開發需要遵循以下規範:
1、Mapper.xml檔案中的 namespace 與 mapper 介面的類路徑相同。
2、Mapper介面方法名和 Mapper.xml 中定義的每個 statement 的id相同
3、Mapper介面方法的輸入引數型別和 mapper.xml 中定義的每個sql 的 parameterType 的型別相同
4、Mapper介面方法的輸出引數型別和 mapper.xml 中定義的每個sql的 resultType 的型別相同

謹記以上4點就不會有錯誤

書寫介面

public interface UserMapper {
    public User findUserById(int id);
}

對映檔案 UserMapper.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="main.java.maping.UserMapper">
    <select id="findUserById" parameterType="int" resultType="main.java.bean.User">
        select * from user where id = #{id}
    </select>

測試檔案

public class MapperTest {

    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void before() {
        String resource = "main/resources/mybatis-config.xml";
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }
    @Test
    public void test(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findUserById(1);
        System.out.println(user);  
    }

mybatis官方推薦使用mapper代理方法開發mapper介面

mappers(對映器)

Mapper配置的幾種方法:

<mapper resource=" " />

使用相對於類路徑的資源(現在的使用方式)
如: < mapper resource=“main/resources/mapper/User.xml” />

<mapper class=" " />

使用mapper介面類路徑
如: < mapper class=“main.java.maping.UserMapper”/>

注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中。

<package name=""/>

註冊指定包下的所有mapper介面
如:< package name=“main.java.maping”/>
注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中。