手写MVC初体验(四)之手写JDBC框架+连接池(初级阶段)

手写MVC初体验(四)之手写JDBC框架(MySQL版本)

1. application.properties

spring.orm.database.driver=com.mysql.jdbc.Driver
spring.orm.database.url=jdbc:mysql://123.57.80.77:3344/forum_user?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&&allowMultiQueries=true
spring.orm.database.username=g15846456247
spring.orm.database.password=990408myj990408Myj-=_+
spring.orm.pool.size=4
spring.orm.pool.max=5

2. annotation——实体类注解

实体类的注解是要配合Example来使用的,下一篇会完善。


import java.lang.annotation.*;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/7/10 22:48
 */
@Target({ElementType.TYPE})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {

    String name() default "" ;
}
import java.lang.annotation.*;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/7/10 22:48
 */
@Target({ElementType.TYPE})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {

    String name() default "" ;

}

3. ConnectionPool——连接池


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/7/11 21:04
 */

public class ConnectionPool implements IConnectionPool{
	//未使用的连接
    private List<Connection> freeConnections ;
	//已使用的连接
    private List<Connection> usedConnections ;
	//默认最大数量
    private int maxSize = 5 ;
	//默认最小数量
    private int minSize = 1 ;
	//初始化的数量
    private int initSize ;
	//当前数量
    private AtomicInteger preSize = new AtomicInteger(0) ;
	//等待时间
    private long waitTimeOut = 1000 ;
	//驱动类的路径
    private String driver ;
	//url
    private String url ;
	//username
    private String username ;
	//password
    private String password ;
	
    private final String driverProperty = "spring.orm.database.driver";

    private final String urlProperty = "spring.orm.database.url";

    private final String usernameProperty = "spring.orm.database.username";

    private final String passwordProperty = "spring.orm.database.password";

    private final String initSizeProperty = "spring.orm.pool.size" ;

    private final String maxSizeProperty = "spring.orm.pool.max" ;

    public ConnectionPool(Properties properties) throws Exception {
        setDriver(properties.getProperty(driverProperty)) ;
        setUrl(properties.getProperty(urlProperty)) ;
        setUsername(properties.getProperty(usernameProperty)) ;
        setPassword(properties.getProperty(passwordProperty)) ;
        setMaxSize(properties.getProperty(maxSizeProperty));
        setInitSize(properties.getProperty(initSizeProperty));
        loaderJDBC() ;
        setFreeConnections();
        setUsedConnections();
        createConnection(this.initSize) ;
    }

