实现原理及规范
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 可省略参数类型配置).
来源: https://www.cnblogs.com/ashleyboy/p/9277048.html