package message.jdbc.sql; import message.jdbc.annontations.Cache; import message.jdbc.base.DynamicBeanUtils; import message.utils.ObjectUtils; import message.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.*; /** * 对bean的(字段,类名)(数据库列名,表名)的映射关系构建类. * * @author sunhao(sunhao.java@gmail.com) * @version V1.0 * @createTime 2012-10-8 上午04:25:01 */ public class BeanPersistenceBuilder { private static final Logger logger = LoggerFactory.getLogger(BeanPersistenceBuilder.class); private BeanPersistenceDef beanPersistenceDef; //beanPersistenceDef public BeanPersistenceBuilder(Class<?> clazz) { this.beanPersistenceDef = new BeanPersistenceDef(clazz); } public BeanPersistenceDef build() throws Exception { Class clazz = this.beanPersistenceDef.getClazz(); logger.debug("build class: '{}'", clazz); // 类头上的注解 Annotation[] anns = clazz.getAnnotations(); for (int i = 0; i < anns.length; i++) { Annotation ann = anns[i]; Class type = ann.annotationType(); if (Table.class == type) { // 处理Table注解 evalTable(clazz, (Table) ann); } else if (Cache.class == type) { // 处理Cache注解 evalCache((Cache) ann); } } // 处理字段 List<Field> fields = new ArrayList<Field>(); // 获得类中所有申明的字段 fields.addAll(Arrays.asList(clazz.getDeclaredFields())); // 处理父类 getSubClassFields(clazz.getSuperclass(), fields); for (Field f : fields) { anns = f.getDeclaredAnnotations(); for (Annotation ann : anns) { evalColumn(f, ann); } } buildInsertSql(); buildUpdateSql(); buildSelectSql(); buildDeleteSql(); return this.beanPersistenceDef; } private void getSubClassFields(Class<?> clazz, List<Field> fields) { Class<?> subClass = clazz.getSuperclass(); if (subClass != null && !Object.class.equals(subClass)) { fields.addAll(Arrays.asList(subClass.getDeclaredFields())); getSubClassFields(subClass.getSuperclass(), fields); } } private void evalTable(Class<?> clazz, Table table) { if (logger.isDebugEnabled()) { logger.debug("Class is '{}' and it's annotation table '{}'", clazz.getName(), table); } String name = table.name(); if (StringUtils.isEmpty(name)) { name = DynamicBeanUtils.underscoreName(clazz.getSimpleName()); } // 设置表名 this.beanPersistenceDef.setTableName(name); } private void evalCache(Cache ann) { if (logger.isDebugEnabled()) { logger.debug("annotation Cache '{}'", ann); } this.beanPersistenceDef.setCacheEnable(true); this.beanPersistenceDef.setCacheRegion(ann.cacheRegion()); } private void buildDeleteSql() throws Exception { StringBuilder sql = new StringBuilder(); sql.append("delete from "); sql.append(this.beanPersistenceDef.getTableName()); sql.append(" where 1 = 1 "); if (ObjectUtils.isNotEmpty(this.beanPersistenceDef.getIdClass())) { sql.append(" and ").append(this.beanPersistenceDef.getIdColumnName()).append(" = :") .append(this.beanPersistenceDef.getIdFieldName()); } else { logger.warn("this delete sql '{}' don't has any condition!That will delete all when this sql execute!", sql.toString()); } if (logger.isDebugEnabled()) { logger.debug("delete sql '{}'", sql.toString()); } this.beanPersistenceDef.setDeleteSql(sql.toString()); } private void buildSelectSql() throws Exception { StringBuilder sql = new StringBuilder(); sql.append("select "); List<String> columns = new ArrayList<String>(); if (ObjectUtils.isNotEmpty(this.beanPersistenceDef.getIdClass())) { columns.add(this.beanPersistenceDef.getIdColumnName()); } Map<String, String> fieldColumnMapping = this.beanPersistenceDef.getFieldColumnMapping(); for (Iterator<String> it = fieldColumnMapping.values().iterator(); it.hasNext(); ) { String column = it.next(); columns.add(column); } sql.append(StringUtils.join(columns, ", ")); sql.append(" from ").append(this.beanPersistenceDef.getTableName()); if (ObjectUtils.isNotEmpty(this.beanPersistenceDef.getIdClass())) { sql.append(" where ").append(this.beanPersistenceDef.getIdColumnName()).append(" = :") .append(this.beanPersistenceDef.getIdFieldName()); } if (logger.isDebugEnabled()) { logger.debug("select sql '{}'", sql.toString()); } this.beanPersistenceDef.setSelectSql(sql.toString()); } private void buildUpdateSql() throws Exception { StringBuilder sql = new StringBuilder(); sql.append("update "); sql.append(this.beanPersistenceDef.getTableName()); sql.append(" set "); Map<String, String> fieldColumnMapping = this.beanPersistenceDef.getFieldColumnMapping(); List<String> columns = new ArrayList<String>(); for (Iterator<Map.Entry<String, String>> it = fieldColumnMapping.entrySet().iterator(); it.hasNext(); ) { Map.Entry<String, String> entry = it.next(); String field = entry.getKey(); String column = entry.getValue(); columns.add(column + " = :" + field); } sql.append(StringUtils.join(columns, ", ")).append(" where 1 = 1 "); if (ObjectUtils.isNotEmpty(this.beanPersistenceDef.getIdClass())) { sql.append(" and ").append(this.beanPersistenceDef.getIdColumnName()).append(" = :") .append(this.beanPersistenceDef.getIdFieldName()); } this.beanPersistenceDef.setUpdateSql(sql.toString()); if (logger.isDebugEnabled()) { logger.debug("update sql '{}'", sql.toString()); } this.beanPersistenceDef.setUpdateSql(sql.toString()); } private void buildInsertSql() throws Exception { StringBuilder sql = new StringBuilder(); sql.append("insert into "); sql.append(this.beanPersistenceDef.getTableName()); Map<String, String> fieldColumnMapping = this.beanPersistenceDef.getFieldColumnMapping(); List<String> columns = new ArrayList<String>(); List<String> values = new ArrayList<String>(); if (ObjectUtils.isNotEmpty(this.beanPersistenceDef.getIdClass())) { columns.add(this.beanPersistenceDef.getIdColumnName()); values.add(":" + this.beanPersistenceDef.getIdFieldName()); } for (Iterator<Map.Entry<String, String>> it = fieldColumnMapping.entrySet().iterator(); it.hasNext(); ) { Map.Entry<String, String> entry = it.next(); String field = entry.getKey(); String column = entry.getValue(); columns.add(column); values.add(":" + field); } sql.append(" (").append(StringUtils.join(columns, ", ")).append(") values (") .append(StringUtils.join(values, ", ")).append(")"); if (logger.isDebugEnabled()) logger.debug("insert sql '{}'", sql.toString()); this.beanPersistenceDef.setInsertSql(sql.toString()); } private void evalColumn(Field field, Annotation ann) { if (field == null || ann == null) { logger.debug("field or ann is null!"); return; } logger.debug("field '{}' annotation is '{}'", field.getName(), ann); Class annType = ann.annotationType(); if (Id.class.equals(annType)) { // 主键 String idFieldName = field.getName(); String idColumnName = DynamicBeanUtils.underscoreName(idFieldName); this.beanPersistenceDef.setIdClass(field.getType()); this.beanPersistenceDef.setIdFieldName(idFieldName); this.beanPersistenceDef.setIdColumnName(idColumnName); } else if (GeneratedValue.class.equals(annType)) { GeneratedValue gv = (GeneratedValue) ann; this.beanPersistenceDef.setGenerator(gv.generator()); } else if (Column.class.equals(annType)) { Column column = (Column) ann; // 普通字段 String fieldName = field.getName(); String columnName = column.name(); if (StringUtils.isEmpty(columnName)) { columnName = DynamicBeanUtils.underscoreName(fieldName); } this.beanPersistenceDef.addFieldColumnMapping(fieldName, columnName); } } }