    private void loaderJDBC() {
        try {
            Class.forName(this.driver) ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
	
    //创建连接
    private synchronized void createConnection(int addSize) {
        if (addSize + preSize.get() > maxSize){
            return ;
        }
        Connection connection ;
        for (int i=0 ; i<addSize ; i++){
            try {
                connection = DriverManager.getConnection(this.url , this.username , this.password) ;
                this.freeConnections.add(connection) ;
                preSize.incrementAndGet() ;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
	
    //判断是否存活
    private boolean isAlive(Connection connection){
        try {
            if (connection == null || connection.isClosed()){
                return false ;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return true ;
    }

    //获取链接
    public synchronized Connection getConnection(){
        Connection connection = null ;
        //空闲连接
        if (freeConnections.size() > 0){
            connection = this.freeConnections.remove(0) ;
            this.preSize.decrementAndGet() ;
        }else{
            //没有空闲连接
            int surplus = 0 ;
            if ((surplus = this.maxSize - this.preSize.get()) > 0){
                createConnection(surplus);
                if (freeConnections.size() > 0){
                    connection = getConnection() ;
                }
            }else{
                try {
                    wait(this.waitTimeOut);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                connection = getConnection() ;
            }
        }
        if (isAlive(connection)){
            this.usedConnections.add(connection) ;
        }
        return connection ;
    }


    public synchronized void releaseConnection(Connection connection){
        if (isAlive(connection)){
            if (this.freeConnections.size() < this.maxSize){
                this.freeConnections.add(connection) ;
            }else{
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        this.usedConnections.remove(connection) ;
        this.preSize.decrementAndGet() ;
        notifyAll();
    }

    private boolean isNull(String param){
        return param == null || "".equals(param) ;
    }

    private void setDriver(String driver) throws Exception {
        if (isNull(driver)){
            throw new Exception("database driver is null or empty") ;
        }
        this.driver = driver;
    }

    private void setUrl(String url) throws Exception {
        if (isNull(url)){
            throw new Exception("database url is null or empty") ;
        }
        this.url = url;
    }

    private void setUsername(String username) throws Exception {
        if (isNull(username)){
            throw new Exception("database username is null or empty") ;
        }
        this.username = username;
    }

    private void setPassword(String password) throws Exception {
        if (isNull(password)){
            throw new Exception("database password is null or empty") ;
        }
        this.password = password;
    }

    private void setFreeConnections() {
        this.freeConnections = new Vector<Connection>(this.maxSize);
    }

    private void setUsedConnections() {
        this.usedConnections = new Vector<Connection>(this.maxSize);
    }

    private void setMaxSize(String maxSize) {
        this.maxSize = isNull(maxSize) ?
                this.maxSize :
                (Integer.parseInt(maxSize) > this.maxSize ?
                        this.maxSize : Integer.parseInt(maxSize))  ;
    }


    private void setInitSize(String initSize) {
        this.initSize = isNull(initSize) ?
                this.minSize :
                (Integer.parseInt(initSize) > this.maxSize ?
                        this.minSize : Integer.parseInt(initSize)) ;
    }
}

4. Executor——执行器


import org.framework.spring.v1.orm.annotation.Column;
import org.framework.spring.v1.orm.pool.ConnectionPool;
import org.framework.spring.v1.orm.sql.Example;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/7/11 21:02
 */

public class Executor {

    public static ConnectionPool pool ;

    public static <T> List<T> selectByExample(Example<T> example){
		//下篇实现 类似于BaseMapper的类型
        return null ;
    }

    //select
    public static <T> List<T> selectSql(String sql , Class<T> object) throws SQLException, InstantiationException, IllegalAccessException {
        Connection connection = pool.getConnection() ;
        Statement st = connection.createStatement() ;
        ResultSet rs = st.executeQuery(sql) ;
        List<T> list = processRS(rs , object) ;
        pool.releaseConnection(connection);
        return list ;
    }

    private static <T> List<T> processRS(ResultSet rs, Class<T> object) throws SQLException, IllegalAccessException, InstantiationException {
        Map<String,Field> colToField = getColToFieldMap(object) ;
        String[] columnNames = getColumnNames(rs) ;
        List<T> list = new ArrayList<T>() ;
        String key ;
        Field value ;
        int size = columnNames.length ;
        while(rs.next()){
            T t = object.newInstance();
            for (int i=0 ; i<size ; i++){
                value = colToField.get(key = columnNames[i]) ;
                if (value == null){
                    continue ;
                }
                if (value.getType() == Integer.class){
                    value.set(t , rs.getInt(key));
                }else if (value.getType() == String.class){
                    value.set(t , rs.getString(key));
                }else if (value.getType() == Long.class){
                    value.set(t , rs.getLong(key));
                }else if (value.getType() == Float.class){
                    value.set(t , rs.getFloat(key));
                }
            }
            list.add(t) ;
        }
        return list ;
    }

    private static String[] getColumnNames(ResultSet rs) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData() ;
        int count = rsmd.getColumnCount() ;
        String[] columnNames = new String[count] ;
        for (int i=0 ; i<count ; i++){
            columnNames[i] = rsmd.getColumnName(i+1) ;
        }
        return columnNames ;
    }

    private static Map<String, Field> getColToFieldMap(Class<?> object) {
        Field[] fields = object.getDeclaredFields() ;
        //列名 -> 属性对象
        Map<String , Field> colToField = new HashMap<String , Field>() ;
        for (int i=0 ; i<fields.length ; i++){
            if (fields[i].isAnnotationPresent(Column.class)){
                Column ic = fields[i].getAnnotation(Column.class) ;
                fields[i].setAccessible(true);
                colToField.put(ic.name() , fields[i]) ;
            }
        }
        return colToField ;
    }

    //insert update delete
    public static int execSql(String sql , Object... params) throws SQLException {
        Connection connection = pool.getConnection() ;
        PreparedStatement psql = connection.prepareStatement(sql);
        for (int i = 1; i <= params.length; i++) {
            if (params[i - 1] instanceof String) {
                psql.setString(i, params[i - 1].toString());
            } else if (params[i - 1] instanceof Double) {
                psql.setDouble(i, Double.parseDouble(params[i - 1].toString()));
            } else if (params[i - 1] instanceof Integer) {
                psql.setInt(i, Integer.parseInt(params[i - 1].toString()));
            } else {
                psql.setString(i, params[i - 1].toString());
            }
        }
        int sum = psql.executeUpdate();
        psql.close();
        pool.releaseConnection(connection);
        return sum;
    }

    public static <T> int execByExample(Example<T> example){
        return 0 ;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40788718/article/details/107373206