mybatis入门(三)——Mapper代理开发替代传统DAO层开发

来源:互联网 发布:java 线程是什么 编辑:程序博客网 时间:2024/05/21 11:27
前言

    mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性;传统的dao层开发容易出现硬编码的问题。下面我们了解一下这两种编码方式:

- 传统DAO层开发:

User.xml:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 此处namespace无特殊的意义 --><mapper namespace="test">   <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">     SELECT * FROM user WHERE id=#{id}   </select>  <select id="findUserByName" parameterType="java.lang.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>  <!-- 删除数据 -->  <delete id="deleteUser" parameterType="java.lang.Integer">      delete from user where id=#{id}  </delete>  <!-- 更新数据 -->  <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>
  • Dao的接口类:UserDao:
package cn.itcast.mybatis.dao;import java.security.PublicKey;import cn.itcast.mybatis.po.User;/** *  * @InterfaceName: UserDao  * @Description: TODO(用户管理接口) * @author 常银玲 * @date 2017年9月26日17:09:36 *  */public interface UserDao {    /**     *根据id进行查询     * @param id     * @return     * @throws Exception     */    public User findUserById(int id)throws Exception;    /**     * 添加用户     * @param user     * @throws Exception     */    public void insertUser(User user)throws Exception;    /**     * 根据id进行删除     * @param id     * @throws Exception     */    public void deleteUser(int id) throws Exception;}

Dao实现类:UserDaoImp1

package com.mybatis.dao;import java.util.List;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import com.mybatis.entity.User;/** *  * @ClassName: UserDaoImpl * @Description: TODO(用户管理接口的实现类) * @author 常银玲 * @date 2017年9月26日17:09:36 *  */public class UserDaoImpl implements UserDAO {    private SqlSessionFactory sqlSessionFactory;    // 需要向dao实现类中注入SqlSessionFactory    // 通过构造方法注入    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {        this.sqlSessionFactory = sqlSessionFactory;    }    @Override    public User findUserById(Integer id) {        SqlSession sqlSession = sqlSessionFactory.openSession();        User user = sqlSession.selectOne("test.findUserById", id);        // 释放资源        sqlSession.close();        return user;    }    @Override    public List<User> findUserByName(String username) {        SqlSession sqlSession = sqlSessionFactory.openSession();        List<User> list = sqlSession                .selectList("test.findUserByName", username);        // 提交事务        sqlSession.commit();        // 释放资源        sqlSession.close();        return list;    }    @Override    public void insertUser(User user) {        SqlSession sqlSession = sqlSessionFactory.openSession();        // 执行插入操作        sqlSession.insert("test.insertUser", user);        // 提交事务        sqlSession.commit();        // 释放资源        sqlSession.close();    }    @Override    public void deleteUser(Integer id) {        SqlSession sqlSession = sqlSessionFactory.openSession();        // 执行插入操作        sqlSession.delete("test.deleteUser", id);        // 提交事务        sqlSession.commit();        // 释放资源        sqlSession.close();    }    @Override    public void updateUser(User user) {        SqlSession sqlSession = sqlSessionFactory.openSession();        // 执行插入操作        sqlSession.update("test.updateUser", user);        // 提交事务        sqlSession.commit();        // 释放资源        sqlSession.close();    }}
  • Junit测试:
package cn.itcast.mybatis.dao;import static org.junit.Assert.*;import java.io.InputStream;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import cn.itcast.mybatis.po.User;/** *  * @ClassName: UserDaoImp1Test  * @Description: 用户管理接口的测试类 * @author 常银玲 * @date 2017年9月26日17:09:36 *  */public class UserDaoImp1Test {    private SqlSessionFactory sqlsessionfactory;    @Before    public void setUp()throws Exception{        String resource="SqlMapConfig.xml";        InputStream inputStream=Resources.getResourceAsStream(resource);            //创建会话工厂        sqlsessionfactory=new SqlSessionFactoryBuilder().build(inputStream);        //SqlSession sqlSession=sqlSessionFactory.openSession();    }/***测试根据id查询的方法;这里只举例一个*/    @Test    public void testFindUserById() throws Exception {        //创建一个userDao的对象        UserDao userDao=new UserDaoImp1(sqlsessionfactory);        User user=userDao.findUserById(1);        System.out.println(user);    }}


mybatis传统DAO层开发存在的问题:
1.dao接口中存在大量模版方法,增加工作量。

2.调用sqlSession方法时将statement的id硬编码了

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

二:mapper代理开发Mapper接口:
mapper代理开发和传统开发主要的区别在于

1. 接口不用实现
2. mapper文件的namespace有意义,必须与mapper接口类路径一致。
3. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
4. mapper接口方法名的输入和输出参数必须和mapper.xml中定义的类型一致。

代码如下:

  • 新建UserMapper.xml:关注namespace
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- mapper代码,namespace有特殊的意义 --><mapper namespace="cn.itcast.mybatis.mapper.UserMapper">   <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">     SELECT * FROM user WHERE id=#{id}   </select></mapper>
  • 配置SqlMapConfig.xml
<mapper resource="mapper/UserMapper.xml"/>
  • mapper代理接口:UserMapper.java(关注mapper.xml中方法名,输出和输入参数类型)
```package cn.itcast.mybatis.dao;import cn.itcast.mybatis.po.User;/** *  * @InterfaceName: UserMapper  * @Description: TODO(用户管理接口) * @author 常银玲 * @date 2017年9月26日17:09:36 *  */public interface UserMapper{    /**     *根据id进行查询     * @param id     * @return     * @throws Exception     */    public User findUserById(int id)throws Exception;}

junit测试类:

package cn.itcast.mybatis.mapper;import static org.junit.Assert.*;import java.io.IOException;import java.io.InputStream;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import cn.itcast.mybatis.po.User;public class UserMapperTest {    private SqlSessionFactory sqlsessionfactory;  @Before  public void setUp() throws IOException{      String resource="SqlMapConfig.xml";    InputStream inputStream=Resources.getResourceAsStream(resource);    /**    * 创建SqlSessionFcatory    */    sqlsessionfactory=new SqlSessionFactoryBuilder().build(inputStream);  }    @Test    public void test() {       SqlSession sqlSession=sqlsessionfactory.openSession();        // 创建Usermapper对象,mybatis自动生成mapper代理对象       UserMapper userMapper=sqlSession.getMapper(UserMapper.class);       User user=userMapper.findUserById(1);       System.out.println(user);    }}

其实学习完mapper代理开发之后,可能你还存在一个疑问,就是返回的结果如果是list,代理内部会怎么判断?

  • 代理内部会自动判断,如果返回list那么就调用sqlsession的selectlist方法,如果是对象,就调用sqlsession的selectone方法。
结语:

mapper代理开发接口不用写实现类,节省了我们的代码量;mapper代理对象减少了我们的硬编码,使编码更加灵活。

阅读全文
0 0
原创粉丝点击