Mybatis学习系列Mapper接口动态代理

敢说敢作敢为, 无怨无恨无悔。这篇文章主要讲述Mybatis学习系列Mapper接口动态代理相关的知识,希望能为你提供帮助。
实现原理及规范Mapper接口动态代理的方式需要手动编写Mapper接口,Mybatis框架将根据接口定义创建接口的动态代理对象,代理对象的方法体实现Mapper接口中定义的方法。
使用Mapper接口需要遵守以下规范:
1.  Mapper.xml文件中的namespace与mapper接口的类路径相同
2.  Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3.  Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4.  Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
编写Mapper.xml映射文件定义mapper映射文件ProductMapper.xml,需要修改namespace的值为 ProductMapper接口路径

< ?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:此处使用包名+文件名 的形式 --> < mapper namespace="com.sl.mapper.ProductMapper"> < !-- 返回自定义类型 注意 selectAllProduct返回的是集合,这种情况下resultType是集合包含的类型,而不能是集合本身 --> < select id="selectAllProduct" resultType="com.sl.po.Product"> select * from products < /select> < select id="selectProductsByVo" resultType="com.sl.po.Product"> select * from products < where> < if test="product.cityCode!=null"> and citycode = #{product.cityCode} < !-- citycode = #{cityCode} --> < /if> < if test="product.Name!=null"> and name like #{product.Name} < /if> < if test="product.Description!=null"> and description like #{product.Description} < /if> < /where> < /select> < /mapper>

编写Mapper.java接口接口定义注意点:
1.  Mapper接口方法名和Mapper.xml中定义的statement的id相同
2.  Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同
3.  Mapper接口方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同
Mybatis学习系列Mapper接口动态代理

文章图片
Mybatis学习系列Mapper接口动态代理

文章图片
package com.sl.mapper; import java.util.List; import com.sl.po.Product; import com.sl.po.ProductVo; public interface ProductMapper {List< Product> selectAllProduct(); List< Product> selectProductsByVo(ProductVo vo); }

View Code
Mybatis学习系列Mapper接口动态代理

文章图片
Mybatis学习系列Mapper接口动态代理

文章图片
package com.sl.po; public class ProductVo {private int category; private Product product; public int getCategory() { return category; }public void setCategory(int category) { this.category = category; }public Product getProduct() { return product; }public void setProduct(Product product) { this.product = product; }}

View Code 注册Mapper.xml配置文件(或者Mapper.java接口)修改SqlMapConfig.xml文件:
< mappers> < !-- 注册productMapper.xml文件 --> < mapper resource="mapper/productMapper.xml"> < /mapper> < !-- mapper.xml文件和mapper接口可以不在一个包下--> < !-- 注册mapper接口 --> < !-- < mapper class="com.sl.mapper.ProductMapper"> < /mapper> --> < !--通过注册mapper接口方式: Mapper接口和mapper.xml必须在同一个包下 --> < /mappers>

测试方法
Mybatis学习系列Mapper接口动态代理

文章图片
Mybatis学习系列Mapper接口动态代理

文章图片
//Mapper接口动态代理方式 public class TestProductMapperClient {// 定义会话SqlSession SqlSession session = null; @Before public void init() throws IOException { // 定义mabatis全局配置文件 String resource = "SqlMapConfig.xml"; // 加载mybatis全局配置文件 // InputStream inputStream = // TestClient.class.getClassLoader().getResourceAsStream(resource); InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(inputStream); // 根据sqlSessionFactory产生会话sqlsession session = factory.openSession(); }// select by id //@Test public void testSelectProduct() {// 获取mapper接口的代理对象 ProductMapper productMapper = session.getMapper(ProductMapper.class); List< Product> listProduct = productMapper.selectAllProduct(); for (Product product : listProduct) { System.out.println(product); } // 关闭会话 session.close(); }@Test public void testwhereTest() { Product product = new Product(); product.setCityCode("A01"); product.setName("%国际%"); //product.setDescription("%xx%"); //product.setUnitPrice(new BigDecimal(100)); ProductVo vo = new ProductVo(); vo.setProduct(product); ProductMapper productMapper = session.getMapper(ProductMapper.class); List< Product> listProduct = productMapper.selectProductsByVo(vo); for (Product pro : listProduct) { System.out.println(pro); }// 关闭会话 session.close(); }}

View Code【Mybatis学习系列Mapper接口动态代理】      动态代理对象内部调用sqlSession.selectOne()和sqlSession.selectList()实现数据库操作,具体调用哪一个是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
由于参数类型在mapper.xml配置文件中ParameterType配置,所以Mapper.java中接口方法只有一个参数,且类型与mapper.xml中配置的相同(mapper.xml可省略参数类型配置)。
 

    推荐阅读