Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
kim.zkp.quick.orm.connection.ConnectionProcessor Maven / Gradle / Ivy
/**
* Copyright (c) 2017, ZhuKaipeng 朱开鹏 ([email protected] ).
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kim.zkp.quick.orm.connection;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;
import kim.zkp.quick.orm.annotation.Join;
import kim.zkp.quick.orm.cache.ClassCache;
import kim.zkp.quick.orm.exception.ConnectionException;
import kim.zkp.quick.orm.exception.ConnectionExceptionCount;
import kim.zkp.quick.orm.exception.ExecuteSqlException;
import kim.zkp.quick.orm.exception.TransactionException;
import kim.zkp.quick.orm.model.Schema;
import kim.zkp.quick.orm.sql.SqlInfo;
import kim.zkp.quick.orm.sql.convert.FieldConvertProcessor;
public class ConnectionProcessor {
private static final Log log = LogFactory.get();
private DataSource dataSource;
private JDBCConfig jdbcConfig;
public ConnectionProcessor(JDBCConfig jdbcConfig) {
super();
this.jdbcConfig = jdbcConfig;
this.dataSource = new QuickDataSource(jdbcConfig);
}
public DataSource getDataSource(){
return dataSource;
}
public Connection getConnection(){
try {
// Connection conn = SingleThreadConnectionHolder.getConnection(dataSource);
// if (conn == null || conn.isClosed()) {
// conn = dataSource.getConnection();
// SingleThreadConnectionHolder.setConnection(dataSource, conn);
// }
// return conn;
return dataSource.getConnection();
} catch (SQLException e) {
throw new ConnectionException("Get db connection error",e);
}
}
public void setAutoCommit(Connection conn,boolean commit){
try {
conn.setAutoCommit(commit);
} catch (SQLException e) {
ConnectionExceptionCount.add(conn);
throw new TransactionException("Open transaction error",e);
}
}
public void rollback(Connection conn){
try {
conn.rollback();
} catch (SQLException e) {
throw new TransactionException("Rollback transaction error",e);
}
}
public void commit(Connection conn){
try {
conn.commit();
} catch (SQLException e) {
throw new TransactionException("Commit transaction error",e);
}
}
public void close(Connection conn){
try {
conn.setAutoCommit(true);
release(conn);
} catch (SQLException e) {
ConnectionExceptionCount.destroy(conn);//有事务的连接关闭出现异常直接废弃
log.error(e, "Close connection error");
try {
conn.close();
} catch (SQLException e1) {
throw new TransactionException("Close transaction error",e1);
}
throw new TransactionException("Close transaction error",e);
}
// try {
// SingleThreadConnectionHolder.removeConnection(conn);
// conn.setAutoCommit(true);
// conn.close();
// } catch (SQLException e) {
// log.error(e, "Close connection error");
// try {
// conn.close();
// } catch (SQLException e1) {
// throw new TransactionException("Close2 transaction error",e1);
// }
// throw new TransactionException("Close transaction error",e);
// }
}
public int update(Connection conn, SqlInfo sqlInfo) {
PreparedStatementWrapper stmt = null;
try {
stmt = createPreparedStatement(conn, sqlInfo);
return stmt.executeUpdate();
} catch (SQLException e) {
// log.error(e, "execute sql error");
throw new ExecuteSqlException(e);
} finally {
close(stmt);
release(conn);
}
}
public Object get(Connection conn, SqlInfo sqlInfo,Class> clzz) {
List list = list(conn, sqlInfo, clzz);
if (list == null || list.size()==0) {
if (clzz.isAssignableFrom(Schema.class)) {
return Schema.open();
}
return null;
}
if (list.size()==1) {
return list.get(0);
}
throw new ExecuteSqlException("Query out multiple results!");
}
public List list(Connection conn, SqlInfo sqlInfo,Class> clzz) {
PreparedStatementWrapper stmt = null;
ResultSet rs = null;
try {
stmt = createPreparedStatement(conn, sqlInfo);
rs = stmt.executeQuery();
return parseResultSetToObject(rs,clzz,sqlInfo);
} catch (Exception e) {
throw new ExecuteSqlException(e);
} finally {
close(stmt);
close(rs);
release(conn);
}
}
private PreparedStatementWrapper createPreparedStatement(Connection conn, SqlInfo sqlInfo) throws SQLException {
if (jdbcConfig.getPrintSql()) {
log.info("execute sql:{}", sqlInfo.getSql());
log.info("params:{}", sqlInfo.getParam());
}
PreparedStatement stmt;
try {
stmt = conn.prepareStatement(sqlInfo.getSql());
} catch (SQLException e) {
ConnectionExceptionCount.add(conn);
throw new ExecuteSqlException(e);
}
List params = sqlInfo.getParam();
for (int i = 0; i < params.size(); i++) {
try {
stmt.setObject(i + 1, params.get(i));
} catch (Exception e) {
log.error(e);
throw new ExecuteSqlException("Setting sql param error",e);
}
}
return new PreparedStatementWrapper(stmt, sqlInfo,jdbcConfig.getExecuteTimeMonitor(),jdbcConfig.getMaxExecuteTime());
}
private List parseResultSetToObject(ResultSet rs,Class> clzz, SqlInfo sqlInfo) {
List list = new ArrayList<>();
try {
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
while (rs.next()) {
Map result = new HashMap<>();
for (int i = 0; i < count; i++) {
String columnLabel = rsmd.getColumnLabel(i + 1);
Object value = rs.getObject(i + 1);
result.put(columnLabel, value);
}
Object o = toJavaObject(result, clzz, sqlInfo);
list.add(o);
}
return list;
} catch (SQLException e) {
throw new ExecuteSqlException(e);
}
}
private Object toJavaObject(Map result,Class> clzz, SqlInfo sqlInfo){
try {
if (clzz.isAssignableFrom(Map.class)) {
return result;
}
if (clzz.isAssignableFrom(Schema.class)) {
Schema s = Schema.open("");
s.setResult(result);
return s;
}
if (clzz.isAssignableFrom(Short.class)) {
if(result.keySet().size() != 1){
throw new ExecuteSqlException("Query out result is not the "+clzz.getSimpleName());
}
return Short.parseShort(result.get(result.keySet().toArray()[0]).toString());
}
if (clzz.isAssignableFrom(Float.class)) {
if(result.keySet().size() != 1){
throw new ExecuteSqlException("Query out result is not the "+clzz.getSimpleName());
}
return Float.parseFloat(result.get(result.keySet().toArray()[0]).toString());
}
if (clzz.isAssignableFrom(Integer.class)) {
if(result.keySet().size() != 1){
throw new ExecuteSqlException("Query out result is not the "+clzz.getSimpleName());
}
return Integer.parseInt(result.get(result.keySet().toArray()[0]).toString());
}
if (clzz.isAssignableFrom(Double.class)) {
if(result.keySet().size() != 1){
throw new ExecuteSqlException("Query out result is not the "+clzz.getSimpleName());
}
return Double.parseDouble(result.get(result.keySet().toArray()[0]).toString());
}
if (clzz.isAssignableFrom(Long.class)) {
if(result.keySet().size() != 1){
throw new ExecuteSqlException("Query out result is not the "+clzz.getSimpleName());
}
return Long.parseLong(result.get(result.keySet().toArray()[0]).toString());
}
if (clzz.isAssignableFrom(BigDecimal.class)) {
if(result.keySet().size() != 1){
throw new ExecuteSqlException("Query out result is not the "+clzz.getSimpleName());
}
return new BigDecimal(result.get(result.keySet().toArray()[0]).toString());
}
if (clzz.isAssignableFrom(String.class)) {
if(result.keySet().size() != 1){
throw new ExecuteSqlException("Query out result is not the "+clzz.getSimpleName());
}
return result.get(result.keySet().toArray()[0]).toString();
}
// log.debug("result:{}",result);
return fillResultObject(clzz, result,true);
} catch (Exception e) {
log.error(e, "query result convert java object error");
}
return null;
}
private Object fillResultObject(Class> clzz, Map result,boolean nextFind){
Object o;
try {
o = clzz.newInstance();
} catch (InstantiationException | IllegalAccessException e1) {
return null;
}
String aliasUnderline = ClassCache.getAliasUnderline(clzz);
List joinAnnotationFields = ClassCache.getJoin(clzz);
List findAnnotationFields = ClassCache.getFind(clzz);
List cachelist = ClassCache.getAllFieldByCache(clzz);
List attrFieldList = new ArrayList<>(cachelist);
attrFieldList.addAll(joinAnnotationFields);
attrFieldList.addAll(findAnnotationFields);
for (Field field : attrFieldList) {
Join join = field.getAnnotation(Join.class);
Object v = null;
if (join != null && nextFind) {
v = fillResultObject(field.getType(), result,false);
}else {
String fieldName = field.getName();
String k = aliasUnderline + fieldName;
v = result.get(k);
if (v == null) {
v = result.get(fieldName);
if (v == null) { //某些数据库返回的字段全为大写
v = result.get(k.toUpperCase());
if (v == null) {
v = result.get(fieldName.toUpperCase());
}
}
}
// log.debug("key:{},value:{}", k,v);
}
if (v != null) {
try {
field.setAccessible(true);
field.set(o, FieldConvertProcessor.toJava(field.getType(),v));
} catch (Exception e) {
log.error(e, "db type to java type error");
}
}
}
return o;
}
private final void release(Connection x) {
if (x != null) {
try {
if (x.getAutoCommit()) {
x.close();
SingleThreadConnectionHolder.removeConnection(dataSource);
}
} catch (Exception e) {//此处若获取事务状态异常,直接移除连接,防止连接占用
SingleThreadConnectionHolder.removeConnection(dataSource);
log.error("close connection error", e);
try {
x.close();
} catch (SQLException e1) {
log.error("close connection error", e1);
}
}
}
}
private final void close(PreparedStatementWrapper x) {
if (x != null) {
try {
x.close();
} catch (Exception e) {
log.error("close statement error", e);
}
}
}
private final void close(ResultSet x) {
if (x != null) {
try {
x.close();
} catch (Exception e) {
log.error("close resultset error", e);
}
}
}
}