原理--JDK动态代理产生mapper动态代理对象
1.通过反射获取方法注解或者xml文件中的sql语句 2.获取数据库连接(jdbc) 3.解析sql语句 4.执行sql语句 4.获取动态代理对象(最终对象,可以直接调用方法)
自己实现简单的mybatis动态代理
获取jdbc连接
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBManager {
public static Connection getConn() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
String user = "root";
String pass = "1234567890";
return DriverManager.getConnection(url, user, pass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
获取Mapper的动态代理
import java.lang.reflect.Proxy;
public class MapperProxy {
public static Object getMapper(Class clazz) {
/**
* 传入三个参数
* classLoader 代理对象的类加载器对象
* Class<?>[] interfaces 代理类实现的接口的数组(可能会代理多个接口)
*InvocationHandler h 方法调用分派给的invocationHandler
*/
return Proxy.newProxyInstance(MapperProxy.class.getClassLoader(),
new Class[]{clazz}, new MyInvocationHandler());
}
} Mapper类
import com.example.mybatisdemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
List<User> queryAll();
} 实体类User
import lombok.Data; @Data public class User { private int id; private String username; private String name; private int age; private int balance; }
自定义类实现InvocationHandler
package com.example.mybatisdemo.test;
import com.example.mybatisdemo.entity.User;
import org.apache.ibatis.annotations.Select;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class MyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取sql语句
Select annotation = method.getAnnotation(Select.class);
String sql = annotation.value()[0];
System.out.println(sql);
//解析sql语句
Connection conn = DBManager.getConn();
PreparedStatement ps = conn.prepareStatement(sql);
//执行sql语句 jdbc
ResultSet rs = ps.executeQuery();
List<User> users = new ArrayList<>();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
user.setBalance(rs.getInt("balance"));
users.add(user);
}
conn.close();
rs.close();
return users;
}
} 测试类
import com.example.mybatisdemo.dao.UserMapper;
import com.example.mybatisdemo.entity.User;
import java.util.List;
public class TestMain {
public static void main(String [] arg) {
UserMapper userMapper = (UserMapper) MapperProxy.getMapper(UserMapper.class);
List<User> users = userMapper.queryAll();
for (User user : users) {
System.out.println(
user.getId() + " "
+ user.getUsername() + " "
+ user.getName() + " "
+ user.getAge() + " "
+ user.getBalance()
);
}
}
} SQL文件
/* Navicat Premium Data Transfer Source Server : localhostMysql Source Server Type : MySQL Source Server Version : 50726 Source Host : localhost:3306 Source Schema : test Target Server Type : MySQL Target Server Version : 50726 File Encoding : 65001 Date: 07/10/2019 20:01:36 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `username` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `age` int(11) NOT NULL, `balance` int(11) UNSIGNED ZEROFILL NOT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'accout1', 'zhangsan', 20, 00000000100); INSERT INTO `user` VALUES (2, 'accout2', 'lisi', 28, 00000000180); INSERT INTO `user` VALUES (3, 'accout3', 'wangwu', 32, 00000000250); INSERT INTO `user` VALUES (4, 'accout4', 'saozhu', 18, 00000000200); INSERT INTO `user` VALUES (5, 'accout5', 'zhangtao', 22, 00000000540); SET FOREIGN_KEY_CHECKS = 1;
笔者也是初学,写博客分享,有错误的地方以及不足的地方欢迎大家指正哈!

京公网安备 11010502036488号