MyBatis學習--mybatis開發dao的方法

  • 簡介

  使用Mybatis開發Dao,一般有兩個方法,即原始Dao開發方法和Mapper接口開發方法。java

  • 主要概念介紹:

  MyBatis中進行Dao開發時候有幾個重要的類,它們是SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession。程序員

  SqlSession中封裝了對數據庫的操做,如:查詢、插入、更新、刪除等。經過SqlSessionFactory建立SqlSession,而SqlSessionFactory是經過SqlSessionFactoryBuilder進行建立。sql

  一、SqlSessionFactoryBuilder數據庫

  SqlSessionFactoryBuilder用於建立SqlSessionFacoty,SqlSessionFacoty一旦建立完成就不須要SqlSessionFactoryBuilder了,由於SqlSession是經過SqlSessionFactory生產,因此能夠將SqlSessionFactoryBuilder當成一個工具類使用,最佳使用範圍是方法範圍即方法體內局部變量。安全

  二、SqlSessionFactorysession

  SqlSessionFactory是一個接口,接口中定義了openSession的不一樣重載方法,SqlSessionFactory的最佳使用範圍是整個應用運行期間,一旦建立後能夠重複使用,一般以單例模式管理SqlSessionFactory。mybatis

  三、SqlSessionapp

  SqlSession是一個面向用戶的接口, sqlSession中定義了數據庫操做,默認使用DefaultSqlSession實現類。框架

  SqlSession中提供了不少操做數據庫的方法:如:selectOne(返回單個對象)、selectList(返回單個或多個對象),SqlSession是線程不安全的,在SqlSesion實現類中除了有接口中的方法(操做數據庫的方法)還有數據域屬性,SqlSession最佳應用場合在方法體內,定義成局部變量使用,絕對不能將SqlSession實例的引用放在一個類的靜態字段或實例字段中。ide

  打開一個 SqlSession;使用完畢就要關閉它。一般把這個關閉操做放到 finally 塊中以確保每次都能執行關閉。以下:

 

1 SqlSession session = sqlSessionFactory.openSession();
2 try {
3       // do work
4 } finally {
5       session.close();
6 }
  • 原始Dao開發方式

  原始Dao開發方法須要程序員編寫Dao接口和Dao實現類。

  仍是之前文提到的簡單的增刪改查爲例,來簡單介紹原始Dao開發方式。

  一、映射文件

 

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="user">
 6     <!-- 根據id獲取用戶信息 -->
 7     <select id="findUserById" parameterType="int" resultType="user">
 8         select * from user where id = #{id}
 9     </select>
10     <!-- 根據username模糊查詢用戶信息 -->
11     <select id="findUserByName" parameterType="java.lang.String" resultType="com.luchao.mybatis.first.po.User">
12         select * from user where username like '%${value}%'
13     </select>
14     <!-- 添加用戶信息 -->
15     <insert id="insertUser" parameterType="com.luchao.mybatis.first.po.User">
16         <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
17             select LAST_INSERT_ID()
18         </selectKey>
19         insert into user(username,birthday,sex,address) value (#{username},#{birthday},#{sex},#{address});
20     </insert>
21     <!-- 根據id刪除用戶信息 -->
22     <delete id="deleteUser" parameterType="int">
23         delete from user where id=#{id}
24     </delete>
25     <!-- 修改用戶信息 -->
26     <update id="updateUser" parameterType="com.luchao.mybatis.first.po.User">
27         update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
28         where id=#{id}
29     </update>
30 </mapper>

 

  二、Dao接口

1 public interface UserDao {
2     //根據ID查詢用戶信息
3     public User findUserById(int id) throws Exception;
4     //添加用戶信息
5     public void insertUser(User user) throws Exception;
6     //刪除用戶信息
7     public void deleteUser(int id) throws Exception;
8 }

  三、Dao接口實現類

 1 public class UserDaoImpl implements UserDao{
 2     
 3     // 須要向dao實現類中注入SqlSessionFactory
 4     // 這裏經過構造方法注入
 5     private SqlSessionFactory sqlSessionFactory;
 6     
 7     public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
 8         super();
 9         this.sqlSessionFactory = sqlSessionFactory;
10     }
11     @Override
12     public void deleteUser(int id) throws Exception {
13         SqlSession sqlSession = sqlSessionFactory.openSession();
14         //執行刪除操做
15         sqlSession.insert("user.deleteUser", id);
16         // 提交事務
17         sqlSession.commit();
18         // 釋放資源
19         sqlSession.close();
20     }
21     @Override
22     public User findUserById(int id) throws Exception {
23         SqlSession sqlSession = sqlSessionFactory.openSession();//獲取sqlSession
24         User user = sqlSession.selectOne("user.findUserById", id);
25         sqlSession.close();//關閉資源
26         return user;
27     }
28     @Override
29     public void insertUser(User user) throws Exception {
30         SqlSession sqlSession = sqlSessionFactory.openSession();
31         //執行插入操做
32         sqlSession.insert("user.insertUser", user);
33         // 提交事務
34         sqlSession.commit();
35         // 釋放資源
36         sqlSession.close();
37     }
38 }

  四、測試代碼:

 1 public class MyBatis_dao_test {
 2     private SqlSessionFactory sqlSessionFactory;
 3     @Before
 4     public void init() throws IOException{
 5         //建立sqlSessionFactory
 6         //MyBatis配置文件
 7         String resource = "SqlMapConfig.xml";
 8         //獲得配置文件流
 9         InputStream inputStream = Resources.getResourceAsStream(resource);
10         //建立會話工廠,傳入MyBatis的配置信息
11         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
12     }
13     @Test
14     public void testFindUserById() throws Exception{
15         //建立UserDao對象
16         UserDao userDao = new UserDaoImpl(sqlSessionFactory);
17         //調用UserDao的方法,根據ID查找user
18         User user = userDao.findUserById(10);
19         //打印客戶信息
20         System.out.println(user);
21     }
22 }

  五、原始Dao方法總結:

  (1)、dao接口實現類方法中存在大量模板方法,如:經過SqlSessionFactory建立SqlSession,調用SqlSession的數據庫操做方法。

  (2)、調用sqlSession的數據庫操做方法須要指定statement的id,這裏存在硬編碼。

  (3)、調用sqlsession方法時傳入的變量,因爲sqlsession方法使用泛型,即便變量類型傳入錯誤,在編譯階段也不報錯,不利於程序員開發。

  • Mapper動態代理方式

  一、實現原理

  Mapper接口開發方法只須要程序員編寫Mapper接口(至關於Dao接口),由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的類型相同。

  二、Mapper.xml(映射文件)

  映射文件與原始Dao開發的映射文件類似,只須要將namespace定於爲mapper接口全路徑。

