Custom implementation of Mybatis framework

preface

This paper is divided into two parts: the first part writes an introductory program with mybatis, and the second part removes mybatis from the introductory program and replaces it with a custom framework

Tip: the following is the main content of this article

1, Introduction to Mybatis framework

1.1. Import tables and data

DROP TABLE IF EXISTS USER;

CREATE TABLE USER (
  id INT(11) NOT NULL AUTO_INCREMENT,
  username VARCHAR(32) NOT NULL COMMENT 'User name',
  birthday DATETIME DEFAULT NULL COMMENT 'birthday',
  sex CHAR(1) DEFAULT NULL COMMENT 'nature`user`other',
  address VARCHAR(256) DEFAULT NULL COMMENT 'address',
  PRIMARY KEY  (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;



INSERT  INTO USER(id,username,birthday,sex,address) VALUES (41,'Lao Wang','2018-02-27 17:47:08','male','Beijing'),(42,'Lao Chen','2018-02-27 17:47:08','male','Beijing'),(43,'Lao Liang','2018-02-27 17:47:08','male','Beijing');





DROP TABLE IF EXISTS account;

CREATE TABLE account (
  accountId INT(11) NOT NULL AUTO_INCREMENT,
  UID INT(11) DEFAULT NULL COMMENT 'User number',
  MONEY DOUBLE DEFAULT NULL COMMENT 'amount of money',
  PRIMARY KEY  (accountId),
  KEY FK_Reference_8 (UID),
  CONSTRAINT FK_Reference_8 FOREIGN KEY (UID) REFERENCES USER (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;



INSERT  INTO account(accountId,UID,MONEY) VALUES (1,41,1000),(2,42,1000),(3,43,2000);

1.2. Prepare database environment, create projects and add dependencies

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mymybatis</groupId>
	<artifactId>mybatis_my</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.46</version>
		</dependency>
		<!-- mybatis rely on -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.5</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
	</dependencies>
</project>

1.3,SqlMapConfig.xml configuration

<?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>
	<!-- Database connection information -->
	<!-- 	environments Configure all database connections
				default:Default connection information
			environment: Configure a database connection information
				id:Unique tag
					transactionManager: Transaction manager
						type:Transaction manager type
							jdbc:use mybatis Built in transaction manager
								Connection.setAutoCommit(false)
                               	Connection.commit()
                               	Connection.rollback()
				dataSource:data source(Connection pool)
					type:Data source type
						pooled:use mybatis Self contained data source
					
			
	 -->
	<environments default="mysql">
		<environment id="mysql">
			<transactionManager type="jdbc"></transactionManager>
			<dataSource type="pooled">
				<property name="url" value="jdbc:mysql://192.168.211.130:3306/mybatis_demo"/>
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="username" value="root"/>
				<property name="password" value="root"/>
			</dataSource>
		</environment>
	</environments>
	<!-- relevant Dao Interface mapping(File or class) -->
	<mappers>
		<mapper resource="com/mymybatis/dao/UserDao.xml"/>
	</mappers>
</configuration>         

1.4 entity class

package com.mymybatis.pojo;

import java.util.Date;

public class User {
	private Integer id;
	private String username;
	private Date birthday;
	private String sex;
	private String address;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", birthday=" + birthday + ", sex=" + sex + ", address="
				+ address + "]";
	}
	
	
	
}


1.5. Write UserDao interface and UserDao interface mapping file

package com.mymybatis.dao;

import java.util.List;

import com.mymybatis.pojo.User;

public interface UserDao {
	List<User> findAll();
}

<?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.mymybatis.dao.UserDao">
	<select id="findAll"   resultType="com.mymybatis.pojo.User">
		select * from user;
	</select>
</mapper>

1.6 test

package com.mymybatis.test;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.mymybatis.dao.UserDao;
import com.mymybatis.pojo.User;

public class Demo {
	@Test
	public void test1() throws Exception{
		//1. Load sqlmapconfig xml
		InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2. Create SQLSessionFactory factory
		SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
		SqlSessionFactory factory = builder.build(in);
		//3. Create SQLSession
		SqlSession sqlSession = factory.openSession();
		//4. Generate Dao interface proxy object
		UserDao userDao = sqlSession.getMapper(UserDao.class);
		List<User> userList = userDao.findAll();
		for (User user : userList) {
			System.out.println(user);
		}
		sqlSession.close();
		in.close();
		
	}
}

2, Custom implementation of Mybatis framework

2.1. Copy the introductory program just now

2.2. User defined framework environment preparation

Technical points used

  1. JDK dynamic agent
  2. Parsing xml with dom4j+xpath
  3. jdbc
  4. jdbc metadata (encapsulating database result set)
  5. reflex

2.3 remove the dependency of mybatis and add a new dependency

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mymybatis</groupId>
	<artifactId>mybatis_my</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<!--mysql drive  -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.46</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
		<!--dom4j  -->
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>
		<!-- xpath -->
		<dependency>
			<groupId>jaxen</groupId>
			<artifactId>jaxen</artifactId>
			<version>1.1.6</version>
		</dependency>
		<!-- druid data source -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.6</version>
		</dependency>
	</dependencies>
</project>

2.4. Modify test class

package com.mymybatis.test;

import java.util.List;

import org.junit.Test;

import com.mymybatis.dao.UserDao;

import com.mymybatis.pojo.User;

public class Demo {
	@Test
	public void test1() throws Exception{
	
		//1. SQLSessionFactory creation
		SqlSessionFactory factory = new SqlSessionFactory();
		//2. Create SQLSession
		SqlSession sqlSession = factory.openSession();
		//3. Generate Dao interface proxy object
		UserDao userDao = sqlSession.getMapper(UserDao.class);
		System.out.println("Proxy object"+userDao.getClass());
		
		List<User> userList = userDao.findAll();
		for (User user : userList) {
			System.out.println(user);
		}
		
		
	}
}


Pay attention to the error report here. Let's ignore it first

2.5 user defined framework analysis

To analyze the test code, we need to implement the following steps

  1. Defines the SqlSessionFactory class and provides the openSession method
  2. Define SqlSession interface, DefaultSqlSession implementation class and getMapper method
  3. In the openSession method of SqlSessionFactory, return the implementation object of the SqlSession interface (DefaultSqlSession)

2.6 user defined framework (II) defining core APIs

package com.mymybatis.mybatis.factory;

public class SqlSessionFactory {
	/**
	 * Create SqlSession implementation object
	 */
	public void openSession() {
		
	}
}

2.7. Define SqlSession interface, DefaultSqlSession implementation class and getMapper method

package com.mymybatis.mybatis.session;

public interface SqlSession {
	/**
	 * Define getMapper to generate Dao interface proxy object
	 * Parameter: pass in the dao interface type to be generated
	 * Return value: the proxy object is finally generated
	 */
	public <T> T getMapper(Class<T> daoClass);
}

Defines the implementation of the SqlSession interface

package com.mymybatis.mybatis.session.impl;

import com.mymybatis.mybatis.session.SqlSession;
/**
 * SqlSession Default implementation of interface
 * @author 16427
 *
 */
public class DefaultSqlSession implements SqlSession{

	@Override
	public <T> T getMapper(Class<T> daoClass) {
		
		return null;
	}

}

2.8 in the openSession method of SqlSessionFactory, return the implementation object of SqlSession interface

package com.mymybatis.mybatis.factory;

import com.mymybatis.mybatis.session.SqlSession;
import com.mymybatis.mybatis.session.impl.DefaultSqlSession;

public class SqlSessionFactory {
	/**
	 * Create SqlSession implementation object
	 */
	public SqlSession openSession() {
		return new DefaultSqlSession();
	}
}

2.9 after defining the above Api, the test code will not report an error, but it will report an error when running


Cause: the getMapper method of the SqlSession interface implementation class (DefaultSqlSession) did not return a proxy object

2.10 customize the framework to improve DefaultSqlSession

Let getMapper of SqlSession generate JDK proxy object

package com.mymybatis.mybatis.session.impl;

import java.lang.reflect.Proxy;

import com.mymybatis.mybatis.proxy.MapperProxy;
import com.mymybatis.mybatis.session.SqlSession;
/**
 * SqlSession Default implementation of interface
 * @author 16427
 *
 */
public class DefaultSqlSession implements SqlSession{
	/**
	 * Use JDK dynamic proxy to generate interface proxy object (interface proxy)
	 * Parameter 1: class loader, which usually provides the class loader of the current class
	 * Parameter 2: incoming interface list
	 * Parameter 3: InvocationHandler interface implementation class, which can provide anonymous internal class implementation
	 */
	@Override
	public <T> T getMapper(Class<T> daoClass) {
		
		return (T)Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(),
				new Class[] {daoClass},
				new MapperProxy());
	}

}

The implementation of InvocationHandler interface and MapperProxy class are extracted

package com.mymybatis.mybatis.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * InvocationHandler Implementation class of interface
 * @author 16427
 *
 */
public class MapperProxy implements InvocationHandler{

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("========="+method.getName());
		return null;
	}

}

Execute test class

2.11 customize the framework and improve MapperProxy A to define Configuration and Mapper classes

2.11.1 Configuration is designed to complete the loading of all configurations

public class Configuration {
    
    //Define variables to store database connection parameters
    private String url;
    private String driver;
    private String username;
    private String password;
    
    //Defines all method information used to store the entire project
    /**
     * key:  namespace+.+id    com.itheima.dao.UserDao.findAll
     * value: Information about the entire method
     */
    private Map<String,Mapper> mappers  = new HashMap<>();
    
    
  
}

At the same time, a Mapper is designed to encapsulate each method information

package com.mymybatis.mybatis.config;
/**
 * This class is used for
 * @author 16427
 *
 */
public class Mapper {
	private String id;
	private String resultType;
	private String sql;
	private String namespace;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getResultType() {
		return resultType;
	}
	public void setResultType(String resultType) {
		this.resultType = resultType;
	}
	public String getSql() {
		return sql;
	}
	public void setSql(String sql) {
		this.sql = sql;
	}
	public String getNamespace() {
		return namespace;
	}
	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}
	

}

