Mybatis之旅第二篇-Mapper動態(tài)代理方式

一、引言

通過上一篇mybatis的入門學習,我們已經(jīng)會使用mybatis實現(xiàn)簡單的增刪改查,但是我們也發(fā)現(xiàn)了用原始Dao開發(fā)的一些問題:

Dao方法體存在重復代碼:通過SqlSessionFactory創(chuàng)建SqlSession,調(diào)用SqlSession的數(shù)據(jù)庫操作方法

調(diào)用sqlSession的數(shù)據(jù)庫操作方法需要指定statement的id,這里存在硬編碼,不得于開發(fā)維護。

為了解決這些問題,我們采用Mapper動態(tài)代理方法來進行開發(fā):程序員編寫Mapper接口(相當于Dao接口),由Mybatis框架根據(jù)接口定義創(chuàng)建接口的動態(tài)代理對象,代理對象的方法體同上邊Dao接口實現(xiàn)類方法。

二、開發(fā)規(guī)范

Mapper接口開發(fā)需要遵循以下規(guī)范:

1、 Mapper.xml文件中的namespace與mapper接口的類路徑相同。

2、 Mapper接口方法名和Mapper.xml中定義的每個statement的id相同

3、 Mapper接口方法的輸入?yún)?shù)類型和mapper.xml中定義的每個sql 的parameterType的類型相同

4、Mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的每個sql的resultType的類型相同

三、改造

第一步:Mapper.xml(映射文件)

定義mapper映射文件UserMapper.xml,將UserMapper.xml放在config下mapper目錄下,效果如下:

文件內(nèi)容如下:

<?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"><!-- namespace:命名空間,用于隔離sql,還有一個很重要的作用,后面會講 --><mapper namespace="com.yuanqinnan.mapper.UserMapper"><select id="queryUserById" parameterType="int" resultType="com.yuanqinnan.model.User">? ? SELECT * FROM `user`where id=#{id}

? </select><!-- 查詢 user 表的所有數(shù)據(jù)--><select id="selectUserAll" resultType="com.yuanqinnan.model.User">? ? ? ? select * from user

? ? </select><!--? ? ? ? ? ? 1、${value}里面必須要寫value,不然會報錯

? ? ? ? ? ? 2、${}表示拼接 sql 字符串,將接收到的參數(shù)不加任何修飾拼接在sql語句中

? ? ? ? ? ? 3、使用${}會造成 sql 注入

? ? --><select id="selectLikeUserName" resultType="com.yuanqinnan.model.User" parameterType="String">? ? ? ? select * from user where username like '%${value}%'

? ? </select><!--#{}實現(xiàn)--><select id="selectLikeUserName2" resultType="com.yuanqinnan.model.User" parameterType="String">? ? ? ? select * from user where username like #{username}

? ? </select><!-- 向 user 表插入一條數(shù)據(jù) --><insert id="insertUser" parameterType="com.yuanqinnan.model.User">? ? ? ? insert into user(id,username,sex,birthday,address)

