mybatis--原始dao和代理Mapper
来源:互联网 发布:vb能做到人脸识别吗 编辑:程序博客网 时间:2024/05/23 11:35
上一篇博客我们讲了对于mybatis的增删改,但是我们看上篇的博客,几乎每一个方法都会出现创建工厂,创建会话,关闭绘画,关闭事务等操作。那么今天我们就来封装一下,用接口实现一下mybatis的增删改查。
原始dao
原始的dao,我们需要dao接口和dao的实现类,代码如下:
dao接口
/** * 用户管理 * @author mengh * */public interface UserDao { //根据id查询 public User findUserById(int id) throws Exception; public void insertUser(User user) throws Exception; public void deleteUser(int id) throws Exception;}
dao实现类
public class UserDaoImpl implements UserDao { //需要向dao实现类注入SqlSessionFactory //这里通过构造函数注入 private SqlSessionFactory sqlSessionFactory; public UserDaoImpl(SqlSessionFactory sqlSessionFactory){ this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById", id); sqlSession.close(); return user; } @Override public void insertUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.insert("test.insertUser", user); sqlSession.commit(); sqlSession.close(); } @Override public void deleteUser(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.delete("test.deleteUser", id); sqlSession.commit(); sqlSession.close(); }
User.xml
<mapper namespace="test"> <!-- 在映射文件中配置很多的sql --> <!-- 需求: 通过id,查询数据库的记录 --> <!-- 通过select执行数据库查询 id:表示映射文件的sql,称为statement的id 将来sql语句会封装到mappedstate的对象中 #{}表示一个占位符 parameterType="" 指定输入的类型,这里指定int #{id}:其中的id标志输入的参数,参数的名称就是id,如果输入的参数是简单类型,#{}中的参数名称可以是任意类型 resultType="" 置顶输出查询的结果的所映射的java对象,这里select置顶resultType表示将单条记录所映射的java对象 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM USER WHERE ID=#{id} </select> <!-- 根据用户名模糊查询用户信息,可能返回多条记录 resultType:指定的就是单挑记录锁映射的java对象类型 ${}表示拼接字符串,将接收的内容,不加任何修饰的凭借到sql中 使用${}凭借sql,会引起sql注入 ${}:接受输入的内容,如果传入的是简单类型,${}只能使用value --> <select id="findUserByName" parameterType="String" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM USER WHERE USERNAME LIKE '%${value}%' </select> <!-- 添加用户 parameterType:指定输入的参数类型(包括用户信息) #{}中指定pojo的属性名,接受到pojo对象的属性值 mybatis也是通过OGNL来获取属性的值 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" ><!-- select LAST_INSERT_ID() :得到刚刚在insert进去记录的主键值,值适用于自增列 --><!-- keyProperty:将查询到的主键值设置到parameterType置顶的对象的哪个属性 --><!-- order="AFTER":select LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序 --><!-- resultType:指定结果的类型 --> <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="java.lang.Integer"> delete from user where id=#{id} </delete> <!-- 更新用户 需要用户的id和用户信息 #{id}:从传入的user实体中获取对应属性的值 --> <update id="updateUser" parameterType="cn.itcast.mybatis.po.User"> update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update></mapper>
客户端
@Override public void deleteUser(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.delete("test.deleteUser", id); sqlSession.commit(); sqlSession.close(); }
原声dao缺点
这样我们的做法就写好了,当然这只是传统的做法,虽然比上一篇博客每次都要去实现一下工厂好多了,但是还是有很多的缺点,如下:
1.存在大量的重复代码,可以提取出来,也就是用模板方法。
2.调用sqlSession方法时,将statement硬编码了
3.调用sqlSession方法的时候,由于Session方法使用泛型,即变量类型传入错误,在编译阶段也不报错,不利于发现错误。
Mapper代理
针对上边的不足,mybatis做了一些相应的政策,就是我们说的mapper代理,而且针对mybatis的代理,我们还需要在mapper.xml和接口上加一些规范。
1.在mapper.xml中namespace中编写Mapper接口的地址
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
2.mapper.java接口中的方法名称和mapper.xml总的statement的id一直
3.接口中的方法的输入参数类型和mapper.xml中的statement的parameterType的类型一直
4.mapper.java中的返回值的类型和映射文件中的resultType的类型一致
以上开发规范总要对下边的代码统一的
<!-- 改进前 --><mapper namespace="cn.itcast.mybatis.mapper.UserMapper"><!-- 改进后 --><mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
改进以后就是我们的mapper.xml,代码如下:
UserMapper.xml
<!-- 命名空间,作用:对sql进行分类话的管理,sql的隔离 注意,如果使用mapper代理开发,他代表mapper接口的地址--><mapper namespace="cn.itcast.mybatis.mapper.UserMapper"> <!-- 在映射文件中配置很多的sql --> <!-- 需求: 通过id,查询数据库的记录 --> <!-- 通过select执行数据库查询 id:表示映射文件的sql,称为statement的id 将来sql语句会封装到mappedstate的对象中 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM USER WHERE ID=#{id} </select> <select id="findUserByName" parameterType="String" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM USER WHERE USERNAME LIKE '%${value}%' </select> <insert id="insertUser" parameterType="cn.itcast.mybatis.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="java.lang.Integer"> delete from user where id=#{id} </delete> <!-- 更新用户 需要用户的id和用户信息 #{id}:从传入的user实体中获取对应属性的值 --> <update id="updateUser" parameterType="cn.itcast.mybatis.po.User"> update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update>
Mapper接口
//根据id查询用户 public User findUserById(int id) throws Exception; //根据用户名查询用户信息 public List<User> findUserByName(String name) throws Exception;// public void insertUser(User user) throws Exception;// public void deleteUser(int id) throws Exception;
你以为这样写就完了吗,确实完了,哈哈。而且这样写的好处就是我们不用写实现类,mapper代理会根据我们的statement来选择到底调用什么方法,例如我们的是Insert,那么他就会调用insert。
客户端
@Test public void test() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(1); System.out.println(user); }
SqlSession
Sqlsession对应着一次数据库会话。由于数据库回话不是永久的,因此Sqlsession的生命周期也不应该是永久的,相反,在你每次访问数据库时都需要创建它(当然并不是说在Sqlsession里只能执行一次sql,你可以执行多次,当一旦关闭了Sqlsession就需要重新创建它)。创建Sqlsession的地方只有一个,那就是SqlsessionFactory的openSession方法。
注意:
这里我们有的方法是查询一个用户,当然也有可能查询出来的是多个用户,没关系,如果我们这个方法查询出来的是多个实体,那么mybaits会自动让让我们的代理类实现selectList()方法,且返回值是List,如果是返回单个实体,则返回User。
小结
针对原始的jdbc和传统的dao的实现,mybaits还是做了非常大的优化的,他让我们真正的面向接口来编程,让我们的代码量减少,让我们的工作能更好的运用在业务上,还真是做到了全心全意为人民服务。
- mybatis--原始dao和代理Mapper
- mybatis--开发Dao--原始dao方式和Mapper代理方式
- mybatis 原始dao开发和mapper代理开发的比较
- Mybatis和Spring整合(原始Dao)非mapper代理
- MyBatis 原始dao与mapper代理
- 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发
- 【Spring+SpringMVC+MyBatis深入学习及搭建】02.MyBatis原始Dao开发和mapper代理开发
- Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合
- Mybatis中mapper代理方法替换原始Dao开发方法
- mybatis入门基础(二)----原始dao的开发和mapper代理开发------------转载
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
- Mybatis入门基础(二)--原始dao的开发和mapper代理开发
- 深入浅出mybatis中原始dao的开发和mapper代理开发
- 原始dao和Mapper动态代理的开放方式---Mybatis学习笔记(六)
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
- spring整合mybatis(原始dao和mapper代理两种方式)
- 深入浅出mybatis中原始dao的开发和mapper代理开发
- HDU 1260 Tickets (简单DP)
- [LeetCode]318. Maximum Product of Word Lengths
- 3876: [Ahoi2014]支线剧情 有上下界的费用流
- 初等数论四大定理之——费马小定理
- spring的aop 基于schema
- mybatis--原始dao和代理Mapper
- D-Professor GukiZ's Robot
- 链表排序
- 线程的取消/撤销
- linux内核权限控制之vfs_permission分析
- 第23讲项目3——两段函数求值
- Linux调优常用命令
- 数据库索引
- java 反射