Continue to supplement the logic of Configuration and complete sqlmapconfig XML and mapping file loading

package com.mymybatis.mybatis.config;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * This class encapsulates all XML configuration files for the project
 * @author 16427
 *
 */
public class Configuration {
	//Define variables to store database connection parameters
	private String url;
	private String driver;
	private String username;
	private String password;
	//Defines all method information used to store the entire project
	private Map<String,Mapper> mappers=new HashMap<>();
	//Define a configuration static object
	private static Configuration configuration=null;
	//The private constructor uses single column mode
	private Configuration() {
		loadSqlMapConfig();
	}
	


	public static Configuration getConfiguration() {
		if(configuration==null) {
			return new Configuration();
		}else {
			return configuration;
		}
	}
	/**
	 * Read sqlmapconfig XML (the singleton mode is read only once)
	 */
	private void loadSqlMapConfig() {
		//Read xml configuration using Dom4j+xpath
		//1. Create a SaxReader
		SAXReader saxReader = new SAXReader();
		//2. Load XML and return Document object
		InputStream in = Configuration.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
		try {
			Document documnet= saxReader.read(in);
			//3. Get root tag
			Element rootElement = documnet.getRootElement();
			/*4.Continue reading word labels
			Read the property tag (it's easier to get the tag using xpath)
			/  Level by level acquisition
			 //  Get the specified label directly
			*/
			List<Element> propElements=rootElement.selectNodes("//property");
			for (Element propElement : propElements) {
				String name=propElement.attributeValue("name");
				String value = propElement.attributeValue("value");
				if("url".equals(name)) {
					this.url=value;
				}
				if("driver".equals(name)) {
					this.driver=value;
				}
				if("username".equals(name)) {
					this.username=value;
				}
				if("password".equals(name)) {
					this.password=value;
				}
			}
			//Continue reading sub Tags
			List<Element> mapperElements=rootElement.selectNodes("//mapper");
			for (Element mapperElement : mapperElements) {
				String mapperResource = mapperElement.attributeValue("resource");
				//Load dao interface configuration file
				loadMapper(mapperResource);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	private void loadMapper(String mapperResource) {
		//Read xml configuration using Dom4j+xpath
		//Create SAXReader
		SAXReader saxReader = new SAXReader();
		//Loading xml returns du
		InputStream in = Configuration.class.getClassLoader().getResourceAsStream(mapperResource);
		try {
			Document document = saxReader.read(in);
			//Get root label
			Element rootElement = document.getRootElement();
			String namespace = rootElement.attributeValue("namespace");
			List<Element> selectElement = rootElement.selectNodes("select");//Ignore the write operation first
			for (Element element : selectElement) {
				Mapper mapper = new Mapper();
				String id=element.attributeValue("id");
				String resultType = element.attributeValue("resultType");
				String sql = element.getTextTrim();
				mapper.setId(id);
				mapper.setResultType(resultType);
				mapper.setSql(sql);
				mapper.setNamespace(namespace);
				//Save to Map collection
                //namespace+id = com.itheima.dao.UserDao.findAll
				mappers.put(namespace+"."+id, mapper);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

2.12. Customize the framework, improve MapperProxy, and define the Executor class

2.12.1 in the Configuration class, provide methods to obtain method mapping information and connect pool objects

package com.mymybatis.mybatis.config;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * This class encapsulates all XML configuration files for the project
 * @author 16427
 *
 */
public class Configuration {
	//Define variables to store database connection parameters
	private String url;
	private String driver;
	private String username;
	private String password;
	//Define connection pool objects
	private DataSource dataSource;
	//Defines all method information used to store the entire project
	private Map<String,Mapper> mappers=new HashMap<>();
	//Define a configuration static object
	private static Configuration configuration=null;
	//The private constructor uses single column mode
	private Configuration() {
		loadSqlMapConfig();
	}
	


	public static Configuration getConfiguration() {
		if(configuration==null) {
			return new Configuration();
		}else {
			return configuration;
		}
	}
	/**
	 * Read sqlmapconfig XML (the singleton mode is read only once)
	 */
	private void loadSqlMapConfig() {
		//Read xml configuration using Dom4j+xpath
		//1. Create a SaxReader
		SAXReader saxReader = new SAXReader();
		//2. Load XML and return Document object
		InputStream in = Configuration.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
		try {
			Document documnet= saxReader.read(in);
			//3. Get root tag
			Element rootElement = documnet.getRootElement();
			/*4.Continue reading word labels
			Read the property tag (it's easier to get the tag using xpath)
			/  Level by level acquisition
			 //  Get the specified label directly
			*/
			List<Element> propElements=rootElement.selectNodes("//property");
			for (Element propElement : propElements) {
				String name=propElement.attributeValue("name");
				String value = propElement.attributeValue("value");
				if("url".equals(name)) {
					this.url=value;
				}
				if("driver".equals(name)) {
					this.driver=value;
				}
				if("username".equals(name)) {
					this.username=value;
				}
				if("password".equals(name)) {
					this.password=value;
				}
			}
			//Continue reading sub Tags
			List<Element> mapperElements=rootElement.selectNodes("//mapper");
			for (Element mapperElement : mapperElements) {
				String mapperResource = mapperElement.attributeValue("resource");
				//Load dao interface configuration file
				loadMapper(mapperResource);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	private void loadMapper(String mapperResource) {
		//Read xml configuration using Dom4j+xpath
		//Create SAXReader
		SAXReader saxReader = new SAXReader();
		//Loading xml returns du
		InputStream in = Configuration.class.getClassLoader().getResourceAsStream(mapperResource);
		try {
			Document document = saxReader.read(in);
			//Get root label
			Element rootElement = document.getRootElement();
			String namespace = rootElement.attributeValue("namespace");
			List<Element> selectElement = rootElement.selectNodes("select");//Ignore the write operation first
			for (Element element : selectElement) {
				Mapper mapper = new Mapper();
				String id=element.attributeValue("id");
				String resultType = element.attributeValue("resultType");
				String sql = element.getTextTrim();
				mapper.setId(id);
				mapper.setResultType(resultType);
				mapper.setSql(sql);
				mapper.setNamespace(namespace);
				//Save to Map collection
                //namespace+id = com.itheima.dao.UserDao.findAll
				mappers.put(namespace+"."+id, mapper);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	//You don't need to provide connection information, you just need to provide connection pool objects
	public DataSource getDataSource() {
		if(dataSource==null) {
			DruidDataSource dataSource = new DruidDataSource();
			dataSource.setUsername(username);
			dataSource.setUrl(url);
			dataSource.setPassword(password);
			dataSource.setDriverClassName(driver);
			this.dataSource=dataSource;
		}
		return dataSource;
	}
}

2.12.2 design the Executor class and provide the selectList method to complete the final database query and result encapsulation

package com.mymybatis.mybatis.util;

import java.util.List;

import javax.sql.DataSource;

import com.mymybatis.mybatis.config.Mapper;
/**
 * This class is used for
 * 1)Execute sql statements using JDBC
 * 2)Encapsulate the execution result level of SQL statement into object return
 * @author 16427
 *
 */
public class Executor {
	/**
	 * Query multiple records
	 * @param mapper  Matching to method mapping information through XML configuration (including executed SQL statements)
	 * @param dataSource Objects required to execute sql statements
	 * @return
	 */
	public static List selectList(Mapper mapper,DataSource dataSource) {
		return null;
	}
}

2.12.3. Complete the core logic in MapperProxy

package com.mymybatis.mybatis.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;

import javax.sql.DataSource;

import com.mymybatis.mybatis.config.Configuration;
import com.mymybatis.mybatis.config.Mapper;
import com.mymybatis.mybatis.util.Executor;

/**
 * InvocationHandler Implementation class of interface
 *
 */
public class MapperProxy implements InvocationHandler{

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//1. Read xml configuration file
		Configuration configuration = Configuration.getConfiguration();
		//2. Get the JAVA object encapsulated with XML information
		Map<String, Mapper> mappers = configuration.getMappers();
		DataSource dataSource = configuration.getDataSource();
		//3. Obtain the sql statement to be executed from the configuration information
		//3.1 get the method of the currently executed interface
		//Method name
		String methodName = method.getName();
		//Interface type of method
		String interName = method.getDeclaringClass().getName();
		Mapper mapper = mappers.get(interName+"."+methodName);
		if(mapper==null) {
			throw new RuntimeException("The method is not in XML Mapping");
		}
		//4. Execute SQL statement to obtain the result set
		//5. Encapsulate the result set into java objects
		return Executor.selectList(mapper, dataSource);
	}

}


package com.mymybatis.mybatis.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import com.mymybatis.mybatis.config.Mapper;
/**
 * This class is used for
 * 1)Execute sql statements using JDBC
 * 2)Encapsulate the execution result level of SQL statement into object return
 * @author 16427
 *
 */
public class Executor {
	/**
	 * Query multiple records
	 * @param mapper  Matching to method mapping information through XML configuration (including executed SQL statements)
	 * @param dataSource Objects required to execute sql statements
	 * @return
	 */
	public static List selectList(Mapper mapper,DataSource dataSource) {
		//Get the sql to be executed
		String sql = mapper.getSql();
		//Get the object that needs to encapsulate each record
		String resultType = mapper.getResultType();// com.itheima.pojo.User
		//A list is designed to store the results of all queries
		List list=new ArrayList<>();
		try {
			//Get connection
			Connection connection = dataSource.getConnection();
			//Prepare sql statements
			PreparedStatement stmt = connection.prepareStatement(sql);
			//Execute sql
			ResultSet rs = stmt.executeQuery();
			//Get bytecode object
			Class clazz = Class.forName(resultType);
			//Get jdbc metadata
			ResultSetMetaData metaData = rs.getMetaData();
			//Get the number of fields through metadata
			Integer columnCount = metaData.getColumnCount();
			//Encapsulate result sets into result sets
			while (rs.next()) {
				//Create an object for each record that needs to be encapsulated
				Object obj = clazz.newInstance();
				//Pass the field value of each record into the object
				/**
				 * Get the attribute name of each object and each field value of each record (corresponding association: the attribute name and field name are consistent)
				 */
				for(int i=1;i<=columnCount;i++) {
					//Subscripts start with 1
					//Get each field name with metadata
					String columnName = metaData.getColumnName(i);
					//Each field value
					Object columnValue = rs.getObject(i);
					//Use reflection to assign a value to the username attribute of the obj object
					Field field = clazz.getDeclaredField(columnName);
					field.setAccessible(true);
					/**
					 * Object assigned to parameter 1
					 * Value to be given for parameter 2
					 * 
					 */
					field.set(obj, columnValue);
					
				}
				//2.3 store each encapsulated object into the list set
				list.add(obj);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		return list;
	}
}

Keywords: Java Mybatis

Added by findshorty on Tue, 04 Jan 2022 04:50:43 +0200