? ? ? ? ? ? value(#{id},#{username},#{sex},#{birthday},#{address})

? ? </insert><!-- 保存用戶 --><insert id="saveUser" parameterType="com.yuanqinnan.model.User"><!-- selectKey 標簽實現(xiàn)主鍵返回 --><!-- keyColumn:主鍵對應(yīng)的表中的哪一列 --><!-- keyProperty:主鍵對應(yīng)的pojo中的哪一個屬性 --><!-- order:設(shè)置在執(zhí)行insert語句前執(zhí)行查詢id的sql,在執(zhí)行insert語句之后執(zhí)行查詢id的sql --><!-- resultType:設(shè)置返回的id的類型 --><selectKey keyColumn="id" keyProperty="id" order="AFTER"? ? ? ? ? ? ? ? ? resultType="int">? ? ? ? ? ? SELECT LAST_INSERT_ID()

? ? ? ? </selectKey>? ? ? ? INSERT INTO `user`

? ? ? ? (username,birthday,sex,address) VALUES

? ? ? ? (#{username},#{birthday},#{sex},#{address})

? ? </insert><!-- 根據(jù) id 更新 user 表的數(shù)據(jù) --><update id="updateUserById" parameterType="com.yuanqinnan.model.User">? ? ? ? update user set username=#{username} where id=#{id}

? ? </update><!-- 根據(jù) id 刪除 user 表的數(shù)據(jù) --><delete id="deleteUserById" parameterType="int">? ? ? ? delete from user where id=#{id}

? ? </delete></mapper>

其他地方未有改動,主要是namespace="com.yuanqinnan.mapper.UserMapper"的修改,現(xiàn)在我們實現(xiàn)這個接口

第二步:UserMapper(接口文件)

新建mapper包,新增接口UserMapper

內(nèi)容:

publicinterface UserMapper {

? ? //查詢用戶User queryUserById(int id);

? ? //查詢用戶列表List selectUserAll();

? ? //模糊查詢List selectLikeUserName(String username);

? ? //新增void saveUser(User user);


}

第三步:加載UserMapper.xml文件

<mappers><!-- 映射文件方式1,一個一個的配置--><mapper resource="config/sqlmap/User.xml"/><mapper resource="config/mapper/UserMapper.xml"/></mappers>

測試:

publicclass MapperTest {

? ? private SqlSessionFactory sqlSessionFactory;

? ? @Before

? ? publicvoidinit()throws Exception {

? ? ? ? // 創(chuàng)建SqlSessionFactoryBuilderSqlSessionFactoryBuilder sqlSessionFactoryBuilder =new SqlSessionFactoryBuilder();

? ? ? ? // 加載SqlMapConfig.xml配置文件InputStream inputStream = Resources.getResourceAsStream("config/SqlMapConfig.xml");

? ? ? ? // 創(chuàng)建SqlsessionFactorythis.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);

? ? }

? ? @Test

? ? publicvoid testQueryUserById() {

? ? ? ? // 獲取sqlSession,和spring整合后由spring管理SqlSession sqlSession =this.sqlSessionFactory.openSession();

? ? ? ? // 從sqlSession中獲取Mapper接口的代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

? ? ? ? // 執(zhí)行查詢方法User user = userMapper.queryUserById(1);

? ? ? ? System.out.println(user);

? ? ? ? // 和spring整合后由spring管理? ? ? ? sqlSession.close();

? ? }

? ? @Test

? ? publicvoid testQueryUserByUsername() {

? ? ? ? // 獲取sqlSession,和spring整合后由spring管理SqlSession sqlSession =this.sqlSessionFactory.openSession();

? ? ? ? // 從sqlSession中獲取Mapper接口的代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

? ? ? ? // 執(zhí)行查詢方法List list = userMapper.selectLikeUserName("張");

? ? ? ? for (User user : list) {

? ? ? ? ? ? System.out.println(user);

? ? ? ? }

? ? ? ? // 和spring整合后由spring管理? ? ? ? sqlSession.close();

? ? }

? ? @Test

? ? publicvoid testSaveUser() {

? ? ? ? // 獲取sqlSession,和spring整合后由spring管理SqlSession sqlSession =this.sqlSessionFactory.openSession();

? ? ? ? // 從sqlSession中獲取Mapper接口的代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

? ? ? ? // 創(chuàng)建保存對象User user =new User();

? ? ? ? user.setUsername("劉備");

? ? ? ? user.setBirthday(new Date());

? ? ? ? user.setSex("1");

? ? ? ? user.setAddress("蜀國");

? ? ? ? // 執(zhí)行查詢方法? ? ? ? userMapper.saveUser(user);

? ? ? ? System.out.println(user);

? ? ? ? // 和spring整合后由spring管理? ? ? ? sqlSession.commit();

? ? ? ? sqlSession.close();

? ? }

}

測試結(jié)果與上一篇相同

四、總結(jié)

selectOne和selectList

動態(tài)代理對象調(diào)用sqlSession.selectOne()和sqlSession.selectList()是根據(jù)mapper接口方法的返回值決定,如果返回list則調(diào)用selectList方法,如果返回單個對象則調(diào)用selectOne方法。

namespace

mybatis官方推薦使用mapper代理方法開發(fā)mapper接口,程序員不用編寫mapper接口實現(xiàn)類,使用mapper代理方法時,輸入?yún)?shù)可以使用pojo包裝對象或map對象,保證dao的通用性。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Mybatis介紹 MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache...
    day_Sunny閱讀 2,695評論 0 6
  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,657評論 0 4
  • 1.1mybatis下載 mybaits 的代碼由github.com 管理,地址:https://github....
    暖熊熊閱讀 882評論 0 5
  • 天???氣???太???熱,文???字???都???出???汗???了??? 熱???瘋???了,全???身???...
    我也是最懶啦閱讀 188評論 0 0
  • 本周可謂處于 “近乎中暑”的狀態(tài)。炎熱的天氣令人些許煩躁,當然還是個人修養(yǎng)欠缺吧。坐得令人后背疼痛的排練以及去外地...
    梁夢婷閱讀 246評論 0 1