MyBatis的兩種開發模式
之前簡單介紹了 MyBatis 持久層框架對於資料的持久化操作。這一篇是對上篇的補充,介紹幾個相關的知識點。
MyBatis 架構
- mybatis配置
SqlMapConfig.xml,此檔案作為mybatis的全域性配置檔案,配置了mybatis的執行環境等資訊。
mapper.xml檔案即sql對映檔案,檔案中配置了操作資料庫的sql語句。此檔案需要在SqlMapConfig.xml中載入。 - 通過mybatis環境等配置資訊構造SqlSessionFactory即會話工廠
- 由會話工廠建立sqlSession即會話,操作資料庫需要通過sqlSession進行。
- mybatis底層自定義了Executor執行器介面操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是快取執行器。
- Mapped Statement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊及sql對映資訊等。mapper.xml檔案中一個sql對應一個Mapped Statement物件,sql的id即是Mapped statement的id。
- Mapped Statement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql前將輸入的java物件對映至sql中,輸入引數對映就是jdbc程式設計中對preparedStatement設定引數。
- 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對映檔名稱相同,且放在同一個目錄中。