美文网首页
97、【JavaEE】【Mybatis】Mapper 接口代理开

97、【JavaEE】【Mybatis】Mapper 接口代理开

作者: yscyber | 来源:发表于2021-10-14 03:39 被阅读0次

1、概述

  • Mapper 代理开发方式(基于接口代理方式实现持久层的开发),是当前使用 MyBatis 的主流。基于接口代理方式的开发只需要程序员编写 Mapper 接口,MyBatis 框架会为我们动态生成实现类的对象。

2、传统开发方式

  • 在传统的开发中,持久层开发的“套路”是,编写接口,再编写接口的实现类,最后基于多态(接口的引用指向实现类的实例)去调用实现的方法。
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * 当前,数据库中字段名 与 类中属性名 需保持一致
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Xxx {

    private Integer id;

    private String name;

}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    
    <properties resource="jdbc.properties" />

    <typeAliases>
        <typeAlias type="com.yscyber.mybatis.one.Xxx" alias="Xxx" />
    </typeAliases>
    
    <environments default="dev">
        <!-- 配置数据源 -->
        <environment id="dev">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc_driver}"/>
                <property name="url" value="${jdbc_url}"/>
                <property name="username" value="${jdbc_username}"/>
                <property name="password" value="${jdbc_password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 加载映射文件 -->
    <mappers>
        <mapper resource="xxxMapper.xml"/>
    </mappers>
    
</configuration>
<?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">

    <select id="listAllXxx" resultType="Xxx">
        SELECT id, name
        FROM xxx
    </select>

</mapper>
import com.yscyber.mybatis.one.Xxx;

import java.util.List;

public interface XxxRepo {

    List<Xxx> listAllXxx();

}
import com.yscyber.mybatis.one.Xxx;
import com.yscyber.mybatis.one.repo.XxxRepo;

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 java.io.IOException;
import java.util.List;

// 代码可能存在不合理,请忽略
public class XxxRepoImpl implements XxxRepo {

    private static SqlSession sqlSession;

    static {
        try {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis.xml"));
            sqlSession = sqlSessionFactory.openSession();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<Xxx> listAllXxx() {
        if (sqlSession != null) {
            List<Xxx> xxxList = sqlSession.selectList("xxxMapper.listAllXxx");
            return xxxList;
        }
        return null;
    }

}
    @Test
    public void test6() {
        XxxRepo xxxRepo = new XxxRepoImpl();

        List<Xxx> xxxList = xxxRepo.listAllXxx();
        for (Xxx val : xxxList) {
            System.out.println(val);
        }
    }

传统开发方式的问题,比如实现类中,如果专门设计、抽取一个工具类的话,会存在 MyBatis 模板代码重复的问题;在实现类中,需要使用到映射配置文件中的namespace.id,这属于“硬编码”,一旦映射配置文件中发生变化,实现类也必须要及时调整。

于是,MyBatis 提供了一种接口代理方案,使得无需编写实现类,只编写持久层接口以及映射配置文件即可。

3、接口代理开发方式

  • 只需要编写持久层接口,由 MyBatis 框架根据接口定义创建接口的动态代理对象。

  • 使用这种开发方式,需要遵循一定的规则,否则无法实现。

MyBatis-8
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * 当前,数据库中字段名 与 类中属性名 需保持一致
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Xxx {

    private Integer id;

    private String name;

}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    
    <properties resource="jdbc.properties"/>
    
    <typeAliases>
        <typeAlias type="com.yscyber.mybatis.one.Xxx" alias="Xxx"/>
    </typeAliases>
    
    <environments default="dev">
        <!-- 配置数据源 -->
        <environment id="dev">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc_driver}"/>
                <property name="url" value="${jdbc_url}"/>
                <property name="username" value="${jdbc_username}"/>
                <property name="password" value="${jdbc_password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 加载映射文件 -->
    <mappers>
        <mapper resource="xxxMapper.xml"/>
    </mappers>
    
</configuration>
<?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 namespace="com.yscyber.mybatis.one.repo.XxxRepo">

    <select id="listAllXxx" resultType="Xxx">
        SELECT id, name
        FROM xxx
    </select>

</mapper>
    @Test
    public void test7() {
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
            SqlSession sqlSession = sqlSessionFactory.openSession();

            XxxRepo xxxRepo = sqlSession.getMapper(XxxRepo.class);

            List<Xxx> xxxList = xxxRepo.listAllXxx();
            for (Xxx val : xxxList) {
                System.out.println(val);
            }

            sqlSession.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 补充,在核心配置文件中,<mappers>标签下的<mapper>标签,有两个专门配合代理开发的写法,一个是<mapper class="">,一个是<mapper package="">
    <mapper class="">,可以直接配置接口的完全限定名,但要求,映射配置文件与接口同名,且编译后.class文件与.xml文件处于同一目录下。
    <mapper package="">,可以直接配置接口所在包的完全限定名,要求同上。
MyBatis-9 MyBatis-10

4、接口代理开发的原理

MyBatis-11 MyBatis-12

相关文章

网友评论

      本文标题:97、【JavaEE】【Mybatis】Mapper 接口代理开

      本文链接:https://www.haomeiwen.com/subject/nlyeoltx.html