mybatis-config.xml
<?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>
<!--<typeAliases>-->
<!--<package name="com.mybatis.entity"/>-->
<!--</typeAliases>-->
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="logImpl" value="LOG4J"/>
</settings>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/PersonMapper.xml"/>
</mappers>
</configuration>
mapper.xml
<?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.zy.dao.PersonMapper">
<insert id="insert" parameterType="com.zy.pojo.Person" >
INSERT INTO person(name, age, phone, email, address)
VALUES(#{name},#{age},#{phone},#{email},#{address})
</insert>
<select id="getPerson" resultType="com.zy.pojo.Person">
select * from person where id = #{id}
</select>
</mapper>
pojo
public class Person {
private int id;
private String name;
private int age;
private String phone;
private String email;
private String address;
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", phone='" + phone + '\'' +
", email='" + email + '\'' +
", address='" + address + '\'' +
'}';
}
}
测试入口:
/**
* @Classname TestMain
* @Description TODO
* @Date 2021/4/30 15:09
*/
public class TestMain {
public static void main(String[] args) throws IOException {
// InputStream is = TestMain.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//拿到SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//工厂模式创建 sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//得到动态代理mapper
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.getPerson("1");
System.out.println(person);
}
}
DefualtSqlSession getMapper()方法
看看DefaultSqlSession中的属性
MapperRegistry 中是一个HashMap key为Mapper.Class value:MapperProxyFactory
其中mybatis代理Mapper使用了工厂模式+动态代理
下面是简单原理
//被代理的接口
/**
* @Classname Hello
* @Description TODO
* @Date 2021/5/28 9:16
*/
public interface Hello {
public void hello();
}
package easyProxy;
/**
* @Classname Hei
* @Description TODO
* @Date 2021/5/28 9:16
*/
public interface Hei {
public void say();
}
动态代理接口
package easyProxy.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @Classname ProxyHanlder
* @Description TODO
* @Date 2021/5/28 9:18
*/
public class ProxyHandler1<T> implements InvocationHandler {
Class<T> methodInterface;
public ProxyHandler1(Class<T> methodInterface) {
this.methodInterface = methodInterface;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理开始");
System.out.println("处理代理逻辑");
return null;
}
}
动态代理生成工厂
package easyProxy.factory;
import easyProxy.proxy.ProxyHandler1;
import java.lang.reflect.Proxy;
/**
* @Classname ProxyFactory
* @Description TODO
* @Date 2021/5/28 9:22
*/
public class ProxyFactory<T> {
Class<T> methodInterface;
public ProxyFactory(Class<T> methodInterface) {
this.methodInterface = methodInterface;
}
public T newInstance() {
ProxyHandler1 proxyHandler = new ProxyHandler1(methodInterface);
return (T)newInstance(proxyHandler);
}
public T newInstance(ProxyHandler1 proxyHandler) {
return (T)Proxy.newProxyInstance(methodInterface.getClassLoader(), new Class[] {methodInterface}, proxyHandler);
}
}
代理接口注册类
package easyProxy.main;
import easyProxy.Hello;
import easyProxy.factory.ProxyFactory;
import java.util.HashMap;
/**
* @Classname MethodRegister
* @Description TODO
* @Date 2021/5/28 9:34
*/
public class MethodRegister {
private HashMap<Class<?>, ProxyFactory<?>> knowMethods = new HashMap<>();
public void addMethod(Class<?> methodInterface) {
knowMethods.put(methodInterface, new ProxyFactory<>(methodInterface));
}
public <T> ProxyFactory<T> getMethodProxyFactory(Class<T> methodInterface) {
return (ProxyFactory<T>)knowMethods.get(methodInterface);
}
}
测试类
package easyProxy.main;
import easyProxy.Hei;
import easyProxy.factory.ProxyFactory;
import jdkProxy.Hello;
/**
* @Classname Main
* @Description TODO
* @Date 2021/5/28 9:32
*/
public class Main {
private MethodRegister methodRegister = new MethodRegister();
/**
* 加载配置注册接口
* */
public void init() {
methodRegister.addMethod(Hello.class);
methodRegister.addMethod(Hei.class);
}
public static void main(String[] args) {
Main main = new Main();
main.init();
ProxyFactory<Hei> methodProxyFactory = main.methodRegister.getMethodProxyFactory(Hei.class);
Hei hei = methodProxyFactory.newInstance();
hei.say();
}
}