1. 程式人生 > >MyBatis使用Mapper動態代理開發Dao層

MyBatis使用Mapper動態代理開發Dao層

開發規範

Mapper介面開發方法只需要程式設計師編寫Mapper介面(相當於Dao介面),由Mybatis框架根據介面定義建立介面的動態代理物件,代理物件的方法體同原始Dao介面實現類方法。
Mapper介面開發需要遵循以下規範:

  • Mapper.xml檔案中的namespace與mapper介面的類路徑相同,即namespace必須是介面的全限定名。

  • Mapper介面方法名和Mapper.xml中定義的每個statement的id相同。

  • Mapper介面方法的輸入引數型別和mapper.xml中定義的每個sql的parameterType的型別相同。

  • Mapper介面方法的輸出引數型別和mapper.xml中定義的每個sql的resultType的型別相同。


使用mapper動態代理開發Dao案例

1)新建專案mybatis_demo02,匯入所需jar包

在這裡插入圖片描述

2)在classpath下建立log4j.properties日誌配置檔案、db.properties資料庫配置檔案以及MyBatis的核心配置檔案SqlMapConfig.xml

新建原始碼包config
在這裡插入圖片描述
log4j.properties內容:

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

db.properties內容:

#mysql的驅動
driver=com.mysql.jdbc.Driver
#連線地址
url=jdbc:mysql://localhost:3306/spring_jdbc02?useUnicode=true&characterEncoding=UTF-8
#連線使用者名稱
user=root
#連線密碼
password=123456
#初始化數量
initsize=5
#最大數量
maxsize=15

SqlMapConfig.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> </configuration>

3)在SqlMapConfig.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>	

	<!-- db.properties配置檔案 -->
	<properties resource="db.properties"/>
	
    <!-- 和spring整合後environments配置將廢除 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事務管理 -->
            <transactionManager type="JDBC" />
            <!-- 資料庫連線池 -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${user}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>
    
</configuration>

4)新建包com.oak.po,在其中新建User

在這裡插入圖片描述

public class User {
	private Integer id;
	private String name;
	//方法略...	
}

5)新建一個包com.oak.mapper,新建UserMapper介面,定義方法

在這裡插入圖片描述

public interface UserMapper {
	/**
	 * 根據id查詢使用者
	 * @param id
	 * @return
	 */
	User findById(int id);
	/**
	 * 根據姓名進行模糊查詢
	 * @param name
	 * @return 所有滿足條件的User資訊
	 */
	List<User> findByName(String name);
	/**
	 * 新增一條User資訊
	 * @param user
	 */
	void  add(User user);
}

6)UserMapper.xml對映檔案

在config下新建一個普通包sqlmap,在其中新建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="com.oak.mapper.UserMapper">

	<!-- 根據id獲取使用者資訊 -->
	<select id="findById" parameterType="int" resultType="com.oak.po.User">
		select * from `user` where id=#{id}
	</select>
	
	<!-- 根據名稱模糊查詢使用者資訊列表 -->
	<select id="findUserByName" parameterType="String" resultType="com.oak.po.User">
		select * from `user` where name like '${value}'
	</select>
	
	<!-- 新增一條資訊 返回自動增長主鍵 -->
	<insert id="add" parameterType="com.oak.po.User">
		insert into `user` values(null,#{name})
	</insert>
</mapper>

Mapper介面開發規範(以上4條):
在這裡插入圖片描述

7)載入UserMapper.xml對映檔案

在SqlMapConfig.xml檔案新增如下配置:

<!-- 載入mapper對映檔案 -->
<mappers>
	<mapper resource="sqlmap/UserMapper.xml"/>
</mappers>

8)測試

在com.oak.test中編寫寫測試類UserTest:

