Hand-written Mybaits simple version comb:

Mybatis function,

Initialization:

1. Read the config. XML configuration file and parse it into ConfGuration object 2. Read the mapper. The XML configuration files Every SQL nodes (insert | delete the update | select) parsing for mappedStatement object, into the configuration object stored in an attribute variables

Properties file, directly configure mapper interface full path + corresponding method name as a statementId to obtain the corresponding ID, also do not configure mapper. XML file to write SQL statements, just extract SQL statements. Put it in a configuration file instead of parsing the mapper.xml file, mostly to get the gist

edu.yuz.yubatis.v1.mapper.BlogMapper.selectBlogById = select * from blog where bid = %d
Copy the code

3. Create a Mapper interface. The Mapper interface contains corresponding methods and QUERY SQL parameters

Public Blog selectBlogById(Integer bid); public Blog selectBlogById(Integer bid); }Copy the code

Mapper interfaces and methods contain the following information: 1. The full path corresponds to the namespace of the mapperf mapping file, and the method name corresponds to the SQL node of the mapping file. The full path + method name is used as mappedStatementid to obtain the corresponding MappedStatement object, which encapsulates the SQL statement of an SQL node. SQL query configuration 2. Method parameters are query conditions, and method return types are query return types

  1. Create a user API called sqlSession that encapsulates the add, delete, alter, and query methods. Create a real Executor named Executor that will actually execute an SQL statement, such as obtaining a connection. Create a Prepastatment object, execute the query, and map the returned ResultSet to a POJO object

(Step 4 create sqlSession object and Executor object)

Public class YuSqlSession {// The executor needs to know how to obtain the corresponding query information from the statementId. So there needs to be a reference to the configuration// object. Private YuConfiguration YuConfiguration; // The real JDBC object private YuExecutor yuExcutor; public YuSqlSession(YuConfiguration yuConfiguration, YuExecutor yuExcutor) { this.yuConfiguration = yuConfiguration; this.yuExcutor = yuExcutor; } public <T> T selectOne(String statementId, Object params) { String sql = yuConfiguration.getSqlString(statementId); YuExcutor. QuereyOne (SQL, params); This method generates a proxy object for the mapper interface, Public <T> T public <T> T public <T> T public <T> T public <T> T getMapper(Class<T> clazz) { return yuConfiguration.getMapper(clazz,this); }}Copy the code

5. The user can get the corresponding instance only through an interface and a method, which must be done through the dynamic proxy. The method to get the interface instance is called as follows:

YuSqlSession yuSqlSession = new YuSqlSession(new YuConfiguration(), new YuExecutor());
        BlogMapper blogMapper = yuSqlSession.getMapper(BlogMapper.class);
Copy the code

So the method getMapper(Blogmapper.class) must generate a dynamic proxy object for the incoming interface

So how do we get it

public class YuConfiguration { private static final ResourceBundle RESOURCE_BUNDLE; static { RESOURCE_BUNDLE = ResourceBundle.getBundle("sql_v1"); } public String getSqlString(String statementId) { return RESOURCE_BUNDLE.getString(statementId); } // You can create a method in the Configuration object, pass in the interface to be propped, and implement the trigger management class of the invocationHandler interface. Public <T> T getMapper(Class<T> clazz, YuSqlSession yuSqlSession) { return (T) Proxy.newProxyInstance(this.getClass().getClassLoader() ,new Class[]{clazz} ,new  YuMapperProxy(yuSqlSession)); }}Copy the code

The invoke method executes a sqlSession (add, delete, change, check) function on the invoke management class. The invoke method executes a sqlSession (add, delete, change) function on the invoke management class

public class YuMapperProxy implements InvocationHandler { private YuSqlSession yuSqlSession; public YuMapperProxy(YuSqlSession yuSqlSession) { this.yuSqlSession = yuSqlSession; } // The generated proxy class will call h.invoke() to pass the interface methods and parameters to the interface method that calls method. // The invoke method holds a sqlSession to perform related operations. // This is not the same as a normal proxy. Mybatis (mybatis, mybatis, mybatis, mybatis, mybatis, mybatis, mybatis, myBatis, myBatis, myBatis, myBatis SQL > create a dynamic proxy class by using a mapPendstament ament to create a dynamic proxy class. Public Object invoke(Object O, Method Method, Object[] objects) throws Throwable {String interFaceName = method.getIngClass ().getName(); String methodName = method.getName(); String statementId = interFaceName + "." + methodName; return yuSqlSession.selectOne(statementId, objects[0]); }}Copy the code

7. How to pass the method parameter value and proxy class to generate this solution: 7.1 how to pass the proxy class to the code is as follows:

// Create the sqlSession object, pass the interface name into the output proxy object, YuSqlSession = new YuSqlSession(new YuConfiguration(), new YuExecutor())); BlogMapper blogMapper = yuSqlSession.getMapper(BlogMapper.class); / / and then this method in the sqlSession object code below public < T > T getMapper (Class < T > clazz) {return yuConfiguration. GetMapper (clazz, this); } // In this method, clazz is the name of the interface passed in. Public <T> T getMapper(Class<T> clazz, YuSqlSession yuSqlSession) { return (T) Proxy.newProxyInstance(this.getClass().getClassLoader() ,new Class[]{clazz} ,new  YuMapperProxy(yuSqlSession)); } public class YuMapperProxy implements InvocationHandler {private YuSqlSession YuSqlSession; public YuMapperProxy(YuSqlSession yuSqlSession) { this.yuSqlSession = yuSqlSession; } // The generated proxy class will call h.invoke() to pass the interface methods and parameters to the interface method that calls method. Public Object invoke(Object o, Method Method, Object[] objects) throws Throwable { String interFaceName = method.getDeclaringClass().getName(); String methodName = method.getName(); String statementId = interFaceName + "." + methodName; return yuSqlSession.selectOne(statementId, objects[0]); }} // Call the method name. Final $proxy extends Proxy implements Interface {InvocationHander h; MethodA (methodA,new Object[]{params})} @override methodB(params){ MethodB (this.methodB,new Object[]{params})} override methodC(params){this.methodC,new Object[]{params})}} The invoke method is similar to a delegate pattern. The parameters of the method are passed when invoked. The instance of the method Object is the same as the method of the proxy instance class you called. Each interface corresponds to a proxy class, and each executor in the proxy class is independent.Copy the code

conclusion

Mybatis has several key classes to implement this simple hand-written version of mybatis: 1. Configuration Parses the configuration information into the configuration class before loading. 2 SQL > select, UPDATE, delete, insert; SQL > select, update, delete, insert; SQL > select, update, delete; 4.MapperProxy how to implement mapper interface proxy, Through a proxy class MapperProxy that implements the InvocationHandler class, the invoke method executes the statementId parameter by concatenating the propped interface, and the method called, and obtains the corresponding execution SQL. Call the sqlSession object method that has been initialized. Execute the JDBC code through the executor in the sqlSession method, and then perform the mapping processing of the resultSet results for parameter resolution 5. There are configuration classes