<?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.luchao.mybatis.first.mapper.UserMapper">
    <!-- 根據id獲取用戶信息 -->
    <select id="findUserById" parameterType="int" resultType="user">
        select * from user where id = #{id}
    </select>
    <!-- 根據username模糊查詢用戶信息 -->
    <select id="findUserByName" parameterType="java.lang.String" resultType="com.luchao.mybatis.first.po.User">
        select * from user where username like '%${value}%'
    </select>
    <!-- 添加用戶信息 -->
    <insert id="insertUser" parameterType="com.luchao.mybatis.first.po.User">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user(username,birthday,sex,address) value (#{username},#{birthday},#{sex},#{address});
    </insert>
    <!-- 根據id刪除用戶信息 -->
    <delete id="deleteUser" parameterType="int">
        delete from user where id=#{id}
    </delete>
    <!-- 修改用戶信息 -->
    <update id="updateUser" parameterType="com.luchao.mybatis.first.po.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
        where id=#{id}
    </update>
</mapper>

 

  三、Mapper.java(接口文件)

 1 public interface UserMapper {
 2     //根據ID查詢用戶信息
 3     public User findUserById(int id) throws Exception;
 4     //添加用戶信息
 5     public void insertUser(User user) throws Exception;
 6     //刪除用戶信息
 7     public void deleteUser(int id) throws Exception;
 8     //更新用戶信息
 9     public void updateUser(User user) throws Exception;
10     //根據用戶名模糊查找
11     public List<User> findUserByName(String user) throws Exception;
12 }

  接口定義有以下特色:

  (1)、 Mapper接口方法名和Mapper.xml中定義的statement的id相同。

  (2)、 Mapper接口方法的輸入參數類型和mapper.xml中定義的statement的parameterType的類型相同。

  (3)、 Mapper接口方法的輸出參數類型和mapper.xml中定義的statement的resultType的類型相同。

  四、加載UserMapper.xml文件

  在SqlMapConfig.xml文件中加載UserMapper.xml,以下:

1 <mappers>
2     <mapper resource="mapper/UserMapper.xml"/>
3 </mappers>

  五、測試代碼:

 1 public class MyBatis_mapper_test {
 2     private SqlSessionFactory sqlSessionFactory;
 3     @Before
 4     public void init() throws IOException{
 5         //建立sqlSessionFactory
 6         //MyBatis配置文件
 7         String resource = "SqlMapConfig.xml";
 8         //獲得配置文件流
 9         InputStream inputStream = Resources.getResourceAsStream(resource);
10         //建立會話工廠,傳入MyBatis的配置信息
11         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
12     }
13     @Test
14     public void testFindUserById() throws Exception{
15         //獲取sqlSession對象
16         SqlSession sqlSession = sqlSessionFactory.openSession();
17         //建立UserMapper對象,MyBatis自動生成mapper代理
18         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
19         //調用userMapper的方法
20         User user = userMapper.findUserById(10);
21         //關閉資源
22         sqlSession.close();
23         //打印客戶信息
24         System.out.println(user);
25     }
26 }

  五、Mapper動態代理總結:

  (1)、動態代理對象調用sqlSession.selectOne()和sqlSession.selectList()是根據mapper接口方法的返回值決定,若是返回list則調用selectList方法,若是返回單個對象則調用selectOne方法。

  (2)、使用mapper代理方法時,輸入參數能夠使用pojo包裝對象或map對象,保證dao的通用性。在系統中,dao層的代碼是被業務層公用的。即便mapper接口只有一個參數,能夠使用包裝類型的pojo知足不一樣的業務方法的需求。

 

   注意:持久層方法的參數能夠包裝類型、map等,service方法中建議不要使用包裝類型(不利於業務層的可擴展)。

  mybatis開發dao的方法有兩種:原始Dao開發和Mapper動態代理開發,這兩種各有優勢。原始Dao開發:程序員要寫Dao和Dao實現,須要些較多的代碼,可是比較好理解。Mapper動態代理:程序員只須要寫Mapper接口,而後按照規範進行配置,MyBatis就會自動實現相似Dao實現,減小模板方法。mybatis官方推薦使用mapper代理方法開發mapper接口,程序員不用編寫mapper接口實現類,使用mapper代理方法時,輸入參數能夠使用pojo包裝對象或map對象,保證dao的通用性。

相關文章
相關標籤/搜索