zoukankan      html  css  js  c++  java
  • 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的类型相同

    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
    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>

    测试方法

    //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

          动态代理对象内部调用sqlSession.selectOne()和sqlSession.selectList()实现数据库操作,具体调用哪一个是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

    由于参数类型在mapper.xml配置文件中ParameterType配置,所以Mapper.java中接口方法只有一个参数,且类型与mapper.xml中配置的相同(mapper.xml可省略参数类型配置)。

  • 相关阅读:
    【html】页面制作规范文档
    【jquery】blockUI 弹出层
    前端攻城师所要掌握的知识和技能
    【html】edm 邮件制作指南
    【css】教你如何写出高效整洁的 css 代码——css优化
    前端开发神器notepad++以及zen coding神级插件
    百度统计流量研究院——了解互联网行业基本数据分布和趋势
    【css】我的 css 框架——base.css
    通过扩展方法 链式方法 为MVC 3 视图添加验证
    使用正则表达式抓取博客园列表数据
  • 原文地址:https://www.cnblogs.com/ashleyboy/p/9277048.html
Copyright © 2011-2022 走看看