版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36827957/article/details/83657004
通过网上的各种资源,结合自身,模仿出Mybatis的简单实现,下面是主要代码:项目是一个普通Java项目,只要导入数据库的Jar包就行(我使用的是Mysql) 其实也就是底层jdbc的实现,底层查询数据库基本就是通过给一个查询语句,使用原生的jdbc实现来查询出结果,其中主要的五个步奏是:
不多说,直接上代码:
项目结构:
package com.lyh;
import java.io.Serializable;
import java.util.Date;
/**
* @author 633805 LYH
* @version V1.0
* @description 实体类
* @create 2018-11-02 10:39
* @since 1.7
*/
public class User implements Serializable{
private Long id;
private String userName;
private String userPassword;
private Date gmt_create;
private Date gmt_modified;
private Integer is_status;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public Date getGmt_create() {
return gmt_create;
}
public void setGmt_create(Date gmt_create) {
this.gmt_create = gmt_create;
}
public Date getGmt_modified() {
return gmt_modified;
}
public void setGmt_modified(Date gmt_modified) {
this.gmt_modified = gmt_modified;
}
public Integer getIs_status() {
return is_status;
}
public void setIs_status(Integer is_status) {
this.is_status = is_status;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", userPassword='" + userPassword + '\'' +
", gmt_create=" + gmt_create +
", gmt_modified=" + gmt_modified +
", is_status=" + is_status +
'}';
}
}
package com.lyh;
/**
* @author 633805 LYH
* @version V1.0
* @description 执行器
* @create 2018-11-02 9:49
* @since 1.7
*/
public interface MyExecutor {
<T> T query(String statement);
}
package com.lyh;
import java.lang.reflect.Field;
import java.sql.*;
/**
* @author 633805 LYH
* @version V1.0
* @description 执行器的实现
* @create 2018-11-02 9:51
* @since 1.7
*/
public class MyBaseExecutor implements MyExecutor {
private static final String URL = "jdbc:mysql://localhost:3306/springboot";
private static final String USER = "root";
private static final String PASS = "";
@Override
public <T> T query(String statement) {
Connection conn =null;
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(URL,USER,PASS);
String sql = statement;
ps = conn.prepareStatement(sql);
resultSet = ps.executeQuery();
Class<?> clazz = User.class;
Object instance = null;
if (resultSet.next()){
instance = clazz.newInstance();
//使用反射进行填充属性
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields){
field.setAccessible(true);
field.set(instance,resultSet.getObject(field.getName()));
}
}
return (T) instance;
}catch (Exception e) {
e.printStackTrace();
return null;
}finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
package com.lyh;
/**
* @author 633805 LYH
* @version V1.0
* @description 对类的描述
* @create 2018-11-02 13:53
* @since 1.7
*/
public interface MySqlSession {
<T> T selectOne(String param);
<T> T getMapper(Class<T> clazz);
}
package com.lyh;
import java.lang.reflect.Proxy;
/**
* @author 633805 LYH
* @version V1.0
* @description 对类的描述
* @create 2018-11-02 13:56
* @since 1.7
*/
public class MyDefaultSqlSession implements MySqlSession {
private MyExecutor myExecutor = new MyBaseExecutor();
@Override
public <T> T selectOne(String param) {
return myExecutor.query(param);
}
@Override
public <T> T getMapper(Class<T> clazz) {
return (T) Proxy.newProxyInstance(clazz.getClassLoader(),new Class[]{clazz},new MyMapperProxy(this));
}
}
package com.lyh;
/**
* @author 633805 LYH
* @version V1.0
* @description 对类的描述
* @create 2018-11-02 11:12
* @since 1.7
*/
public interface UserMapper {
// User findUserById(Integer id);
void insert(User user);
User findUserById(int id);
}
package com.lyh;
import java.util.HashMap;
import java.util.Map;
/**
* @author 633805 LYH
* @version V1.0
* @description 对类的描述
* @create 2018-11-02 11:14
* @since 1.7
*/
public class UserMapperXML {
//相当于xml的命名空间
public static final String namespace = "com.lyh.UserMapper";
//相当于select标签
private static Map<String, String> methodSqlMap = new HashMap<>();
static {
methodSqlMap.put("findUserById", "select * from user where id = %s");
}
public static String getMethodSql(String method) {
return methodSqlMap.get(method);
}
}
package com.lyh;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author 633805 LYH
* @version V1.0
* @description 获取mapper,JDK的动态代理
* @create 2018-11-02 14:01
* @since 1.7
*/
public class MyMapperProxy implements InvocationHandler{
private MySqlSession sqlSession;
public MyMapperProxy(){}
public MyMapperProxy(MySqlSession sqlSession){
this.sqlSession = sqlSession;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String mapperClass = method.getDeclaringClass().getName();
System.out.println("mapperClass"+mapperClass);
if (UserMapperXML.namespace.equals(mapperClass)){
String methodName = method.getName();
String originsql = UserMapperXML.getMethodSql(methodName);
String formatSql = String.format(originsql,String.valueOf(args[0]));
return sqlSession.selectOne(formatSql);
}
return null;
}
}
package com.lyh;
/**
* @author 633805 LYH
* @version V1.0
* @description 首先根据命名空间,找出与mapper接口方法名相同的sql语句,然后交给sqlSession来执行。
* @create 2018-11-02 14:15
* @since 1.7
*/
public class Test {
public static void main(String[] args) {
MySqlSession sqlSession = new MyDefaultSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
}
}
测试结果:
下面是我的数据库表结构:
参考:https://www.jianshu.com/p/73ee8caddc68?open_source=weibo_search