Mybatis 增刪改查之dao層實現

1.背景

   在上篇中咱們使用了MyBatis實現簡單的增刪改查,並無進行dao層的封裝,因此在這裏咱們進行dao層開發:html

   (1)傳統的jdbc dao層開發(寫dao接口,實現dao接口類)java

   (2)mapper代理方法 (只須要寫mapper接口類,至關於dao接口類)mysql

     在Mybatis操做的時候,咱們使用的是SqlSession 來進行數據庫操做,其中SqlSession的使用範圍:
     經過SqlSessionFactoryBuilder建立SqlSessionFactory ,而SqlSession經過SqlSessionFactory 建立,因此使用單例模式管理SqlSessionFactory,未來使用mybatis和spring整合後,使用單例模式管理SqlSessionFactory;
      
spring

     SqlSession的做用是:
            1)提供接口,不少操做數據庫的方法,如:selectOne ,selectList
  2)線程不安全,在sqlSession實現類中除了有接口中的方法,還有數據域的屬性;
  3)最佳應用的場合在方法體內,定義成局部變量使用。
sql

 

2.原始dao開發實現

   (1)dao接口

 

[java]  view plain  copy
 
  1. package mybatie.dao;  
  2.   
  3. import mybatis.po.FClient;  
  4.   
  5.   
  6. /** 
  7.  * 用戶接口 
  8.  * 
  9.  * 做者:原明卓 
  10.  * 時間:2015年12月21日 上午10:00:00 
  11.  * 描述:TODO 
  12.  */  
  13. public interface ClientDao {  
  14.       
  15.     FClient findClientById(int id) throws Exception;  
  16.       
  17.     void updateClient(FClient f)  throws Exception;  
  18.       
  19.     void deleteClient(int id) throws Exception;  
  20.   
  21.     void insertClient(FClient f) throws Exception;  
  22.       
  23. }  

 

 

    (2)實現dao接口

 

             實現數據庫操做的幾個方法:數據庫

 

[java]  view plain  copy
 
  1. package mybatie.dao;  
  2.   
  3. import mybatis.po.FClient;  
  4. import oracle.net.aso.s;  
  5.   
  6. import org.apache.ibatis.session.SqlSession;  
  7. import org.apache.ibatis.session.SqlSessionFactory;  
  8.   
  9. public class ClientDaoImp implements ClientDao {  
  10.   
  11.     private SqlSessionFactory sqlSessionFactory;  
  12.   
  13.     public ClientDaoImp(SqlSessionFactory sqlSessionFactory) {  
  14.         this.sqlSessionFactory = sqlSessionFactory;  
  15.     }  
  16.   
  17.     @Override  
  18.     public FClient findClientById(int id) {  
  19.   
  20.         SqlSession sqlSession = sqlSessionFactory.openSession();  
  21.         FClient c = sqlSession.selectOne("test.findClientById", id);  
  22.         sqlSession.close();  
  23.         return c;  
  24.     }  
  25.   
  26.     @Override  
  27.     public void updateClient(FClient f) {  
  28.         SqlSession sqlSession=sqlSessionFactory.openSession();  
  29.         sqlSession.update("test.updateClient",f);  
  30.         sqlSession.commit();  
  31.         sqlSession.close();  
  32.     }  
  33.   
  34.     @Override  
  35.     public void deleteClient(int id) {  
  36.           SqlSession session = sqlSessionFactory.openSession();  
  37.           session.delete("test.deleteClient", id);  
  38.           session.commit();  
  39.           session.close();  
  40.     }  
  41.   
  42.     @Override  
  43.     public void insertClient(FClient f) {  
  44.         SqlSession session = sqlSessionFactory.openSession();  
  45.         session.insert("test.insertClient", f);  
  46.         session.commit();  
  47.         session.close();   
  48.     }  
  49.       
  50.   
  51. }  



 

   (3)測試類

 

[java]  view plain  copy
 
  1. public class TestClient {  
  2.   
  3.     private SqlSessionFactory sqlSessionFactory;  
  4.   
  5.     @Before  
  6.     public void setUp() throws Exception {  
  7.         InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");  
  8.         sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);  
  9.     }  
  10.   
  11.     @Test  
  12.     public void test() {  
  13.         fail("Not yet implemented");  
  14.     }  
  15.   
  16.     @Test  
  17.     public void findClientById() throws Exception {  
  18.   
  19.         ClientDao clientDao = new ClientDaoImp(sqlSessionFactory);  
  20.         FClient c = clientDao.findClientById(1);  
  21.         System.out.println(c);  
  22.     }  
  23.   
  24. }  

 

 

    (4)原始的dao層遇到的問題

 

             1)dao接口實現類方法中存在大量的模板方法,設想可否將這些代碼提取出來
     2)調用sqlsession方法的時候將statement存在硬編碼
     3)調用sqlsession的方法的時候,傳入參數爲Object 類型,及時傳入錯誤,也不會報錯

