zoukankan      html  css  js  c++  java
  • Mybatis 增删改查之dao层实现

    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方法中建议不要使用包装类型,因为不利于
     业务层的可扩展性。

    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方法中建议不要使用包装类型,因为不利于
     业务层的可扩展性。

  • 相关阅读:
    python 中的subprocess
    Pandas 的基本操作
    mongodb的基本操作
    Mongodb的安装
    Mysql has gone way (Django 下的解决方法)
    python 中的魔法类
    python2与python3共存时的pip问题
    Tango with django 1.9 中文——3.Django基础
    bootstrap日期范围选择插件daterangepicker详细使用方法
    Django Static与Media
  • 原文地址:https://www.cnblogs.com/wangf-keep/p/6425633.html
Copyright © 2011-2022 走看看