Hana数据库,Java连接池

 SAP Hana是个内存数据库

驱动

        <dependency>
            <groupId>com.sap.cloud.db.jdbc</groupId>
            <artifactId>ngdbc</artifactId>
            <version>2.4.64</version>
        </dependency>
package com.df.rpc.jdbc;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;

/**
 * 原生的jdbc连接池
 */

@SuppressWarnings("all")
@Slf4j
@Component
public class HanaJDBCPool implements DataSource {

    private static LinkedList<Connection> listConnections = new LinkedList<Connection>();

    @Value("${hana.db.driver}")
    String driver;
    @Value("${hana.db.url}")
    String url;
    @Value("${hana.db.username}")
    String username;
    @Value("${hana.db.password}")
    String password;

    @Value("${hana.db.initsize}")
    Integer jdbcPoolInitSize;

    @Value("${hana.db.poolmax}")
    Integer jdbcPoolMax;//必须大于init 的两倍

    @PostConstruct
    public void initHanaConnection(){
        try {
            Class.forName(driver);
            for(int i = 0;i< jdbcPoolInitSize;i++){
                Connection conn = DriverManager.getConnection(url, username, password);
                listConnections.add(conn);
            }

        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }


    @Async
    private void createConnection(){
        try {
            Class.forName(driver);
            for(int i = 0;i< jdbcPoolInitSize;i++){
                Connection conn = DriverManager.getConnection(url, username, password);
                listConnections.add(conn);
            }

        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }





    @Override
    public Connection getConnection() throws SQLException {
        if (listConnections.size() <= jdbcPoolMax/2){
            createConnection();
        }

        if (listConnections.size() > 0) {
            Connection conn1 = listConnections.removeFirst();
            log.debug("linkedlist1数据库连接池大小是" + listConnections.size());
            return (Connection) Proxy.newProxyInstance(conn1.getClass().getClassLoader(),
                    new Class[]{Connection.class}, new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            if (!method.getName().equalsIgnoreCase("close")) {
                                return method.invoke(conn1, args);
                            } else {
                                listConnections.add(conn1);
                                log.debug(conn1 + "对象被释放,重新放回linkedlist集合中!");
                                log.debug("此时Linkedlist集合中有" + listConnections.size() + "个数据库连接对象!");
                                return null;
                            }
                        }
                    });
        } else {
            log.error(url +" 连接数据库失败!");
        }
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }



}
package com.df.rpc.jdbc;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


@SuppressWarnings("all")
@Slf4j
@Component
public class HanaJDBCRpc {

    @Autowired
    private HanaJDBCPool pool;


    /**
     *  * 获取资源
     */
    public Connection getConnection() throws SQLException {
        return pool.getConnection();
    }
    /**
     *  * 关闭资源
     *  * @param resultSet 查询返回的结果集,没有为空
     *  * @param statement
     *  * @param connection
     */
    public void close(ResultSet resultSet, Statement statement, Connection connection) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            resultSet = null;
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }


}

查询结果包装 

package com.df.rpc.utils;


import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据库查询结果POJO转换
 *
 * @author chenyl
 */
public class HanaDbUtil {
    private static final char SEPARATOR = '_';

    public static <T> T toBean(Class<T> clazz, ResultSet rs) throws Exception {
        if (!rs.next()) {
            return null;
        }
        T t = clazz.newInstance();
        ResultSetMetaData rsmd = rs.getMetaData();
        int len = rsmd.getColumnCount();
        Map<String, Method> mm = getSetMethod(clazz);
        for (int i = 1; i <= len; i++) {
            String label = rsmd.getColumnLabel(i);
            Method m = mm.get(lineToCamel(label, true));
            if (m != null) {
                m.invoke(t, rs.getObject(label));
            }
        }
        return t;
    }