apache

 

3.使用Mapper代理的方式實現

      基本步驟爲 :   安全

             1)編寫mapper.xml映射文件 session

             2)編寫Mapper接口,至關於dao接口 mybatis

             3)mybatis能夠自動生成mapper接口的實現類代理對象

    (1)實現Mapper映射文件

              mapper.xml 規範 :
 1)namespace 等於mapper接口地址
 2)mapper.Java 接口中的方法和mapper.xml中的statement 的id一致
 3)mapper.java 接口中的方法的參數和mapper.xml中的statement 的paramterType類型一致
 4)mapper.java 接口中的方法的返回值和mapper.xml中的statement的resultType類型一致
 
總結 :mapper.xml實現的規範,就是對SqlSession接口中的方法進行統一的生成

       好比 :

 

[html]  view plain  copy
 
  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.   
  6. <!-- namespace命名空間,做用就是對sql進行分類化管理,理解sql隔離 -->  
  7. <!-- 注意:使用mapper代理的方法開發,namespace有特殊的重要做用,namespace爲mapper接口的地址 -->  
  8.   
  9. <mapper namespace="mybatie.mapper.ClientMapper">  
  10.   
  11.     <!-- 在映射文件中配置不少的sql語句 -->  
  12.     <!-- 經過select 執行數據庫查詢 id:表示映射文件的sql, 將sql語句封裝到mappedStatement對象中,因此將id稱爲statement的id   
  13.         #{}: 表示一個佔位符,至關於jdbc中的? parameterType : 指定參數類型,好比指定爲int #{id} : 其中的id表示接入輸入的參數,參數名稱就是id,若是輸入的參數是簡單類型   
  14.         #{}中參數名能夠任意,能夠value或其餘名稱; resultType :指定sql輸出的結果的映射java對象類型,select指定的resultType表示將單條記錄映射成java對象 -->  
  15.     <!-- 根據id查用戶 -->  
  16.     <select id="findClientById" parameterType="int" resultType="mybatis.po.FClient">  
  17.         select * from f_client where id=#{id}  
  18.     </select>  
  19.   
  20.     <!-- 根據用戶名模糊查詢 resultType :指定的單條記錄所映射的java對象類型 #{} 表示佔位符 ${}:表示拼接sql串,將接收到的參數內容不加任何修飾拼接在sql中,使用${}拼接,引發sql注入   
  21.         ${value} :接入輸入參數的內容,若是傳入類型是簡單類型,${}簡單的 -->  
  22.     <select id="findClientByName" parameterType="java.lang.String"  
  23.         resultType="mybatis.po.FClient">  
  24.         select *from f_client where username like '%${value}%'  
  25.     </select>  
  26.   
  27.     <!-- 添加用戶 這裏注意 主鍵返回實現 -->  
  28.     <select id="insertClient" parameterType="mybatis.po.FClient"  
  29.         resultType="java.lang.Integer">  
  30.         insert into  
  31.         f_client(id,username,client_certificate_no,born_date,family_register_address,now_address,contact_mode,urgency_contact_mode,create_date)  
  32.         values (#{id},  
  33.         #{username},#{client_certificate_no},#{born_date},#{family_register_address},#{now_address},#{contact_mode},#{urgency_contact_mode},#{create_data})  
  34.     </select>  
  35.   
  36.     <!-- 刪除用戶 -->  
  37.     <delete id="deleteClient" parameterType="int">  
  38.         delete from f_client where id=#{id}  
  39.     </delete>  
  40.   
  41.     <!-- 更新用戶 -->  
  42.     <update id="updateClient" parameterType="mybatis.po.FClient">  
  43.   
  44.         update f_client set  
  45.         username=#{username},client_certificate_no=#{client_certificate_no},born_date=#{born_date},family_register_address=#{family_register_address},now_address=#{now_address},contact_mode=#{contact_mode},urgency_contact_mode=#{urgency_contact_mode}  
  46.         where id=#{id}  
  47.   
  48.     </update>  
  49.   
  50.   
  51. </mapper>  



 

   (2)mapper接口

               注意接口定義的和Mapper.xml對比下,看看mapper.xml的 規範!!

 

[java]  view plain  copy
 
  1. package mybatie.mapper;  
  2.   
  3. import java.util.List;  
  4.   
  5. import mybatis.po.FClient;  
  6.   
  7.   
  8. /** 
  9.  * mapper接口 ,對應Clientmapper.xml 
  10.  * 做者:原明卓 
  11.  * 時間:2015年12月21日 上午10:00:00 
  12.  * 描述:TODO 
  13.  */  
  14. public interface ClientMapper {  
  15.       
  16.     public FClient findClientById(int id) throws Exception;  
  17.       
  18.     public void updateClient(FClient f)  throws Exception;  
  19.       
  20.     public void deleteClient(int id) throws Exception;  
  21.   
  22.     public int insertClient(FClient f) throws Exception;  
  23.       
  24.     public List<FClient> findClientByName(String name) throws Exception;  
  25. }  

 

 

      (3)測試

 

 

[java]  view plain  copy
 
  1. private SqlSessionFactory sqlfactory;  
  2.   
  3. @Before  
  4. public void setUp() throws Exception {  
  5.     InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");  
  6.     sqlfactory=new SqlSessionFactoryBuilder().build(is);  
  7. }  
  8.   
  9. @Test  
  10. public void testFindClientById() throws Exception {  
  11.     SqlSession session = sqlfactory.openSession();  
  12.     ClientMapper mapper = session.getMapper(ClientMapper.class);  
  13.     FClient fc = mapper.findClientById(1);  
  14.     System.out.println(fc);  
  15.     session.close();  
  16. }  



 

 

4.一些問題

       (1)代理對象內部調用selectOne或 selectList
 若是mapper方法返回單個pojo對象,代理對象內部經過selectOne查詢數據庫;
 若是mapper方法返回集合對象,代理對象內部經過內部經過selectList查詢數據庫;
 不然會報錯誤。
        (2) mapper接口方法參數只能有一個是否影響系統開發
  系統框架中,dao層的代碼是不是被業務層公用的,即便mapper接口只有一個參數,可使用包裝
 類型pojo知足不一樣業務方法需求;
  注意:持久層方法的參數能夠包裝類型,map,service方法中建議不要使用包裝類型,由於不利於
 業務層的可擴展性。

1.背景

   在上篇中咱們使用了MyBatis實現簡單的增刪改查,並無進行dao層的封裝,因此在這裏咱們進行dao層開發:

   (1)傳統的jdbc dao層開發(寫dao接口,實現dao接口類)

   (2)mapper代理方法 (只須要寫mapper接口類,至關於dao接口類)

     在Mybatis操做的時候,咱們使用的是SqlSession 來進行數據庫操做,其中SqlSession的使用範圍:
     經過SqlSessionFactoryBuilder建立SqlSessionFactory ,而SqlSession經過SqlSessionFactory 建立,因此使用單例模式管理SqlSessionFactory,未來使用mybatis和spring整合後,使用單例模式管理SqlSessionFactory;
      

     SqlSession的做用是:
            1)提供接口,不少操做數據庫的方法,如:selectOne ,selectList
  2)線程不安全,在sqlSession實現類中除了有接口中的方法,還有數據域的屬性;
  3)最佳應用的場合在方法體內,定義成局部變量使用。

 

