mybatis生成mapper接口(dao接口)对象原理(代理模式-JDK动态代理)

需要掌握:设计模式-代理模式-JDK动态代理(Proxy.newProxyInstance)

介绍

由于 mybatis 使用中,需要实现 mapper接口(dao接口),所以可通过 JDK动态代理,生成 接口对象

核心代码

生成 mapper对象

public class SqlSession {

    public <T> T getMapper(Class<T> mapperInterface){
        Class[] array=new Class[]{mapperInterface};
        InvocationHandlerImpl ihi=new InvocationHandlerImpl(mapperInterface);
        Object agent= Proxy.newProxyInstance(mapperInterface.getClassLoader(),array,ihi);
        return (T)agent;
    }
}

实现 mapper对象方法

public class InvocationHandlerImpl implements InvocationHandler {
    private Class mapperInterface;
    public InvocationHandlerImpl(Class mapperInterface){
        this.mapperInterface=mapperInterface;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String name=mapperInterface.getName();
        String methodName=method.getName();

        String sql=SQL.get(name+"."+methodName);
        System.out.println("sql:"+sql);
        System.out.println("传输参数:"+args[0]);

        return 1;
    }
}

其他代码

为了简化操作,没有实现 SqlSessionFactory 类

mapper配置文件

模拟 mapper.xml 配置文件

namespace=com.company.mapper.IStudentMapper
select=addStudent;INSERT INTO student(sid, sname, age, sex, addr, phone) VALUES (#{sid}, #{sname}, #{age}, #{sex}, #{addr}, #{phone});

SqlSessionFactoryBuilder

模拟 SqlSessionFactoryBuilder 类

public class SqlSessionFactoryBuilder {

    public SqlSession build(InputStream is) throws IOException {
        Properties p=new Properties();
        p.load(is);
        String namespace=p.getProperty("namespace");
        String select=p.getProperty("select");
        String[] array=select.split(";");


        SQL.put(namespace+"."+array[0],array[1]);

        return new SqlSession();
    }
}

存放 sql语句

public class SQL {

    private static final Map<String,String> SQL_MAP=new HashMap();

    public static void put(String key,String sql){
        SQL_MAP.put(key,sql);
    }
    public static String get(String key){
        return SQL_MAP.get(key);
    }
}

实体类

public class Student {
    private String sid;
    private String sname;
    private Integer age;

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sid='" + sid + '\'' +
                ", sname='" + sname + '\'' +
                ", age=" + age +
                '}';
    }
}

mapper接口(dao接口)

public interface IStudentMapper {

    public int addStudent(Student std);

}

测试类

import com.company.entity.Student;
import com.company.mapper.IStudentMapper;
import com.company.mybatis.SqlSession;
import com.company.mybatis.SqlSessionFactoryBuilder;

import java.io.FileInputStream;
import java.io.IOException;

public class Main {


    public static void main(String[] args) throws IOException {

        FileInputStream is=new FileInputStream("StudentMapper.properties");

        SqlSession sqlSession=new SqlSessionFactoryBuilder().build(is);
        IStudentMapper mapper=sqlSession.getMapper(IStudentMapper.class);
        Student std=new Student();
        std.setSid("123");
        std.setSname("李雷");
        int i=mapper.addStudent(std);
        System.out.println(i);
    }
}