public class UserTest {	
	// 工廠物件一般在我們的系統中是單例的
	private SqlSessionFactory sqlSessionFactory=null;
	@Before
	public void init() throws IOException{
		// 第一步,建立SqlSessionFactoryBuilder物件
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 第二步,載入配置檔案
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 第三步,建立SqlSessionFactory物件
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
	}
	@Test
	public void testFindById(){
		//第四步  得到sqlSession,與Spring整合後省略
		SqlSession sqlSession=sqlSessionFactory.openSession();
		//獲得代理物件(與Spring整合後只需要通過Spring容器拿到UserMapper介面的代理物件就行了)
		UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
		User user=userMapper.findById(2);
		System.out.println(user);
		sqlSession.close();
	}
}

檢視結果:
在這裡插入圖片描述


小結

selectOne和selectList

動態代理物件呼叫sqlSession.selectOne()和sqlSession.selectList()是根據mapper介面方法的返回值決定,如果返回list則呼叫selectList方法,如果返回單個物件則呼叫selectOne方法。

namespace

mybatis官方推薦使用mapper代理方法開發mapper介面,程式設計師不用編寫mapper介面實現類,使用mapper代理方法時,輸入引數可以使用pojo包裝物件或map物件,保證dao的通用性。


MyBatis核心配置檔案SqlMapConfig.xml配置內容

  • properties(屬性)
  • settings(全域性配置引數)
  • typeAliases(類型別名)
  • typeHandlers(型別處理器)
  • objectFactory(物件工廠)
  • plugins(外掛)
  • environments(環境集合屬性物件)
    • environment(環境子屬性物件)
      • transactionManager(事務管理)
      • dataSource(資料來源)
  • mappers(對映器)

properties

如上案例:

<!-- 配置屬性 -->
<properties resource="db.properties"/>

我們也可以在properties屬性中使用property子標籤來定義屬性:

<!-- 配置屬性 -->
<properties resource="db.properties">
	 <property name="driver" value="com.mysql.jdbc.Driver"/>
</properties>

MyBatis將按照下面的順序來載入屬性為:
在properties元素體內定義的屬性首先被讀取
然後會讀取properties元素中resource或url載入的屬性,它會覆蓋已讀取的同名屬性
也就是說,此處通過property定義的屬性名driver屬性會被db.properties中同名的driver屬性覆蓋。
我們一般使用resource的方式載入屬性。


typeAliases(類型別名)

mybatis支援別名:

別名 對映型別
_byte byte
_short short
_int int
_integer int
_long long
_float float
_double double
_boolean boolean
string String
byte Byte
short Short
int Integer
integer Integer
long Long
float Float
double Double
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map

自定義別名

我們把上述案例中的com.oak.po.User類定義別名,以方便使用,在SqlMapConfig.xml中新增如下配置資訊:

<!-- 配置User別名 -->
<typeAliases>
	<!-- 單個別名定義 -->
	<typeAlias type="com.oak.po.User" alias="user"/>
</typeAliases>

在UserMapper.xml中使用別名:

<!-- 根據id獲取使用者資訊 別名 不區分大小寫-->
<select id="findById" parameterType="int" 
resultType="User">
	select * from `user` where id=#{id}
</select>

注意:resultType屬性的值就是User類的別名,且別名是不區分大小寫的。

給所有的po同時定義別名

可以給所有的po批量定義別名,別名就是類名且不區分大小寫:

<typeAliases>
  	<!-- 批量別名定義,掃描包的形式建立別名,別名就是類名,且不區分大小寫 -->
    <package name="com.oak.po"/>
</typeAliases>

SqlMapConfig.xml檔案載入mapper.xml檔案

Mapper(對映器)配置的幾種方法:

1)使用相對於類路徑的資源:< mapper resource=" " />

在這裡插入圖片描述

2)使用mapper介面類路徑:< mapper class=" " />

 <!-- 載入mapper對映檔案 -->
 <mappers>
  		<mapper class="com.oak.mapper.UserMapper"/>
 </mappers>

注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中。
在這裡插入圖片描述

3)註冊指定包下的所有mapper介面:< package name=""/>

<!-- 載入mapper對映檔案 -->
<mappers>
	<!-- 要求與使用介面名載入配置相同 -->
	<package name="com.oak.mapper"/>
</mappers>

注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中。
在這裡插入圖片描述

雖然Mapper(對映器)配置有以上三種方法,但是實際開發中就用第三種方法。