2.原始dao開發實現

   (1)dao接口

 

[java]  view plain  copy
 
  1. package mybatie.dao;  
  2.   
  3. import mybatis.po.FClient;  
  4.   
  5.   
  6. /** 
  7.  * 用戶接口 
  8.  * 
  9.  * 做者:原明卓 
  10.  * 時間:2015年12月21日 上午10:00:00 
  11.  * 描述:TODO 
  12.  */  
  13. public interface ClientDao {  
  14.       
  15.     FClient findClientById(int id) throws Exception;  
  16.       
  17.     void updateClient(FClient f)  throws Exception;  
  18.       
  19.     void deleteClient(int id) throws Exception;  
  20.   
  21.     void insertClient(FClient f) throws Exception;  
  22.       
  23. }  

 

 

    (2)實現dao接口

 

             實現數據庫操做的幾個方法:

 

[java]  view plain  copy
 
  1. package mybatie.dao;  
  2.   
  3. import mybatis.po.FClient;  
  4. import oracle.net.aso.s;  
  5.   
  6. import org.apache.ibatis.session.SqlSession;  
  7. import org.apache.ibatis.session.SqlSessionFactory;  
  8.   
  9. public class ClientDaoImp implements ClientDao {  
  10.   
  11.     private SqlSessionFactory sqlSessionFactory;  
  12.   
  13.     public ClientDaoImp(SqlSessionFactory sqlSessionFactory) {  
  14.         this.sqlSessionFactory = sqlSessionFactory;  
  15.     }  
  16.   
  17.     @Override  
  18.     public FClient findClientById(int id) {  
  19.   
  20.         SqlSession sqlSession = sqlSessionFactory.openSession();  
  21.         FClient c = sqlSession.selectOne("test.findClientById", id);  
  22.         sqlSession.close();  
  23.         return c;  
  24.     }  
  25.   
  26.     @Override  
  27.     public void updateClient(FClient f) {  
  28.         SqlSession sqlSession=sqlSessionFactory.openSession();  
  29.         sqlSession.update("test.updateClient",f);  
  30.         sqlSession.commit();  
  31.         sqlSession.close();  
  32.     }  
  33.   
  34.     @Override  
  35.     public void deleteClient(int id) {  
  36.           SqlSession session = sqlSessionFactory.openSession();  
  37.           session.delete("test.deleteClient", id);  
  38.           session.commit();  
  39.           session.close();  
  40.     }  
  41.   
  42.     @Override  
  43.     public void insertClient(FClient f) {  
  44.         SqlSession session = sqlSessionFactory.openSession();  
  45.         session.insert("test.insertClient", f);  
  46.         session.commit();  
  47.         session.close();   
  48.     }  
  49.       
  50.   
  51. }  



 

   (3)測試類

 

