Java tutorial
/* * The MIT License (MIT) * * Copyright (c) 2014 abel533@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.github.abel533.mapperhelper; import org.apache.commons.beanutils.BeanUtils; import javax.persistence.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * - ??? * <p/> * <p>? : <a href="https://github.com/abel533/Mapper" target="_blank">https://github.com/abel533/Mapper</a></p> * * @author liuzh */ public class EntityHelper { /** * ?? */ public static class EntityTable { private String name; private String catalog; private String schema; private StringBuilder orderByClause; // => private Set<EntityColumn> entityClassColumns; // => ? private Set<EntityColumn> entityClassPKColumns; //???? private Map<String, String> aliasMap; public void setTable(Table table) { this.name = table.name(); this.catalog = table.catalog(); this.schema = table.schema(); } public String getName() { return name; } public String getCatalog() { return catalog; } public String getSchema() { return schema; } public String getPrefix() { if (catalog != null && catalog.length() > 0) { return catalog; } if (schema != null && schema.length() > 0) { return catalog; } return ""; } public Set<EntityColumn> getEntityClassColumns() { return entityClassColumns; } public Set<EntityColumn> getEntityClassPKColumns() { return entityClassPKColumns; } public Map<String, String> getAliasMap() { return aliasMap; } } /** * ?? */ public static class EntityColumn { private String property; private String column; private Class<?> javaType; private String sequenceName; private boolean id = false; private boolean uuid = false; private boolean identity = false; private String generator; private String orderBy; public String getProperty() { return property; } public void setProperty(String property) { this.property = property; } public String getColumn() { return column; } public void setColumn(String column) { this.column = column; } public Class<?> getJavaType() { return javaType; } public void setJavaType(Class<?> javaType) { this.javaType = javaType; } public String getSequenceName() { return sequenceName; } public void setSequenceName(String sequenceName) { this.sequenceName = sequenceName; } public boolean isId() { return id; } public void setId(boolean id) { this.id = id; } public boolean isUuid() { return uuid; } public void setUuid(boolean uuid) { this.uuid = uuid; } public boolean isIdentity() { return identity; } public void setIdentity(boolean identity) { this.identity = identity; } public String getGenerator() { return generator; } public void setGenerator(String generator) { this.generator = generator; } public String getOrderBy() { return orderBy; } public void setOrderBy(String orderBy) { this.orderBy = orderBy; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; EntityColumn that = (EntityColumn) o; if (id != that.id) return false; if (identity != that.identity) return false; if (uuid != that.uuid) return false; if (column != null ? !column.equals(that.column) : that.column != null) return false; if (generator != null ? !generator.equals(that.generator) : that.generator != null) return false; if (javaType != null ? !javaType.equals(that.javaType) : that.javaType != null) return false; if (orderBy != null ? !orderBy.equals(that.orderBy) : that.orderBy != null) return false; if (property != null ? !property.equals(that.property) : that.property != null) return false; if (sequenceName != null ? !sequenceName.equals(that.sequenceName) : that.sequenceName != null) return false; return true; } @Override public int hashCode() { int result = property != null ? property.hashCode() : 0; result = 31 * result + (column != null ? column.hashCode() : 0); result = 31 * result + (javaType != null ? javaType.hashCode() : 0); result = 31 * result + (sequenceName != null ? sequenceName.hashCode() : 0); result = 31 * result + (id ? 1 : 0); result = 31 * result + (uuid ? 1 : 0); result = 31 * result + (identity ? 1 : 0); result = 31 * result + (generator != null ? generator.hashCode() : 0); result = 31 * result + (orderBy != null ? orderBy.hashCode() : 0); return result; } } /** * => */ private static final Map<Class<?>, EntityTable> entityTableMap = new HashMap<Class<?>, EntityTable>(); /** * ? * * @param entityClass * @return */ public static EntityTable getEntityTable(Class<?> entityClass) { EntityTable entityTable = entityTableMap.get(entityClass); if (entityTable == null) { initEntityNameMap(entityClass); entityTable = entityTableMap.get(entityClass); } if (entityTable == null) { throw new RuntimeException( "?" + entityClass.getCanonicalName() + "??!"); } return entityTable; } /** * ?orderby? * * @param entityClass * @return */ public static StringBuilder getOrderByClause(Class<?> entityClass) { EntityTable table = getEntityTable(entityClass); if (table.orderByClause != null) { return table.orderByClause; } StringBuilder orderBy = new StringBuilder(); for (EntityHelper.EntityColumn column : table.getEntityClassColumns()) { if (column.getOrderBy() != null) { if (orderBy.length() != 0) { orderBy.append(","); } orderBy.append(column.getColumn()).append(" ").append(column.getOrderBy()); } } table.orderByClause = orderBy; return table.orderByClause; } /** * ? * * @param entityClass * @return */ public static Set<EntityColumn> getColumns(Class<?> entityClass) { return getEntityTable(entityClass).getEntityClassColumns(); } /** * ?? * * @param entityClass * @return */ public static Set<EntityColumn> getPKColumns(Class<?> entityClass) { return getEntityTable(entityClass).getEntityClassPKColumns(); } /** * ? * * @param entityClass * @return */ public static Map<String, String> getColumnAlias(Class<?> entityClass) { EntityTable entityTable = getEntityTable(entityClass); if (entityTable.aliasMap != null) { return entityTable.aliasMap; } Set<EntityColumn> columnList = entityTable.getEntityClassColumns(); entityTable.aliasMap = new HashMap<String, String>(columnList.size()); for (EntityColumn column : columnList) { entityTable.aliasMap.put(column.getColumn(), column.getProperty()); } return entityTable.aliasMap; } /** * ?Select * * @param entityClass * @return */ public static String getSelectColumns(Class<?> entityClass) { Set<EntityColumn> columnList = getColumns(entityClass); StringBuilder selectBuilder = new StringBuilder(); boolean skipAlias = Map.class.isAssignableFrom(entityClass); for (EntityColumn entityColumn : columnList) { selectBuilder.append(entityColumn.getColumn()); if (!skipAlias && !entityColumn.getColumn().equalsIgnoreCase(entityColumn.getProperty())) { selectBuilder.append(" ").append(entityColumn.getProperty().toUpperCase()).append(","); } else { selectBuilder.append(","); } } return selectBuilder.substring(0, selectBuilder.length() - 1); } /** * ?Select * * @param entityClass * @return */ public static String getAllColumns(Class<?> entityClass) { Set<EntityColumn> columnList = getColumns(entityClass); StringBuilder selectBuilder = new StringBuilder(); for (EntityColumn entityColumn : columnList) { selectBuilder.append(entityColumn.getColumn()).append(","); } return selectBuilder.substring(0, selectBuilder.length() - 1); } /** * ?Where? * * @param entityClass * @return */ public static String getPrimaryKeyWhere(Class<?> entityClass) { Set<EntityColumn> entityColumns = getPKColumns(entityClass); StringBuilder whereBuilder = new StringBuilder(); for (EntityColumn column : entityColumns) { whereBuilder.append(column.getColumn()).append(" = ?").append(" AND "); } return whereBuilder.substring(0, whereBuilder.length() - 4); } /** * ? * * @param entityClass */ public static synchronized void initEntityNameMap(Class<?> entityClass) { if (entityTableMap.get(entityClass) != null) { return; } //?? EntityTable entityTable = null; if (entityClass.isAnnotationPresent(Table.class)) { Table table = entityClass.getAnnotation(Table.class); if (!table.name().equals("")) { entityTable = new EntityTable(); entityTable.setTable(table); } } if (entityTable == null) { entityTable = new EntityTable(); //??????@Table entityTable.name = camelhumpToUnderline(entityClass.getSimpleName()); } // List<Field> fieldList = getAllField(entityClass, null); Set<EntityColumn> columnSet = new HashSet<EntityColumn>(); Set<EntityColumn> pkColumnSet = new HashSet<EntityColumn>(); for (Field field : fieldList) { // if (field.isAnnotationPresent(Transient.class)) { continue; } EntityColumn entityColumn = new EntityColumn(); if (field.isAnnotationPresent(Id.class)) { entityColumn.setId(true); } String columnName = null; if (field.isAnnotationPresent(Column.class)) { Column column = field.getAnnotation(Column.class); columnName = column.name(); } if (columnName == null || columnName.equals("")) { columnName = camelhumpToUnderline(field.getName()); } entityColumn.setProperty(field.getName()); entityColumn.setColumn(columnName.toUpperCase()); entityColumn.setJavaType(field.getType()); //order by if (field.isAnnotationPresent(OrderBy.class)) { OrderBy orderBy = field.getAnnotation(OrderBy.class); if (orderBy.value().equals("")) { entityColumn.setOrderBy("ASC"); } else { entityColumn.setOrderBy(orderBy.value()); } } // - Oracle?MySqlUUID if (field.isAnnotationPresent(SequenceGenerator.class)) { SequenceGenerator sequenceGenerator = field.getAnnotation(SequenceGenerator.class); if (sequenceGenerator.sequenceName().equals("")) { throw new RuntimeException(entityClass + "" + field.getName() + "@SequenceGeneratorsequenceName!"); } entityColumn.setSequenceName(sequenceGenerator.sequenceName()); } else if (field.isAnnotationPresent(GeneratedValue.class)) { GeneratedValue generatedValue = field.getAnnotation(GeneratedValue.class); if (generatedValue.generator().equals("UUID")) { if (field.getType().equals(String.class)) { entityColumn.setUuid(true); } else { throw new RuntimeException(field.getName() + " - @GeneratedValue?UUID?String"); } } else if (generatedValue.generator().equals("JDBC")) { if (Number.class.isAssignableFrom(field.getType())) { entityColumn.setIdentity(true); entityColumn.setGenerator("JDBC"); } else { throw new RuntimeException(field.getName() + " - @GeneratedValue?UUID?String"); } } else { //?generator??idsql,mysql=CALL IDENTITY(),hsqldb=SELECT SCOPE_IDENTITY() //??generator if (generatedValue.strategy() == GenerationType.IDENTITY) { //mysql entityColumn.setIdentity(true); if (!generatedValue.generator().equals("")) { String generator = null; MapperHelper.IdentityDialect identityDialect = MapperHelper.IdentityDialect .getDatabaseDialect(generatedValue.generator()); if (identityDialect != null) { generator = identityDialect.getIdentityRetrievalStatement(); } else { generator = generatedValue.generator(); } entityColumn.setGenerator(generator); } } else { throw new RuntimeException(field.getName() + " - @GeneratedValue?????:" + "\n1.?@GeneratedValue(generator=\"UUID\")" + "\n2.useGeneratedKeys@GeneratedValue(generator=\\\"JDBC\\\") " + "\n3.mysql?@GeneratedValue(strategy=GenerationType.IDENTITY[,generator=\"Mysql\"])"); } } } columnSet.add(entityColumn); if (entityColumn.isId()) { pkColumnSet.add(entityColumn); } } entityTable.entityClassColumns = columnSet; if (pkColumnSet.size() == 0) { entityTable.entityClassPKColumns = columnSet; } else { entityTable.entityClassPKColumns = pkColumnSet; } // entityTableMap.put(entityClass, entityTable); } public static void main(String[] args) { System.out.println(camelhumpToUnderline("userName")); System.out.println(camelhumpToUnderline("userPassWord")); System.out.println(camelhumpToUnderline("ISO9001")); System.out.println(camelhumpToUnderline("hello_world")); } /** * ? */ public static String camelhumpToUnderline(String str) { final int size; final char[] chars; final StringBuilder sb = new StringBuilder((size = (chars = str.toCharArray()).length) * 3 / 2 + 1); char c; for (int i = 0; i < size; i++) { c = chars[i]; if (isUppercaseAlpha(c)) { sb.append('_').append(c); } else { sb.append(toUpperAscii(c)); } } return sb.charAt(0) == '_' ? sb.substring(1) : sb.toString(); } /** * ? */ public static String underlineToCamelhump(String str) { Matcher matcher = Pattern.compile("_[a-z]").matcher(str); StringBuilder builder = new StringBuilder(str); for (int i = 0; matcher.find(); i++) { builder.replace(matcher.start() - i, matcher.end() - i, matcher.group().substring(1).toUpperCase()); } if (Character.isUpperCase(builder.charAt(0))) { builder.replace(0, 1, String.valueOf(Character.toLowerCase(builder.charAt(0)))); } return builder.toString(); } public static boolean isUppercaseAlpha(char c) { return (c >= 'A') && (c <= 'Z'); } public static char toUpperAscii(char c) { if (isUppercaseAlpha(c)) { c -= (char) 0x20; } return c; } /** * ?Field * * @param entityClass * @param fieldList * @return */ private static List<Field> getAllField(Class<?> entityClass, List<Field> fieldList) { if (fieldList == null) { fieldList = new ArrayList<Field>(); } if (entityClass.equals(Object.class)) { return fieldList; } Field[] fields = entityClass.getDeclaredFields(); for (Field field : fields) { //??bug#2 if (!Modifier.isStatic(field.getModifiers())) { fieldList.add(field); } } Class<?> superClass = entityClass.getSuperclass(); if (superClass != null && !superClass.equals(Object.class) && (superClass.isAnnotationPresent(Entity.class) || (!Map.class.isAssignableFrom(superClass) && !Collection.class.isAssignableFrom(superClass)))) { return getAllField(entityClass.getSuperclass(), fieldList); } return fieldList; } /** * map?Map * * @param map * @param beanClass * @return */ public static Map<String, Object> map2AliasMap(Map<String, Object> map, Class<?> beanClass) { if (map == null) { return null; } Map<String, String> alias = getColumnAlias(beanClass); Map<String, Object> result = new HashMap<String, Object>(); for (String name : map.keySet()) { String alia = name; //sql??????rownum if (alias.containsKey(name)) { alia = alias.get(name); } result.put(alia, map.get(name)); } return result; } /** * map?bean * * @param map * @param beanClass * @return */ public static Object map2Bean(Map<String, Object> map, Class<?> beanClass) { try { if (map == null) { return null; } Map<String, Object> aliasMap = map2AliasMap(map, beanClass); Object bean = beanClass.newInstance(); BeanUtils.copyProperties(bean, aliasMap); return bean; } catch (InstantiationException e) { throw new RuntimeException(beanClass.getCanonicalName() + "!"); } catch (Exception e) { throw new RuntimeException(e); } } /** * mapList?beanList * * @param mapList * @param beanClass * @return */ public static List<?> maplist2BeanList(List<?> mapList, Class<?> beanClass) { if (mapList == null || mapList.size() == 0) { return null; } List list = new ArrayList<Object>(mapList.size()); for (Object map : mapList) { list.add(map2Bean((Map) map, beanClass)); } mapList.clear(); mapList.addAll(list); return mapList; } }