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(資料來源)
- environment(環境子屬性物件)
- 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(對映器)配置有以上三種方法,但是實際開發中就用第三種方法。