[java]  view plain  copy
 
  1. public class TestClient {  
  2.   
  3.     private SqlSessionFactory sqlSessionFactory;  
  4.   
  5.     @Before  
  6.     public void setUp() throws Exception {  
  7.         InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");  
  8.         sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);  
  9.     }  
  10.   
  11.     @Test  
  12.     public void test() {  
  13.         fail("Not yet implemented");  
  14.     }  
  15.   
  16.     @Test  
  17.     public void findClientById() throws Exception {  
  18.   
  19.         ClientDao clientDao = new ClientDaoImp(sqlSessionFactory);  
  20.         FClient c = clientDao.findClientById(1);  
  21.         System.out.println(c);  
  22.     }  
  23.   
  24. }  

 

 

    (4)原始的dao層遇到的問題

 

             1)dao接口實現類方法中存在大量的模板方法,設想可否將這些代碼提取出來
     2)調用sqlsession方法的時候將statement存在硬編碼
     3)調用sqlsession的方法的時候,傳入參數爲Object 類型,及時傳入錯誤,也不會報錯

 

3.使用Mapper代理的方式實現

      基本步驟爲 :   

             1)編寫mapper.xml映射文件 

             2)編寫Mapper接口,至關於dao接口 

             3)mybatis能夠自動生成mapper接口的實現類代理對象

    (1)實現Mapper映射文件

              mapper.xml 規範 :
 1)namespace 等於mapper接口地址
 2)mapper.Java 接口中的方法和mapper.xml中的statement 的id一致
 3)mapper.java 接口中的方法的參數和mapper.xml中的statement 的paramterType類型一致
 4)mapper.java 接口中的方法的返回值和mapper.xml中的statement的resultType類型一致
 
總結 :mapper.xml實現的規範,就是對SqlSession接口中的方法進行統一的生成

       好比 :

 

