Search in sources :

Example 31 with EntityMeta

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);
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult)

Example 32 with EntityMeta

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);
    }
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) Serializable(java.io.Serializable) PreparedStatementResultHandler(org.sagacity.sqltoy.callback.PreparedStatementResultHandler) FieldMeta(org.sagacity.sqltoy.config.model.FieldMeta) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 33 with EntityMeta

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);
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) GenerateSqlHandler(org.sagacity.sqltoy.callback.GenerateSqlHandler) PKStrategy(org.sagacity.sqltoy.config.model.PKStrategy)

Example 34 with EntityMeta

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);
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) GenerateSqlHandler(org.sagacity.sqltoy.callback.GenerateSqlHandler) GenerateSavePKStrategy(org.sagacity.sqltoy.callback.GenerateSavePKStrategy) SavePKStrategy(org.sagacity.sqltoy.dialect.model.SavePKStrategy) GenerateSavePKStrategy(org.sagacity.sqltoy.callback.GenerateSavePKStrategy)

Example 35 with EntityMeta

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);
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) GenerateSavePKStrategy(org.sagacity.sqltoy.callback.GenerateSavePKStrategy) SavePKStrategy(org.sagacity.sqltoy.dialect.model.SavePKStrategy) PKStrategy(org.sagacity.sqltoy.config.model.PKStrategy)

Aggregations

EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)141 SavePKStrategy (org.sagacity.sqltoy.dialect.model.SavePKStrategy)36 PKStrategy (org.sagacity.sqltoy.config.model.PKStrategy)28 GenerateSavePKStrategy (org.sagacity.sqltoy.callback.GenerateSavePKStrategy)24 ArrayList (java.util.ArrayList)23 Serializable (java.io.Serializable)22 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)22 List (java.util.List)20 GenerateSqlHandler (org.sagacity.sqltoy.callback.GenerateSqlHandler)20 GenerateSqlHandler (org.sagacity.sqltoy.dialect.handler.GenerateSqlHandler)13 GenerateSavePKStrategy (org.sagacity.sqltoy.dialect.handler.GenerateSavePKStrategy)12 IOException (java.io.IOException)11 SQLException (java.sql.SQLException)11 HashMap (java.util.HashMap)11 TableCascadeModel (org.sagacity.sqltoy.config.model.TableCascadeModel)10 ReturnPkType (org.sagacity.sqltoy.dialect.model.ReturnPkType)10 OneToManyModel (org.sagacity.sqltoy.config.model.OneToManyModel)8 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)8 Type (java.lang.reflect.Type)6 PreparedStatement (java.sql.PreparedStatement)6