【MyBatis框架】Mybatis开发dao方法第一部分

来源:互联网 发布:淘宝爆款计划表 编辑:程序博客网 时间:2024/06/04 19:34
下面来讨论mybatis开发Dao的方法

先来说一下基本架构流程中使用到的几个类
1.SqlSession使用范围

1.1SqlSessionFactoryBuilder
 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。
在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

1.2SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。

将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。

1.3SqlSession
SqlSession是一个面向用户(程序员)的接口。
SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。

SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

SqlSession最佳应用场合在方法体内,定义成局部变量使用。

接下来就来说说MyBatis的Dao的写法,分为两种,一种是原始Dao开发方法,一种是mapper代理方法,我们下面一一讨论:

2.原始dao开发方法(程序员需要写dao接口和dao实现类)

2.1思路:程序员需要写dao接口和dao实现类。
需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession。

下面实现Dao的场景是基于之前对用户数据进行增删改查的需求。

先建立一个config源包,包里创建一个User.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">


<!-- namespace命名空间,为了对sql语句进行隔离,方便管理 ,mapper开发dao方式,使用namespace有特殊作用 -->
<mapper namespace="test">
<!-- 在mapper.xml文件中配置很多的sql语句,执行每个sql语句时,封装为MappedStatement对象
mapper.xml以statement为单位管理sql语句
 -->
 
  <!-- 根据id查询用户信息 -->
<!-- 
id:唯一标识 一个statement
#{}:表示 一个占位符,如果#{}中传入简单类型的参数,#{}中的名称随意
parameterType:输入 参数的类型,通过#{}接收parameterType输入 的参数
resultType:输出结果 类型,不管返回是多条还是单条,指定单条记录映射的pojo类型
-->
 <select id="findById" parameterType="int" resultType="cn.edu.hpu.mybatis.po.User">
  select * from user where id = #{id}
 </select>
 
<!-- 根据用户名称查询用户信息,可能返回多条
${}:表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。
-->
 <select id="findByName" parameterType="java.lang.String" resultType="cn.edu.hpu.mybatis.po.User">
  select * from user where username like '%${value}%'
 </select>
 
  <!-- 添加用户
  parameterType:输入 参数的类型,User对象 包括 username,birthday,sex,address
  #{}接收pojo数据,可以使用OGNL解析出pojo的属性值
#{username}表示从parameterType中获取pojo的属性值 
  selectKey:用于进行主键返回,定义了获取主键值的sql
order:设置selectKey中sql执行的顺序,相对于insert语句来说
keyProperty:将主键值设置到哪个属性
resultType:select LAST_INSERT_ID()的结果 类型
  -->
 <insert id="insertUser" parameterType="cn.edu.hpu.mybatis.po.User">
  <selectKey keyProperty="id" order="AFTER" resultType="int">
  select LAST_INSERT_ID()
  </selectKey>
  insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
 </insert>
 
 <!-- mysql的uuid生成主键 -->
<!-- <insert id="insertUser" parameterType="cn.edu.hpu.mybatis.po.User">
<selectKey keyProperty="id" order="BEFORE" resultType="string">
select uuid()
</selectKey>

INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
 -->
 
 <!-- oracle
在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性
-->
<!-- <insert id="insertUser" parameterType="cn.edu.hpu.mybatis.po.User">
<selectKey keyProperty="id" order="BEFORE" resultType="int">
select 序列.nextval() from dual
</selectKey>

INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert> -->

<!-- 删除 -->
  <delete id="deleteUser" parameterType="int">
  delete from user where id = #{id}
  </delete>
 
  <!-- 更新 -->
<update id="updateUser" parameterType="cn.edu.hpu.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id = #{id}
</update>
 
</mapper>

2.2写Dao接口

[java] view plain copy
  1. package cn.edu.hpu.mybatis.dao;  
  2.   
  3. import cn.edu.hpu.mybatis.PO.User;  
  4.   
  5. //用户管理的Dao接口  
  6. public interface UserDao {  
  7.       
  8.     //根据Id查询用户信息  
  9.     public User findUserById(int id) throws Exception;  
  10.       
  11.     //添加用户信息  
  12.     public void insertUser(User user) throws Exception;  
  13.       
  14.     //删除用户信息  
  15.     public void deleteUser(int id) throws Exception;  
  16.       
  17.     //修改用户信息  
  18.     public void updateUser(User user) throws Exception;  
  19. }  

2.3写Dao的实现

