use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class DefaultDialectUtils method deleteAll.
/**
* @todo 批量删除对象
* @param sqlToyContext
* @param entities
* @param batchSize
* @param conn
* @param dbType
* @param autoCommit
* @param tableName
* @return
* @throws Exception
*/
public static Long deleteAll(SqlToyContext sqlToyContext, List<?> entities, final int batchSize, Connection conn, final Integer dbType, final Boolean autoCommit, final String tableName) throws Exception {
if (null == entities || entities.isEmpty()) {
return 0L;
}
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
String realTable = entityMeta.getSchemaTable(tableName, dbType);
if (null == entityMeta.getIdArray() || entityMeta.getIdArray().length == 0) {
throw new IllegalArgumentException("delete/deleteAll 操作,表:" + realTable + "没有主键,请检查表设计!");
}
int idSize = entityMeta.getIdArray().length;
// 构造delete 语句
StringBuilder deleteSql = new StringBuilder();
// clickhouse 删除语法特殊
if (dbType == DBType.CLICKHOUSE) {
deleteSql.append("alter table ");
deleteSql.append(realTable);
deleteSql.append(" delete where ");
} else {
deleteSql.append("delete from ");
deleteSql.append(realTable);
deleteSql.append(" where ");
}
String field;
SqlToyResult sqlToyResult = null;
String colName;
// 单主键
if (idSize == 1) {
Object[] idValues = BeanUtil.sliceToArray(entities, entityMeta.getIdArray()[0]);
if (idValues == null || idValues.length == 0) {
throw new IllegalArgumentException(tableName + " deleteAll method must assign value for pk field:" + entityMeta.getIdArray()[0]);
}
field = entityMeta.getIdArray()[0];
colName = ReservedWordsUtil.convertWord(entityMeta.getColumnName(field), dbType);
deleteSql.append(colName);
deleteSql.append(" in (?) ");
sqlToyResult = SqlConfigParseUtils.processSql(deleteSql.toString(), null, new Object[] { idValues }, null);
} else {
List<Object[]> idValues = BeanUtil.reflectBeansToInnerAry(entities, entityMeta.getIdArray(), null, null);
int dataSize = idValues.size();
Object[] rowData;
Object cellValue;
// 将条件构造成一个数组
Object[] realValues = new Object[idValues.size() * idSize];
int index = 0;
for (int i = 0; i < dataSize; i++) {
rowData = idValues.get(i);
for (int j = 0; j < idSize; j++) {
cellValue = rowData[j];
// 验证主键值是否合法
if (StringUtil.isBlank(cellValue)) {
throw new IllegalArgumentException(tableName + " deleteAll method must assign value for pk,row:" + i + " pk field:" + entityMeta.getIdArray()[j]);
}
realValues[index] = cellValue;
index++;
}
}
// 复合主键构造 (field1=? and field2=?)
String condition = " (";
for (int i = 0, n = idSize; i < n; i++) {
field = entityMeta.getIdArray()[i];
colName = ReservedWordsUtil.convertWord(entityMeta.getColumnName(field), dbType);
if (i > 0) {
condition = condition.concat(" and ");
}
condition = condition.concat(colName).concat("=?");
}
condition = condition.concat(")");
// 构造 (field1=? and field2=?) or (field1=? and field2=?)
for (int i = 0; i < dataSize; i++) {
if (i > 0) {
deleteSql.append(" or ");
}
deleteSql.append(condition);
}
sqlToyResult = SqlConfigParseUtils.processSql(deleteSql.toString(), null, realValues, null);
}
return SqlUtil.executeSql(sqlToyContext.getTypeHandler(), sqlToyResult.getSql(), sqlToyResult.getParamsValue(), null, conn, dbType, autoCommit, false);
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class DefaultDialectUtils method updateSaveFetch.
/**
* @TODO 实现:1、锁查询;2、记录存在则修改;3、记录不存在则执行insert;4、返回修改或插入的记录信息,尽量不要使用identity、sequence主键
* @param sqlToyContext
* @param entity
* @param updateRowHandler
* @param uniqueProps
* @param conn
* @param dbType
* @param dialect
* @param tableName
* @return
* @throws Exception
*/
public static Serializable updateSaveFetch(final SqlToyContext sqlToyContext, final Serializable entity, final UpdateRowHandler updateRowHandler, String[] uniqueProps, final Connection conn, final Integer dbType, String dialect, String tableName) throws Exception {
final EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
// 条件字段
String[] whereFields = uniqueProps;
if (whereFields == null || whereFields.length == 0) {
whereFields = entityMeta.getIdArray();
}
if (whereFields == null || whereFields.length == 0) {
throw new DataAccessException("updateSaveFetch操作的表:" + tableName + " 没有唯一获得一条记录的条件字段,请检查!");
}
// 全部字段的值
Object[] tempFieldValues = null;
// 条件字段值
Object[] whereParamValues = BeanUtil.reflectBeanToAry(entity, whereFields);
for (int i = 0; i < whereParamValues.length; i++) {
// 唯一性属性值存在空,则表示首次插入
if (StringUtil.isBlank(whereParamValues[i])) {
tempFieldValues = processFieldValues(sqlToyContext, entityMeta, entity);
whereParamValues = BeanUtil.reflectBeanToAry(entity, whereFields);
break;
}
}
final Object[] fieldValues = tempFieldValues;
final boolean hasUpdateRow = (updateRowHandler == null) ? false : true;
// 组织select * from table for update 语句
String sql = wrapFetchSql(entityMeta, dbType, whereFields, tableName);
SqlExecuteStat.showSql("执行锁记录查询", sql, whereParamValues);
// 可编辑结果集
PreparedStatement pst = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
List updateResult = (List) SqlUtil.preparedStatementProcess(whereParamValues, pst, null, new PreparedStatementResultHandler() {
@Override
public void execute(Object rowData, PreparedStatement pst, ResultSet rs) throws Exception {
SqlUtil.setParamsValue(sqlToyContext.getTypeHandler(), conn, dbType, pst, (Object[]) rowData, null, 0);
// 执行类似 select xxx from table for update(sqlserver语法有差异)
rs = pst.executeQuery();
int rowCnt = rs.getMetaData().getColumnCount();
int index = 0;
List result = new ArrayList();
while (rs.next()) {
if (index > 0) {
throw new DataAccessException("updateSaveFetch操作只能针对单条记录进行操作,请检查uniqueProps参数设置!");
}
// 存在修改记录
if (hasUpdateRow) {
SqlExecuteStat.debug("执行updateRow", "记录存在调用updateRowHandler.updateRow!");
// 执行update反调,实现锁定行记录值的修改
updateRowHandler.updateRow(rs, index);
// 执行update
rs.updateRow();
}
index++;
// 重新获得修改后的值
result.add(ResultUtils.processResultRow(rs, 0, rowCnt, false));
}
// 没有查询到记录,表示是需要首次插入
if (index == 0) {
SqlExecuteStat.debug("执行insertRow", "查询未匹配到结果则进行首次插入!");
// 移到插入行
rs.moveToInsertRow();
FieldMeta fieldMeta;
Object[] fullFieldvalues = (fieldValues == null) ? processFieldValues(sqlToyContext, entityMeta, entity) : fieldValues;
Object fieldValue;
for (int i = 0; i < entityMeta.getFieldsArray().length; i++) {
fieldMeta = entityMeta.getFieldMeta(entityMeta.getFieldsArray()[i]);
if (fieldMeta.isPK()) {
fieldValue = fullFieldvalues[i];
} else {
fieldValue = SqlUtilsExt.getDefaultValue(fullFieldvalues[i], fieldMeta.getDefaultValue(), fieldMeta.getType(), fieldMeta.isNullable());
}
// 插入设置具体列的值
if (fieldValue != null) {
rs.updateObject(fieldMeta.getColumnName(), fieldValue);
}
}
// 执行插入
rs.insertRow();
}
this.setResult(result);
}
});
// 记录不存在首次保存,返回entity自身
if (updateResult == null || updateResult.isEmpty()) {
return entity;
} else {
List entities = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), updateResult, entityMeta.getFieldsArray(), entity.getClass());
return (Serializable) entities.get(0);
}
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class PostgreSqlDialect method update.
/*
* (non-Javadoc)
*
* @see org.sagacity.sqltoy.dialect.Dialect#update(org.sagacity.sqltoy.
* SqlToyContext, java.io.Serializable, java.lang.String[], boolean,
* java.lang.Class[], java.util.HashMap, java.sql.Connection)
*/
@Override
public Long update(SqlToyContext sqlToyContext, Serializable entity, String[] forceUpdateFields, boolean cascade, Class[] emptyCascadeClasses, HashMap<Class, String[]> subTableForceUpdateProps, Connection conn, final Integer dbType, final String dialect, final String tableName) throws Exception {
return DialectUtils.update(sqlToyContext, entity, NVL_FUNCTION, forceUpdateFields, cascade, (cascade == false) ? null : new GenerateSqlHandler() {
@Override
public String generateSql(EntityMeta entityMeta, String[] forceUpdateFields) {
PKStrategy pkStrategy = entityMeta.getIdStrategy();
String sequence = "nextval('" + entityMeta.getSequence() + "')";
if (pkStrategy != null && pkStrategy.equals(PKStrategy.IDENTITY)) {
// 伪造成sequence模式
pkStrategy = PKStrategy.SEQUENCE;
sequence = "DEFAULT";
}
boolean isAssignPK = PostgreSqlDialectUtils.isAssignPKValue(pkStrategy);
return PostgreSqlDialectUtils.getSaveOrUpdateSql(dbType, entityMeta, pkStrategy, isAssignPK, sequence, forceUpdateFields, null);
}
}, emptyCascadeClasses, subTableForceUpdateProps, conn, dbType, tableName);
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class SqliteDialect method save.
/*
* (non-Javadoc)
*
* @see org.sagacity.sqltoy.dialect.Dialect#save(org.sagacity.sqltoy.
* SqlToyContext , java.io.Serializable, java.util.List, java.sql.Connection)
*/
@Override
public Object save(SqlToyContext sqlToyContext, Serializable entity, Connection conn, final Integer dbType, final String dialect, final String tableName) throws Exception {
// sqlite 只提供autoincrement 机制,即identity模式,所以sequence可以忽略
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
boolean isAssignPk = SqliteDialectUtils.isAssignPKValue(entityMeta.getIdStrategy());
String insertSql = DialectExtUtils.generateInsertSql(dbType, entityMeta, entityMeta.getIdStrategy(), NVL_FUNCTION, "NEXTVAL FOR " + entityMeta.getSequence(), isAssignPk, tableName);
return DialectUtils.save(sqlToyContext, entityMeta, entityMeta.getIdStrategy(), isAssignPk, ReturnPkType.PREPARD_ID, insertSql, entity, new GenerateSqlHandler() {
@Override
public String generateSql(EntityMeta entityMeta, String[] forceUpdateField) {
return DialectExtUtils.generateInsertSql(dbType, entityMeta, entityMeta.getIdStrategy(), NVL_FUNCTION, "NEXTVAL FOR " + entityMeta.getSequence(), SqliteDialectUtils.isAssignPKValue(entityMeta.getIdStrategy()), null);
}
}, new GenerateSavePKStrategy() {
@Override
public SavePKStrategy generate(EntityMeta entityMeta) {
return new SavePKStrategy(entityMeta.getIdStrategy(), SqliteDialectUtils.isAssignPKValue(entityMeta.getIdStrategy()));
}
}, conn, dbType);
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class PostgreSqlDialectUtils method saveAll.
/**
* @todo 批量保存对象入数据库
* @param sqlToyContext
* @param entities
* @param batchSize
* @param reflectPropsHandler
* @param conn
* @param dbType
* @param autoCommit
* @param tableName
* @return
* @throws Exception
*/
public static Long saveAll(SqlToyContext sqlToyContext, List<?> entities, final int batchSize, ReflectPropsHandler reflectPropsHandler, Connection conn, final Integer dbType, final Boolean autoCommit, String tableName) throws Exception {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
PKStrategy pkStrategy = entityMeta.getIdStrategy();
String sequence = "nextval('" + entityMeta.getSequence() + "')";
// identity模式用关键词default 代替
if (pkStrategy != null && pkStrategy.equals(PKStrategy.IDENTITY)) {
// 伪造成sequence模式
pkStrategy = PKStrategy.SEQUENCE;
sequence = "DEFAULT";
}
boolean isAssignPK = isAssignPKValue(pkStrategy);
String insertSql = DialectExtUtils.generateInsertSql(dbType, entityMeta, pkStrategy, NVL_FUNCTION, sequence, isAssignPK, tableName);
return DialectUtils.saveAll(sqlToyContext, entityMeta, pkStrategy, isAssignPK, insertSql, entities, batchSize, reflectPropsHandler, conn, dbType, autoCommit);
}
Aggregations