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.
package com.litongjava.db.activerecord;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.jfinal.kit.StrKit;
/**
* DbKit
*/
@SuppressWarnings("rawtypes")
public final class DbKit {
public static final int DB_BATCH_COUNT = 1024;
/**
* The main Config object for system
*/
static Config config = null;
static List replicaConfigs = null;
/**
* 1: For ActiveRecordPlugin.useAsDataTransfer(...) 用于分布式场景 2: For
* Model.getAttrsMap()/getModifyFlag() and Record.getColumnsMap() while the
* ActiveRecordPlugin not start or the Exception throws of
* HashSessionManager.restorSession(..) by Jetty
*/
static Config brokenConfig = Config.createBrokenConfig();
static List brokenConfigs = null;
private static Map, Config> modelToConfig = new HashMap, Config>(512, 0.5F);
private static Map configNameToConfig = new HashMap(32, 0.25F);
static final Object[] NULL_PARA_ARRAY = new Object[0];
public static final String MAIN_CONFIG_NAME = "main";
public static final String REPLICA_CONFIG_NAME = "replica";
public static final int DEFAULT_TRANSACTION_LEVEL = Connection.TRANSACTION_REPEATABLE_READ;
private DbKit() {
}
/**
* Add Config object
*
* @param config the Config contains DataSource, Dialect and so on
*/
public static void addConfig(Config config) {
if (config == null) {
throw new IllegalArgumentException("Config can not be null");
}
if (configNameToConfig.containsKey(config.getName())) {
throw new IllegalArgumentException("Config already exists: " + config.getName());
}
configNameToConfig.put(config.getName(), config);
/**
* Replace the main config if current config name is MAIN_CONFIG_NAME
*/
if (MAIN_CONFIG_NAME.equals(config.getName())) {
DbKit.config = config;
Db.init(DbKit.config.getName());
}
/**
* The configName may not be MAIN_CONFIG_NAME, the main config have to set the
* first comming Config if it is null
*/
if (DbKit.config == null) {
DbKit.config = config;
Db.init(DbKit.config.getName());
}
}
public static void addReplicaConfigs(List configs) {
for (Config config : configs) {
if (config == null) {
throw new IllegalArgumentException("Config can not be null");
}
if (configNameToConfig.containsKey(config.getName())) {
throw new IllegalArgumentException("Config already exists: " + config.getName());
}
configNameToConfig.put(config.getName(), config);
}
/**
* The configName may not be MAIN_CONFIG_NAME, the main config have to set the
* first comming Config if it is null
*/
replicaConfigs = configs;
Db.initReplicas(replicaConfigs);
}
public static Config removeConfig(String configName) {
if (DbKit.config != null && DbKit.config.getName().equals(configName)) {
// throw new RuntimeException("Can not remove the main config.");
DbKit.config = null;
}
Db.removeDbProWithConfig(configName);
return configNameToConfig.remove(configName);
}
static void addModelToConfigMapping(Class extends Model> modelClass, Config config) {
modelToConfig.put(modelClass, config);
}
public static Config getConfig() {
return config;
}
public static Config getConfig(String configName) {
return configNameToConfig.get(configName);
}
public static Config getConfig(Class extends Model> modelClass) {
return modelToConfig.get(modelClass);
}
static final void close(ResultSet rs, Statement st) throws SQLException {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
}
static final void close(ResultSet rs) throws SQLException {
if (rs != null) {
rs.close();
}
}
static final void close(Statement st) throws SQLException {
if (st != null) {
st.close();
}
}
public static Set> getConfigSet() {
return configNameToConfig.entrySet();
}
@SuppressWarnings("unchecked")
public static Class extends Model> getUsefulClass(Class extends Model> modelClass) {
// com.demo.blog.Blog$$EnhancerByCGLIB$$69a17158
// return (Class extends
// Model>)((modelClass.getName().indexOf("EnhancerByCGLIB") == -1 ? modelClass :
// modelClass.getSuperclass()));
// return (Class extends Model>)(modelClass.getName().indexOf("$$EnhancerBy")
// == -1 ? modelClass : modelClass.getSuperclass());
String n = modelClass.getName();
return (Class extends Model>) (n.indexOf("_$$_") > -1 || n.indexOf("$$Enhancer") > -1 ? modelClass.getSuperclass() : modelClass);
}
/**
* 原有框架方法更新只会取modelList第一个元素的字段状态,批量更新的SQL全部相同,只是参数值不同
* 本方法会根据modelList中所有元素,生成不同的SQL和参数,分批分别执行 自动过滤所有null值属性
*
* @param modelList
* @param batchSize
* @param db 使用的数据源,为空时使用默认
* @return
* @see :https://jfinal.com/share/2629
*/
@SuppressWarnings("unchecked")
public static List batchListUpdate(List extends Model> modelList, int batchSize, String db) {
if (modelList == null || modelList.size() == 0)
return new ArrayList<>();
Map modelUpdateMap = new HashMap<>();
for (Model model : modelList) {
Set modifyFlag = CPI.getModifyFlag(model);
Config config = CPI.getConfig(model);
Table table = TableMapping.me().getTable(model.getClass());
String[] pKeys = table.getPrimaryKey();
Map attrs = CPI.getAttrs(model);
List attrNames = new ArrayList<>();
// the same as the iterator in Dialect.forModelSave() to ensure the order of the
// attrs
for (Map.Entry e : attrs.entrySet()) {
String attr = e.getKey();
if (modifyFlag.contains(attr) && !config.getDialect().isPrimaryKey(attr, pKeys) && table.hasColumnLabel(attr))
attrNames.add(attr);
}
for (String pKey : pKeys)
attrNames.add(pKey);
String columns = StrKit.join(attrNames.toArray(new String[attrNames.size()]), ",");
BatchInfo updateInfo = modelUpdateMap.get(columns);
if (updateInfo == null) {
updateInfo = new BatchInfo();
updateInfo.list = new ArrayList<>();
StringBuilder sql = new StringBuilder();
config.getDialect().forModelUpdate(TableMapping.me().getTable(model.getClass()), attrs, modifyFlag, sql, new ArrayList<>());
updateInfo.sql = sql.toString();
modelUpdateMap.put(columns, updateInfo);
}
updateInfo.list.add(model);
}
return batchModelList(modelList, batchSize, db, modelUpdateMap);
}
public static List batchListUpdate(List extends Model> modelList) {
return batchListUpdate(modelList, DB_BATCH_COUNT, null);
}
public static List batchListUpdate(List extends Model> modelList, String db) {
return batchListUpdate(modelList, DB_BATCH_COUNT, db);
}
private static List batchModelList(List list, int batchSize, String db, Map modelUpdateMap) {
List ret = new ArrayList<>(list.size());
DbPro dbPro;
if (StrKit.isBlank(db)) {
dbPro = Db.use();
} else {
dbPro = Db.use(db);
}
// 批量更新
for (Map.Entry entry : modelUpdateMap.entrySet()) {
int[] batch = dbPro.batch(entry.getValue().sql, entry.getKey(), entry.getValue().list, batchSize);
for (int i : batch) {
ret.add(i);
}
}
return ret;
}
/**
* 原有框架方法更新只会取modelList第一个元素的字段状态,批量插入的SQL全部相同,只是参数值不同
* 本方法会根据modelList中所有元素,生成不同的SQL和参数,分批分别执行 自动过滤所有null值属性
*
* @param modelList
* @param batchSize
* @param db 使用的数据源,为空时使用默认
* @return
* @see :https://jfinal.com/share/2629
*/
@SuppressWarnings("unchecked")
public static List batchListSave(List extends Model> modelList, int batchSize, String db) {
if (modelList == null || modelList.size() == 0)
return new ArrayList<>();
Map modelUpdateMap = new HashMap<>();
for (Model model : modelList) {
Config config = CPI.getConfig(model);
Map attrs = CPI.getAttrs(model);
int index = 0;
StringBuilder columns = new StringBuilder();
// the same as the iterator in Dialect.forModelSave() to ensure the order of the
// attrs
for (Map.Entry e : attrs.entrySet()) {
if (index++ > 0) {
columns.append(',');
}
columns.append(e.getKey());
}
String cs = columns.toString();
BatchInfo batchInfo = modelUpdateMap.get(cs);
if (batchInfo == null) {
batchInfo = new BatchInfo();
batchInfo.list = new ArrayList<>();
StringBuilder sql = new StringBuilder();
config.getDialect().forModelSave(TableMapping.me().getTable(model.getClass()), attrs, sql, new ArrayList());
batchInfo.sql = sql.toString();
modelUpdateMap.put(cs, batchInfo);
}
batchInfo.list.add(model);
}
return batchModelList(modelList, batchSize, db, modelUpdateMap);
}
public static List batchListSave(List extends Model> modelList) {
return batchListSave(modelList, DB_BATCH_COUNT, null);
}
public static List batchListSave(List extends Model> modelList, String db) {
return batchListSave(modelList, DB_BATCH_COUNT, db);
}
@SuppressWarnings("unchecked")
public static List batchListSave(String tableName, List extends Record> recordList, int batchSize, String db) {
if (recordList == null || recordList.size() == 0)
return new ArrayList<>();
Map updateMap = new HashMap<>();
for (Record record : recordList) {
Map attrs = record.getColumns();
int index = 0;
StringBuilder columns = new StringBuilder();
// the same as the iterator in Dialect.forModelSave() to ensure the order of the
// attrs
for (Map.Entry e : attrs.entrySet()) {
if (index++ > 0) {
columns.append(',');
}
columns.append(e.getKey());
}
String cs = columns.toString();
BatchInfo batchInfo = updateMap.get(cs);
if (batchInfo == null) {
batchInfo = new BatchInfo();
batchInfo.list = new ArrayList<>();
StringBuilder sql = new StringBuilder();
Db.use().getConfig().getDialect().forDbSave(tableName, new String[0], record, sql, new ArrayList<>());
batchInfo.sql = sql.toString();
updateMap.put(cs, batchInfo);
}
batchInfo.list.add(record);
}
return batchModelList(recordList, batchSize, db, updateMap);
}
public static List batchListSave(String tableName, List extends Record> recordList) {
return batchListSave(tableName, recordList, DB_BATCH_COUNT, null);
}
/**
* 设置IN查询的sql和参数
*
* @param paras
* @param sb
* @param inParas
* @return
*/
public static StringBuilder buildInSqlPara(List