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可省略參數類型配置)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM