mybatis(7)--使用mapper代理开发代替原始的dao开发

原创 2017年07月17日 17:26:06

在原始的dao中我们发现了很多问题,而mapper代理开发则会帮我们解决这些问题。
具体思路:
1.需要编写映射文件mapper.xml
2.使用mapper接口来代替dao接口
3.mybatis会自动实现mapper接口的代理类对象
how?
mapper接口是有一定的编写规范,mybatis根据这些规范动态的使用反射获取方法名方法参数等,从而实现mapper的代理

首先来看mapper.xml,不难看出,它和之前的user.xml
几乎是一样的,只是这个namespace不一样,以前的是test,所以我们调用的时候便只能硬编码调用。那么现在,他把这个sql的调用写成一个类,里面的方法遵循一定的规范,根据这种规范,去实现其代理。

<?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" >
<!-- mapper.xml的namespace需要和mapper的接口地址一致 -->
<mapper namespace="com.ddd.mybatis.mapper ">

    <select id="findUserById" parameterType="int"
        resultType="com.ddd.mybatis.pojo.User">
        SELECT * FROM USER WHERE id=#{id}
    </select>

    <select id="findUserByName" parameterType="java.lang.String"
        resultType="com.ddd.mybatis.pojo.User">
        SELECT * FROM USER WHERE username LIKE '%${value}%'
    </select>

    <insert id="insertUser" parameterType="com.ddd.mybatis.pojo.User">

        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT
            LAST_INSERT_ID()
        </selectKey>

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


    <delete id="deleteUserById" parameterType="java.lang.Integer">
        DELETE FROM USER WHERE
        id=#{id}
    </delete>


    <update id="updateUser" parameterType="com.ddd.mybatis.pojo.User">
        UPDATE USER SET
        username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
        WHERE id=#{id}
    </update>
</mapper>

再看mapper.java是怎么写的:

package com.ddd.mybatis.mapper;

import java.util.List;

import com.ddd.mybatis.pojo.User;

/**
 * 使用mapper接口相当于dao接口
 * 
 * @author Dan
 * mapper.xml的namespace需要和mapper.java的接口地址一致
 *mapper.java中的方法的方法名要和mapper.xml中的statement的id一致
 *输入参数要和mapper.xml中的statement的parameterType指定类型一致
 *方法的返回值要和mapper.xml中的statement的resultType指定类型一致
 */
public interface UserMapper {

    // 根据id查询一个user
    public User findUserById(int id);
    //根据名字查询user
    public List<User> findUserByName(String name);
    // 添加用户
    public void insertUser(User u);

    // 删除用户
    public void deleteUserById(int id);

    // 更新用户
    public void updateUser(User u);

}

根据这四个规范,我们可以看出,方法名字,sql的id名字,输入输出类型的限制,可以使用Method.class.getDeclaredMethod(name, parameterTypes)来获取到一个方法,在这方法的前后加入sqlSession的创建提交等,这很明显我们可以使用动态代理。

接下来测试:(记得要将userMapper.xml加入到sqlMapConfig.xml中)

package com.ddd.mybatis.mapperTest;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.ddd.mybatis.mapper.UserMapper;
import com.ddd.mybatis.pojo.User;