    public static Map<String, Object> toMap(ResultSet rs) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        if (!rs.next()) {
            return null;
        }
        ResultSetMetaData rsmd = rs.getMetaData();
        int len = rsmd.getColumnCount();
        for (int i = 1; i <= len; i++) {
            String label = rsmd.getColumnLabel(i);
            map.put(lineToCamel(label, false), rs.getObject(label));
        }
        return map;
    }

    public static Map<String, Object> toStrMap(ResultSet rs) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        if (!rs.next()) {
            return null;
        }
        ResultSetMetaData rsmd = rs.getMetaData();
        int len = rsmd.getColumnCount();
        for (int i = 1; i <= len; i++) {
            String label = rsmd.getColumnLabel(i);
            Object obj = rs.getObject(label);
            if (obj instanceof java.sql.Timestamp) {
                java.sql.Timestamp ts = (java.sql.Timestamp) obj;
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                map.put(lineToCamel(label, false), format.format(new Date(ts.getTime())));
            } else if (obj instanceof java.util.Date) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                map.put(lineToCamel(label, false), format.format((Date) obj));
            } else {
                map.put(lineToCamel(label, false), rs.getString(label));
            }
        }
        return map;
    }

    public static <T> List<T> toList(Class<T> clazz, ResultSet rs) throws Exception {
        List<T> list = new ArrayList<T>();
        while (true) {
            T t = toBean(clazz, rs);
            if (t == null) {
                break;
            }
            list.add(t);
        }
        return list;
    }

    public static List toList(ResultSet rs) throws Exception {
        List list = new ArrayList();
        while (true) {
            Map m = toMap(rs);
            if (m == null) {
                break;
            }
            list.add(m);
        }
        return list;
    }

    public static List toStrList(ResultSet rs) throws Exception {
        List list = new ArrayList();
        while (true) {
            Map m = toStrMap(rs);
            if (m == null) {
                break;
            }
            list.add(m);
        }
        return list;
    }

    private static Map<String, Method> getSetMethod(Class<?> clazz) {
        Map<String, Method> map = new HashMap<String, Method>();
        Method[] array = clazz.getMethods();
        int len = array.length;
        for (int i = 0; i < len; i++) {
            Method m = array[i];
            if (m.getName().startsWith("set") && m.getParameterTypes().length == 1) {
                map.put(m.getName().substring(3), m);
            }
        }
        return map;
    }

    public static String lineToCamel(String str, boolean firstUpperCase) {
        if (str == null || str.length() == 0) {
            return str;
        }
        str = str.toLowerCase();
        int len = str.length();
        StringBuffer sb = new StringBuffer();
        boolean upperCase = firstUpperCase;
        for (int i = 0; i < len; i++) {
            char c = str.charAt(i);
            if (c == SEPARATOR) {
                upperCase = true;
                continue;
            }
            if (upperCase) {
                sb.append(Character.toUpperCase(str.charAt(i)));
                upperCase = false;
            } else {
                sb.append(str.charAt(i));
            }
        }
        return sb.toString();
    }

    public static String camelToLine(String str) throws Exception {
        if (str == null || str.length() == 0) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        boolean nextIsUpperCase = false;
        int len = str.length();
        for (int i = 0; i < len; i++) {
            char c = str.charAt(i);
            if (i < len - 1) {
                nextIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            } else {
                nextIsUpperCase = false;
            }
            if (Character.isLowerCase(c) && nextIsUpperCase) {
                if (i < len - 1) {
                    sb.append(c).append(SEPARATOR).append(Character.toLowerCase(str.charAt(i + 1)));
                    i++;
                } else {
                    sb.append(c).append(SEPARATOR);
                }

            } else if (Character.isUpperCase(c) && !nextIsUpperCase && i > 0) {
                sb.append(SEPARATOR).append(Character.toLowerCase(str.charAt(i)));
            } else {
                sb.append(Character.toLowerCase(c));
            }

        }
        return sb.toString();
    }


    public static void close(ResultSet rs) throws SQLException {
        if (rs != null) {
            rs.close();
        }
    }

    public static void close(Connection conn) throws SQLException {
        if (conn != null) {
            conn.close();
        }
    }
}

配置文件

hana.db.name=poc-hana
hana.db.driver = com.sap.db.jdbc.Driver
#jdbc:sap://192.168.0.102:39015??DatabaseName=HXE&reconnect=true
hana.db.url=jdbc:sap://192.168.1.5:39015?reconnect=true
hana.db.username=SYSTEM
hana.db.password=Hana2021@123
hana.db.initsize=5
#必须大于init 的两倍
hana.db.poolmax=12

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值