[html]  view plain  copy
 
  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.   
  6. <!-- namespace命名空間,做用就是對sql進行分類化管理,理解sql隔離 -->  
  7. <!-- 注意:使用mapper代理的方法開發,namespace有特殊的重要做用,namespace爲mapper接口的地址 -->  
  8.   
  9. <mapper namespace="mybatie.mapper.ClientMapper">  
  10.   
  11.     <!-- 在映射文件中配置不少的sql語句 -->  
  12.     <!-- 經過select 執行數據庫查詢 id:表示映射文件的sql, 將sql語句封裝到mappedStatement對象中,因此將id稱爲statement的id   
  13.         #{}: 表示一個佔位符,至關於jdbc中的? parameterType : 指定參數類型,好比指定爲int #{id} : 其中的id表示接入輸入的參數,參數名稱就是id,若是輸入的參數是簡單類型   
  14.         #{}中參數名能夠任意,能夠value或其餘名稱; resultType :指定sql輸出的結果的映射java對象類型,select指定的resultType表示將單條記錄映射成java對象 -->  
  15.     <!-- 根據id查用戶 -->  
  16.     <select id="findClientById" parameterType="int" resultType="mybatis.po.FClient">  
  17.         select * from f_client where id=#{id}  
  18.     </select>  
  19.   
  20.     <!-- 根據用戶名模糊查詢 resultType :指定的單條記錄所映射的java對象類型 #{} 表示佔位符 ${}:表示拼接sql串,將接收到的參數內容不加任何修飾拼接在sql中,使用${}拼接,引發sql注入   
  21.         ${value} :接入輸入參數的內容,若是傳入類型是簡單類型,${}簡單的 -->  
  22.     <select id="findClientByName" parameterType="java.lang.String"  
  23.         resultType="mybatis.po.FClient">  
  24.         select *from f_client where username like '%${value}%'  
  25.     </select>  
  26.   
  27.     <!-- 添加用戶 這裏注意 主鍵返回實現 -->  
  28.     <select id="insertClient" parameterType="mybatis.po.FClient"  
  29.         resultType="java.lang.Integer">  
  30.         insert into  
  31.         f_client(id,username,client_certificate_no,born_date,family_register_address,now_address,contact_mode,urgency_contact_mode,create_date)  
  32.         values (#{id},  
  33.         #{username},#{client_certificate_no},#{born_date},#{family_register_address},#{now_address},#{contact_mode},#{urgency_contact_mode},#{create_data})  
  34.     </select>  
  35.   
  36.     <!-- 刪除用戶 -->  
  37.     <delete id="deleteClient" parameterType="int">  
  38.         delete from f_client where id=#{id}  
  39.     </delete>  
  40.   
  41.     <!-- 更新用戶 -->  
  42.     <update id="updateClient" parameterType="mybatis.po.FClient">  
  43.   
  44.         update f_client set  
  45.         username=#{username},client_certificate_no=#{client_certificate_no},born_date=#{born_date},family_register_address=#{family_register_address},now_address=#{now_address},contact_mode=#{contact_mode},urgency_contact_mode=#{urgency_contact_mode}  
  46.         where id=#{id}  
  47.   
  48.     </update>  
  49.   
  50.   
  51. </mapper>  



 

   (2)mapper接口

               注意接口定義的和Mapper.xml對比下,看看mapper.xml的 規範!!

 

[java]  view plain  copy
 
  1. package mybatie.mapper;  
  2.   
  3. import java.util.List;  
  4.   
  5. import mybatis.po.FClient;  
  6.   
  7.   
  8. /** 
  9.  * mapper接口 ,對應Clientmapper.xml 
  10.  * 做者:原明卓 
  11.  * 時間:2015年12月21日 上午10:00:00 
  12.  * 描述:TODO 
  13.  */  
  14. public interface ClientMapper {  
  15.       
  16.     public FClient findClientById(int id) throws Exception;  
  17.       
  18.     public void updateClient(FClient f)  throws Exception;  
  19.       
  20.     public void deleteClient(int id) throws Exception;  
  21.   
  22.     public int insertClient(FClient f) throws Exception;  
  23.       
  24.     public List<FClient> findClientByName(String name) throws Exception;  
  25. }  

 

 

      (3)測試

 

 

[java]  view plain  copy
 
  1. private SqlSessionFactory sqlfactory;  
  2.   
  3. @Before  
  4. public void setUp() throws Exception {  
  5.     InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");  
  6.     sqlfactory=new SqlSessionFactoryBuilder().build(is);  
  7. }  
  8.   
  9. @Test  
  10. public void testFindClientById() throws Exception {  
  11.     SqlSession session = sqlfactory.openSession();  
  12.     ClientMapper mapper = session.getMapper(ClientMapper.class);  
  13.     FClient fc = mapper.findClientById(1);  
  14.     System.out.println(fc);  
  15.     session.close();  
  16. }  



 

 

4.一些問題

       (1)代理對象內部調用selectOne或 selectList 若是mapper方法返回單個pojo對象,代理對象內部經過selectOne查詢數據庫; 若是mapper方法返回集合對象,代理對象內部經過內部經過selectList查詢數據庫; 不然會報錯誤。        (2) mapper接口方法參數只能有一個是否影響系統開發  系統框架中,dao層的代碼是不是被業務層公用的,即便mapper接口只有一個參數,可使用包裝 類型pojo知足不一樣業務方法需求;  注意:持久層方法的參數能夠包裝類型,map,service方法中建議不要使用包裝類型,由於不利於 業務層的可擴展性。

相關文章
相關標籤/搜索