public class UserMapperTest {
    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void setUp() throws IOException{
        String fileSource="SqlMapConfig.xml";
        //获取文件流
        InputStream inputStream=Resources.getResourceAsStream(fileSource);
        //根据加载的配置文件信息创建SqlSessionFactory
        sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindUserById() {
        //由于之前是在UserDaoImpl中每次获取sqlSession,所以这里需要我们手动写
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //mybatis自动生成mapper代理对象,代理对象内部调用selectOne或者selectList
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //调用userMapper的方法
        User u=userMapper.findUserById(1);
        System.out.println(u);
    }
    @Test
    public void testFindUserByName() {
        //由于之前是在UserDaoImpl中每次获取sqlSession,所以这里需要我们手动写
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //mybatis自动生成mapper代理对象,代理对象内部调用selectOne或者selectList
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //调用userMapper的方法,返回集合,但这里如果不小心用一个单个user来接收,那会报错
        List<User> list=userMapper.findUserByName("小明");
        System.out.println(list);
    }
}

问题总结:

mapper的方法是依据parameterType来写,而它只能有一个,这是否会影响我们扩展维护呢?

在我们的系统框架中,dao层的代码是被业务层调用的,即使mapper接口的方法只有一个参数,可以使用包装类型的pojo满足不同的业务方法需求
ps:持久层方法中参数可以是包装类型,例如map等,但service中不建议使用包装类型,因为service是被各种各样的前台服务调用的,而前台并不知道你这个map中究竟有多少对象,这样不利于业务层的可扩展。

版权声明:本文为博主原创文章,未经博主允许不得转载。

目前流行框架的一些替代技术

1. jsp、servlet、javabean的替代技术:     jsp和servlet完全同意,底层运行机制完全一致,jsp必须被web服务器编译成servlet,在服务器真正运行的事servl...
  • IT_lollipop
  • IT_lollipop
  • 2016年11月14日 09:16
  • 2452

Mybatis Mapper动态代理方法 即 只写Dao接口 不写Dao的实现类

Mapper动态代理方法:程序员只需要写dao接口(Mapper),而不需要写dao实现类,由mybatis根据dao接口和映射文件中statement的定义生成接口实现代理对象。可以调用代理对象方法...
  • u010924894
  • u010924894
  • 2016年09月13日 09:53
  • 4747

mybatis--原始dao和代理Mapper

上一篇博客我们讲了对于mybatis的增删改,但是我们看上篇的博客,几乎每一个方法都会出现创建工厂,创建会话,关闭绘画,关闭事务等操作。那么今天我们讲一下mybatis的mapper的代理,让我们更好...
  • lovemenghaibin
  • lovemenghaibin
  • 2016年03月06日 09:25
  • 1293

Mybatis总结(二):开发Dao的方式和Mapper的方式

1.SqlSession使用范围 1.1 SqlSessionFactoryBuilder  通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory ...
  • u014206695
  • u014206695
  • 2017年03月13日 20:37
  • 320

MyBatis 实践 -Mapper与DAO

MyBatis 实践  -Mapper与DAO标签: Java与存储MyBatis简介MyBatis前身是iBatis,是一个基于Java的数据持久层/对象关系映射(ORM)框架. MyBati...
  • hanqing280441589
  • hanqing280441589
  • 2016年02月28日 15:34
  • 18989

spring整合mybatis(原始dao和mapper代理两种方式)

一.原始Dao方式 1.引入jar包(maven文件和下面的Mapper代理方式一样) 2.applicationContext.xml ...
  • gwd1154978352
  • gwd1154978352
  • 2017年04月02日 21:26
  • 1032

【持久化框架】Mybatis与Hibernate的详细对比

这篇博文我们重点分析一下Mybatis与Hibernate的区别
  • jiuqiyuliang
  • jiuqiyuliang
  • 2015年05月01日 14:20
  • 76991

Spring+MYBatis企业应用实战pdf

下载地址:网盘下载 内容提要 编辑 《Spring+MyBatis企业应用实战》介绍了Java EE 领域的两个开源框架:Spring 的MVC 和MyBatis。其中Spring 的...
  • cf406061841
  • cf406061841
  • 2017年08月30日 22:37
  • 2112

【MyBatis学习04】mapper代理方法开发dao

上一篇博文总结了mybatis使用 原始dao的方法存在的一些弊端,我们肯定不会去用它,那么mybatis中该如何开发dao呢?如题所述,这篇博文主要来总结一下使用mapper代理的方法来开发dao的...
  • eson_15
  • eson_15
  • 2016年06月11日 19:20
  • 8917

mybatis教程--原始方式和mapper方式开发dao详解

mybatis开发dao的两种方式 一、原始的dao开发方式 所谓的原始的dao的开发方式,其实就是和hibernate的开发方式类似的,需要dao的接口和dao的实现类,这个就是原始的开发方式...
  • sihai12345
  • sihai12345
  • 2017年04月21日 11:03
  • 681
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:mybatis(7)--使用mapper代理开发代替原始的dao开发
举报原因:
原因补充:

(最多只允许输入30个字)