[java] view plain copy
  1. package cn.edu.hpu.mybatis.dao;  
  2.   
  3. import org.apache.ibatis.session.SqlSession;  
  4. import org.apache.ibatis.session.SqlSessionFactory;  
  5.   
  6. import cn.edu.hpu.mybatis.PO.User;  
  7.   
  8. public class UserDaoImpl implements UserDao{  
  9.   
  10.     //需要向dao实现类中注入SqlSessionFactory工厂  
  11.     //这里我们暂时没用spring,我们通过构造方法注入  
  12.     private SqlSessionFactory sqlSessionFactory;  
  13.     public UserDaoImpl(SqlSessionFactory sqlSessionFactory){  
  14.         this.sqlSessionFactory=sqlSessionFactory;  
  15.     }  
  16.       
  17.     @Override  
  18.     public void deleteUser(int id) throws Exception {  
  19.           
  20.         SqlSession sqlSession=sqlSessionFactory.openSession();  
  21.           
  22.         //传入id删除用户  
  23.         sqlSession.delete("test.deleteUser",id);  
  24.           
  25.         //提交事务  
  26.         sqlSession.commit();  
  27.           
  28.         sqlSession.close();  
  29.     }  
  30.   
  31.   
  32.     @Override  
  33.     public User findUserById(int id) throws Exception {  
  34.         SqlSession sqlSession=sqlSessionFactory.openSession();  
  35.           
  36.         User user=sqlSession.selectOne("test.findUserById",id);  
  37.           
  38.         //释放资源  
  39.         sqlSession.close();  
  40.         return user;  
  41.     }  
  42.   
  43.   
  44.     @Override  
  45.     public void insertUser(User user) throws Exception {  
  46.           
  47.         SqlSession sqlSession=sqlSessionFactory.openSession();  
  48.           
  49.         sqlSession.insert("test.insertUser",user);  
  50.           
  51.         //提交事务  
  52.         sqlSession.commit();  
  53.           
  54.         //释放资源  
  55.         sqlSession.close();  
  56.           
  57.     }  
  58.   
  59.   
  60.     @Override  
  61.     public void updateUser(User user) throws Exception {  
  62.           
  63.         SqlSession sqlSession=sqlSessionFactory.openSession();  
  64.           
  65.         sqlSession.update("test.updateUser",user);  
  66.           
  67.         //提交事务  
  68.         sqlSession.commit();  
  69.           
  70.         sqlSession.close();  
  71.           
  72.     }  
  73.   
  74.   
  75. }  
测试方法(这里只测试findUserBiId方法):
[java] view plain copy
  1. package cn.edu.hpu.mybatis.test;  
  2.   
  3. import java.io.InputStream;  
  4.   
  5. import org.apache.ibatis.io.Resources;  
  6. import org.apache.ibatis.session.SqlSessionFactory;  
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
  8. import org.junit.Before;  
  9. import org.junit.Test;  
  10.   
  11.   
  12. import cn.edu.hpu.mybatis.PO.User;  
  13. import cn.edu.hpu.mybatis.dao.UserDao;  
  14. import cn.edu.hpu.mybatis.dao.UserDaoImpl;  
  15.   
  16.   
  17. public class UserDaoImplTest {  
  18.   
  19.   
  20.     private SqlSessionFactory sqlSessionFactory;  
  21.       
  22.     //注解Before是在执行本类所有测试方法之前先调用这个方法  
  23.     @Before  
  24.     public void setup() throws Exception{  
  25.         //创建SqlSessionFactory  
  26.         String resource="SqlMapConfig.xml";  
  27.           
  28.         //将配置文件加载成流  
  29.         InputStream inputStream = Resources.getResourceAsStream(resource);  
  30.         //创建会话工厂,传入mybatis配置文件的信息  
  31.         sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);  
  32.     }  
  33.       
  34.     @Test  
  35.     public void testFindUserById() throws Exception{  
  36.           
  37.         //创建Dao对象  
  38.         UserDao userDao=new UserDaoImpl(sqlSessionFactory);  
  39.           
  40.         //调用UserDao的方法  
  41.         User user=userDao.findUserById(1);  
  42.           
  43.         System.out.println(user.getUsername());  
  44.           
  45.     }  
  46.       
  47. }  

测试结果:
张三

输出的日志:

  1. DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.  
  2. DEBUG [main] - PooledDataSource forcefully closed/removed all connections.  
  3. DEBUG [main] - PooledDataSource forcefully closed/removed all connections.  
  4. DEBUG [main] - PooledDataSource forcefully closed/removed all connections.  
  5. DEBUG [main] - PooledDataSource forcefully closed/removed all connections.  
  6. DEBUG [main] - Opening JDBC Connection  
  7. DEBUG [main] - Created connection 28970806.  
  8. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1ba0f36]  
  9. DEBUG [main] - ==>  Preparing: SELECT * FROM USER WHERE id=?   
  10. DEBUG [main] - ==> Parameters: 1(Integer)  
  11. DEBUG [main] - <==      Total: 1  
  12. DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@1ba0f36]  
  13. DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.Connection@1ba0f36]  
  14. DEBUG [main] - Returned connection 28970806 to pool.  

2.4总结原始 dao开发问题
1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

2、调用sqlsession方法时将statement的id硬编码了

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

下一篇总结我们来使用mapper代理方法来写Dao,来解决上面我们发现的问题。


源:http://blog.csdn.net/acmman/article/details/46455507


1 0
原创粉丝点击