From JDBC to the minimalist version of MybatiesJDBC, automatic parsing of configuration files

Posted by TechGuru on Sun, 16 Jan 2022 20:38:27 +0100

brief introduction

To be frank, there is a class called properties in Java. This class is mainly used to read Java configuration files. Different programming languages have their own supported configuration files. Many variables in the configuration file are often changed. In order to facilitate user configuration, users can modify relevant variable settings without the program itself. Just like in Java, its configuration file is often The properties file is used to configure parameters in the form of key value pairs.
Therefore, we can try to use this class to automatically load a configuration file we customize. Then, hehe, our JDBC encapsulation class can be more convenient.

Specific operation

First, we need to know the specific usage of Properties. emmmm,, there are a lot of online codes, which are directly given here:
Create our profile here:

Then the code is as follows:

Properties pro = new Properties();
pro.load(ReflectTest.class.getClassLoader().getResourceAsStream("pro.properties"));
String v = pro.getProperty("Parameter name");

Code parsing

Okay, so here's the question, what do these lines of code do? Why can we find our profile?
First of all, let's start with reflection. Well, it's too long. It's directly said here: reflection can be implemented because there is a class in java, and its classLoader() can load our bytecode file (. Class) into memory..
Wait, did you find anything? Hey, since classLoader can load our compiled class file, does it mean that it has our compiled file path?
Let's take a look at our target:

okk, you can find that our class files, in addition to our packages, are our configuration files. When our classLoader loads one Class file, should we enter the full package name? Does that mean that the default path of our classLoader is our classes folder?
Ha ha, the case is solved.
So pro load(ReflectTest.class.getClassLoader(). getResourceAsStream("pro.properties"));
Where, reflecttest class. Getclassloader () is to get the path of our classLoader. As the name suggests, the following function is to get the byte stream. The input content of this function is the relative classLoader path of the configuration file.
We can know from the figure that our configuration file is under classes, so just enter the name of the configuration file directly.

Merge code

Finally, incorporate our new features into the code in our previous article:

package com.sy;

import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @author : byMJC
 * @date : Created 2022/1/16 19:04
 * @description: 
 */

public class JDBCUtilPro {
    private static final String DB_DEIVER = "com.mysql.jdbc.Driver";
    private static String DB_URL ;
    private static String DB_USER ;
    private static String DB_PWD ;
    private static Connection connection;

    /**
     * Static code block, registered driver
     */
    static {
        try {
            Class.forName(DB_DEIVER);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * Parsing configuration files
     * @param configName file name
     * @throws IOException
     */
    private void parseConfig(String configName) throws IOException {
        Properties properties = new Properties();
        properties.load(JDBCUtilPro.class.getClassLoader().getResourceAsStream(configName));
        DB_URL = properties.getProperty("DB_URL");
        DB_USER = properties.getProperty("DB_USER");
        DB_PWD = properties.getProperty("DB_PWD");
    }

    /**
     * Get connection
     */
    private void getConnection(){
        try {
            connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    /**
     * Constructor, passing in the configuration file name
     * @param configName
     */
    JDBCUtilPro(String configName){
        try {
            parseConfig(configName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        getConnection();
    }


    /**
     * The query statement is encapsulated, and the return value is assigned according to the order of entity class members
     * @param sql sql sentence
     * @param args Parameters, passed by List
     * @param tClass Returns the member type in the value list
     * @return Returns a List of query results
     */
    public <T> List<T> selectResultByOrder(String sql, List<?> args, Class<T> tClass){
        List<T> resList = new ArrayList<>();
        int columLen;
        try {
            if (connection.isClosed()) {
                getConnection();
            }
            // Get attributes using reflection
            Field[] declaredFields = tClass.getDeclaredFields();

            // Create statement
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            // Assignment parameter
            for (int i = 0; i < args.size(); i++) {
                preparedStatement.setObject(i+1, args.get(i));
            }
            // Execute statement
            ResultSet resultSet = preparedStatement.executeQuery();
            // Gets the table data of the return value and its length
            ResultSetMetaData metaData = resultSet.getMetaData();
            columLen = metaData.getColumnCount();
            while (resultSet.next()) {
                // Reflection build class
                Object res = tClass.getDeclaredConstructor().newInstance();
                // Traverse each property value of the resultSet
                for (int i = 0; i < columLen; i++) {
                    // Get the parameter name of each returned object
                    String columnName = metaData.getColumnName(i + 1);
                    // Get the parameter of the corresponding name
                    Object object = resultSet.getObject(columnName);
                    // Using reflection to assign parameters to res
                    declaredFields[i].setAccessible(true);
                    declaredFields[i].set(res, object);
                }
                resList.add((T) res);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return resList;
    }


    /**
     * The query statement is encapsulated, and the return value is assigned according to the name of the entity class member
     * @param sql sql sentence
     * @param args Parameters, passed by List
     * @param tClass Returns the member type in the value list
     * @return Returns a List of query results
     */
    public <T> List<T>  selectResultByName(String sql, List<?> args, Class<T> tClass){

        List<T> resList = new ArrayList<>();
        try {
            if (connection.isClosed()) {
                getConnection();
            }
            // Get attributes using reflection
            Field[] declaredFields = tClass.getDeclaredFields();

            // Create statement
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            // Assignment parameter
            for (int i = 0; i < args.size(); i++) {
                preparedStatement.setObject(i+1, args.get(i));
            }
            // Execute statement
            ResultSet resultSet = preparedStatement.executeQuery();
            // Gets the table data of the return value and its length
            ResultSetMetaData metaData = resultSet.getMetaData();
            while (resultSet.next()) {
                // Reflection build class
                Object res = tClass.getDeclaredConstructor().newInstance();
                for (Field declaredField : declaredFields) {
                    Object object = resultSet.getObject(declaredField.getName());
                    declaredField.setAccessible(true);
                    declaredField.set(res, object);
                }
                resList.add((T) res);
            }
            preparedStatement.close();
            resultSet.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return resList;
    }

    /**
     * Close connection
     */
    public void close(){
        try {
            connection.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }


}

Test code:

        JDBCUtilPro jdbcUtilPro = new JDBCUtilPro("JDBCConfig.properties");
        List<String> list = new ArrayList();
        List<User1> list1 = jdbcUtilPro.selectResultByName("select * from user", list, User1.class);
        System.out.println(list1);
        jdbcUtilPro.close();

Operation effect:

Topics: Java JavaEE intellij-idea