package com.yanzuoguang.dao.impl; import com.yanzuoguang.dao.DaoConst; import com.yanzuoguang.dao.TableAnnotation; import com.yanzuoguang.util.helper.StringHelper; import com.yanzuoguang.util.base.MethodField; import com.yanzuoguang.util.base.ObjectHelper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 表结构的基本信息 * * @author 颜佐光 */ public class TableStruct { /** * 表名称 */ private String name; /** * 主键名称 */ private TableFieldVo key; /** * MD5KEY */ private TableFieldVo md5Key; /** * 其他字段 */ private List<TableFieldVo> fields = new ArrayList<TableFieldVo>(); public List<TableFieldVo> getFields() { return fields; } public String getName() { return name; } public void setName(String name) { this.name = name; } public TableFieldVo getKey() { return key; } public TableFieldVo getMd5Key() { return md5Key; } public String getKeyName() { return this.key.inputName; } public String getMD5KeyName() { return md5Key != null ? md5Key.inputName : null; } public Class<?> getKeyType() { return this.key.type; } /** * 构造函数 */ public TableStruct() { this.name = ""; this.key = new TableFieldVo(DaoConst.ID_FIELD); } /** * 通过实体的字段来创建表结构信息 * * @param name 表名称 * @param cls 关联的实体,主键放在第一位,其他字段放到后面;需要注意的是必需和表结构对应起来,会有隐性BUG,比如说在实体中增加了字段,会导致增加修改失败 */ public TableStruct(String name, Class<?> cls) { this.name = name; // 获取实体中的所有字段信息,包含get、set、field HashMap<String, MethodField> fields = ObjectHelper.getTypeField(cls); // 遍历字段 for (Map.Entry<String, MethodField> entry : fields.entrySet()) { // 字段信息获取 MethodField field = entry.getValue(); if (field.field == null && field.getMethod == null) { continue; } String fieldName = field.name; String fieldInputName = field.name; Class<?> fieldType = String.class; TableAnnotation annotation = null; if (field.field != null) { annotation = field.field.getAnnotation(TableAnnotation.class); fieldType = field.field.getType(); } else if (field.getMethod != null) { annotation = field.getMethod.getAnnotation(TableAnnotation.class); fieldType = field.getMethod.getReturnType(); } if (annotation != null) { fieldName = annotation.value(); } TableFieldVo vo = new TableFieldVo(fieldName, fieldInputName, fieldType); // 判断是否属于统计字段 if ("md5key".equals(vo.inputLName)) { this.md5Key = vo; } // 判断是否是主键,获取主键数据类型 if (this.key == null) { this.key = vo; } else { this.fields.add(vo); } } } public TableFieldVo getField(String name) { if (StringHelper.isEmpty(name)) { return null; } for (TableFieldVo fieldVo : this.fields) { if (fieldVo.lName.equals(name.toLowerCase()) || fieldVo.inputLName.equals(name.toLowerCase())) { return fieldVo; } } return null; } /** * 判断是否包含版本号字段 * * @return */ public TableFieldVo getVersion() { return this.getField(DaoConst.VERSON); } /** * 判断是否包含remove字段 * * @return */ private TableFieldVo getRemove() { return this.getField(DaoConst.ISREMOVE); } /** * 通过表结构自动生成SQL语句 * * @return */ public void init(TableSqlCache table) { table.setTable(this); if (!StringHelper.isEmpty(this.name)) { table.add(releaseSqlCreate(), releaseSqlUpdate(), releaseSqlRemove(), releaseSqlLoad()); } } /** * 生成创建的SQL语句 * * @return */ private SqlData releaseSqlCreate() { // 生成添加的SQL语句 String text = DaoConst.INSERT_MODEL.replace(DaoConst.TABLE_CODE, this.name); SqlData sql = new SqlData(DaoConst.CREATE, text); String flag = ""; if (this.getKeyType() == String.class) { sql.addParaConst(this.key.inputName, DaoConst.FIELD_CODE, this.key.name, DaoConst.VALUES_CODE, "?"); flag = ","; } for (TableFieldVo field : this.fields) { sql.addParaConst(field.inputName, DaoConst.FIELD_CODE, flag + field.name, DaoConst.VALUES_CODE, flag + "?"); flag = ","; } return sql; } /** * 生成修改的SQL语句 * * @return */ private SqlData releaseSqlUpdate() { // 生成添加的SQL语句 String text = DaoConst.UPDATE_MODEL.replace(DaoConst.TABLE_CODE, this.name); SqlData sql = new SqlData(DaoConst.UPDATE, text); TableFieldVo removeField = this.getRemove(); TableFieldVo versionField = this.getVersion(); sql.addParaConst(this.key.inputName, DaoConst.FIELD_CODE, "" + this.key.name + "=" + this.key.name, DaoConst.WHERE_CODE, " AND " + this.key.name + "=?"); for (TableFieldVo field : this.fields) { if (field == removeField || field == versionField) { continue; } sql.addParaConst(field.inputName, DaoConst.FIELD_CODE, "," + field.name + "=?"); } if (removeField != null) { sql.addParaConst(removeField.inputName, DaoConst.WHERE_CODE, " AND " + removeField.name + "=0"); } if (versionField != null) { sql.addParaConst(versionField.inputName, DaoConst.FIELD_CODE, "," + versionField.name + "=1+" + versionField.name, DaoConst.WHERE_CODE, " AND " + versionField.name + "=?"); } return sql; } /** * 生成删除的SQL语句 * * @return */ private SqlData releaseSqlRemove() { TableFieldVo removeField = this.getRemove(); TableFieldVo versionField = this.getVersion(); if (removeField != null) { // 生成添加的SQL语句 String text = DaoConst.UPDATE_MODEL.replace(DaoConst.TABLE_CODE, this.name); SqlData sql = new SqlData(DaoConst.REMOVE, text); sql.addCode(DaoConst.FIELD_CODE, removeField.name + "=1"); if (versionField != null) { sql.addCode(DaoConst.FIELD_CODE, "," + versionField.name + "=1+" + versionField.name); } addWhereField(sql, ""); return sql; } else { String text = DaoConst.REMOVE_MODEL.replace(DaoConst.TABLE_CODE, this.name); SqlData sql = new SqlData(DaoConst.REMOVE, text); addWhereField(sql, ""); return sql; } } /** * 生成加载的SQL语句 * * @return */ private SqlData releaseSqlLoad() { // 生成添加的SQL语句 String text = DaoConst.LOAD_MODEL.replace(DaoConst.TABLE_CODE, this.name); SqlData sql = new SqlData(DaoConst.LOAD, text); addWhereField(sql, "a."); return sql; } /** * 当前当前表所有字段的等于SQL语句 * * @param sql */ private void addWhereField(SqlData sql, String tag) { TableFieldVo removeField = this.getRemove(); sql.add(this.key.inputName, " AND " + tag + this.key.name + "=?"); for (TableFieldVo field : this.fields) { sql.add(field.inputName, " AND " + tag + field.name + "=?"); } if (removeField != null) { sql.addConst(DaoConst.ISREMOVE_CONTANS, " AND " + tag + removeField.name + "=0"); } } /** * 生成统计的SQL语句 * * @param sqlTableData 需要生成的实体 * @param whereFields WHERE字段 * @param updateFields 需要增加的值的字段 */ public void addGroupSql(TableSqlCache sqlTableData, TableFieldString whereFields, TableFieldString updateFields) { sqlTableData.add(this.releaseSqlWhere(DaoConst.GROUP_QUERY, DaoConst.LOAD_MODEL, whereFields)); sqlTableData.add(this.releaseSql(DaoConst.GROUP_ADD, DaoConst.UPDATE_MODEL, "{FIELD}={FIELD}+?", updateFields, new TableFieldString(this.key.name))); } /** * 生成SQL语句 * * @param name * @param model * @param whereFields * @return */ public SqlData releaseSqlWhere(String name, String model, TableFieldString whereFields) { return this.releaseSql(name, model, "", new TableFieldString(), whereFields); } /** * 生成SQL语句 * * @param name SQL语句名称 * @param model SQL语句模板 * @param valueModel 值字段模板 * @param valueFields 值字段 * @param whereFields WHERE字段 * @return */ public SqlData releaseSql(String name, String model, String valueModel, TableFieldString valueFields, TableFieldString whereFields) { // 参数字段 List<String> paraFields = new ArrayList<String>(); // 生成添加的SQL语句 StringBuilder sbField = new StringBuilder(); for (String field : valueFields.getFields()) { if (sbField.length() > 0) { sbField.append(","); } sbField.append(valueModel.replace(DaoConst.FIELD_CODE, field)); paraFields.add(field); } StringBuilder sbWhere = new StringBuilder(); for (String field : whereFields.getFields()) { sbWhere.append(" AND "); sbWhere.append(field); sbWhere.append("=?"); paraFields.add(field); } String[] fields = new String[paraFields.size()]; fields = paraFields.toArray(fields); // 生成修改的SQL语句 String sql = model.replace(DaoConst.TABLE_CODE, this.name).replace(DaoConst.FIELD_CODE, sbField.toString()).replace(DaoConst.WHERE_CODE, sbWhere.toString()); SqlData ret = new SqlData(name, sql, fields); return ret; } /** * 生成根据某些字段不存在则保存的SQL语句 * * @param tableStruct * @param sqlName * @param whereFields */ public void addSaveWithSql(TableSqlCache tableStruct, String sqlName, TableFieldString whereFields) { tableStruct.add(this.releaseSqlWhere(sqlName, DaoConst.LOAD_MODEL, whereFields)); } /** * 生成判断数据是否存在的SQL语句 * * @param sqlTableData * @param sqlName * @param fields */ public void addExist(TableSqlCache sqlTableData, String sqlName, String[] fields) { String text = DaoConst.LOAD_MODEL.replace(DaoConst.TABLE_CODE, this.name); SqlData sql = new SqlData(sqlName, text); sql.addPara(this.key.inputName, DaoConst.WHERE_CODE, " AND a." + this.key.name + "<>?"); for (String field : fields) { sql.addParaConst(field, DaoConst.WHERE_CODE, " AND a." + field + "=?"); } if (getRemove() != null) { sql.addParaConst(DaoConst.ISREMOVE_CONTANS, DaoConst.WHERE_CODE, " AND a." + DaoConst.ISREMOVE + "=0"); } sqlTableData.add(sql); } }