近期学习了如何手写简易的mybatis,网上的博客的代码多多少少有些问题,运行不起来,本篇博文保证你百分百能运行和理解mybaits。
首先我觉得这张图用来理解mybatis很易懂。
然后是本次demo的流程图
demo运行环境
IntelliJ IDEA,jdk1.8,mysql
运行代码步骤
1.创建user数据库(主键id,name属性)
2.修改SimpleExcutor中JDBC的URL和用户名和密码
然后从我的github (git clone)下来这个项目就可以运行了。
代码分析
首先看流程图,我们从执行器入手。
Excutor接口
public interface Excutor {
public T query(String statement,Object parameter);
}
然后用SimpleExcutor实现它
public class SimpleExcutor implements Excutor{
@Override
public T query(String sql, Object parameter) {
Connection connection = null;
PreparedStatement preparedStatement = null;
connection = getConnection();
try{
PreparedStatement pre = connection.prepareStatement(sql);
String str = (String) parameter;
pre.setInt(1,Integer.parseInt(str));
ResultSet set = pre.executeQuery();
User user = new User();
while(set.next()){
user.setName(set.getString(2));
//System.out.println(set.getString(2));
}
return (T)user;
}catch (SQLException e){
e.printStackTrace();
}
return null;
}
private Connection getConnection(){
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://120.78.149.145:3306/springbootdb?useUnicode=true&characterEncoding=utf8&useSSL=false";
String username = "root";
String password = "cui8135130";
try{
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,username,password);
System.out.println("连接成功");
return connection;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
这样一来数据源的连接我们就做好了。
然后创建实体类:
public class User {
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
创建mybaits的dao层接口和映射文件(这里用Java文件模拟)
UserMapper接口
public interface UserMapper {
public User getUserById(String id);
}
UserMapperXml(映射文件)
public class UserMapperXml {
//类xml的命名空间
public static final String namespate = "com.example.writemybaits.service.UserMapper";
public static final Map map = new HashMap();
static{
//模拟xml中的id与sql语句
map.put("getUserById","select * from user where id = ?");
}
}
接下来是核心内容了
动态代理实现sqlsession的装配
首先我们看看sqlsession的代码
public class Sqlsession {
private Excutor excutor = new SimpleExcutor();
public T selectOne(String statement,Object parameter){
return excutor.query(statement,parameter);
}
public T getMapper(Class tClass){
return (T) Proxy.newProxyInstance(tClass.getClassLoader(),new Class[]{tClass},new MyMapperHandler<>(this));
}
}
有三部分组成
1>创建一个执行器
2>调用执行器查询
3>通过动态代理来dao层接口和映射文件的装配查询。
(关于动态代理可以看我的这篇博文https://blog.csdn.net/Jet_Green/article/details/81198691)
MyMapperHandler
private Sqlsession sqlsession = null;
public MyMapperHandler(Sqlsession sqlsession){
this.sqlsession = sqlsession;
}
@Override
public Object invoke(Object proxy, Method method,Object[] args)throws Throwable{
System.out.println("运行invoke方法");
System.out.println(method.getDeclaringClass().getName());
System.out.println("args "+args[0]);
if(method.getDeclaringClass().getName().equals(UserMapperXml.namespate)){
String sql = UserMapperXml.map.get(method.getName());
System.out.println(sql);
return sqlsession.selectOne(sql,String.valueOf(args[0]));
}
return null;
}
}
最后写一个测试类测试下就行
TestMybatis
public class TestMybatis {
public static void main(String [] args){
Sqlsession sqlsession = new Sqlsession();
UserMapper mapper = sqlsession.getMapper(UserMapper.class);
User userById = mapper.getUserById("1");
System.out.println(userById.getName());
}
}
运行结果:
运行invoke方法
com.example.writemybaits.service.UserMapper
args 1
select * from user where id = ?
连接成功
jack
根据代码和我输出的变量和流程图理解mybaits原理基本上应该不难吧
最后附上源码
https://github.com/jet0605/-mybatis