Java tutorial
/* * Copyright (c) 2008-2016 Computer Network Information Center (CNIC), Chinese Academy of Sciences. * * This file is part of Duckling project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package net.duckling.falcon.api.orm; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.log4j.Logger; import org.springframework.jdbc.core.RowMapper; /** * Simulation ORM-Mapping ??bean ? ?? javaBean DB * -------------------------- someClass some_class(????) id id someField * some_field -------------- boolean????extendSQLnull * boolean?Boolean * * * ?@TempField * * @author lvly * @since 2012-08-07 * */ public class DAOUtils<T> { private static final Logger LOG = Logger.getLogger(DAOUtils.class); private static final int DELTA_FROM_UPPER_TO_LOWER = 32; private static final int UPPER_START_CODE = 64; private static final int UPPER_END_CODE = 91; public static final String FIELDS = "${field}"; public static final String TABLE = "${table}"; public static final String VALUES = "${value}"; public static final String INSERT_SQL = "insert into " + TABLE + "(" + FIELDS + ") values(" + VALUES + ")"; public static final String SELECT_SQL = "select * from " + TABLE + " where 1=1"; public static final String UPDATE_SQL = "update " + TABLE + " set " + FIELDS + " where id=:id"; public static final String DELETE_SQL = "delete from " + TABLE + " where 1=1" + FIELDS; /** ?orm-mappingbean */ private Class<?> objClass; /** ?mapping */ private Field[] fields; /** * ?? * * @param objClass * ?.class * */ public DAOUtils(Class<?> objClass) { this.objClass = objClass; Field[] allFields = objClass.getDeclaredFields(); List<Field> privateFields = new ArrayList<Field>(); for (int i = 0; i < allFields.length; i++) { if (!Modifier.isStatic(allFields[i].getModifiers()) && Modifier.isPrivate(allFields[i].getModifiers()) && allFields[i].getAnnotation(TempField.class) == null) { privateFields.add(allFields[i]); } } this.fields = new Field[privateFields.size()]; int index = 0; for (Field field : privateFields) { this.fields[index++] = field; } } public Class<?> getObjClass() { return objClass; } public void setObjClass(Class<?> objClass) { this.objClass = objClass; } /** * ?sql?t * * */ public String getUpdate(T t) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; Object value = getFieldValue(t, field); if (isNullValue(value)) { continue; } sb.append(getDBField(field.getName())); sb.append("=:"); sb.append(field.getName()); sb.append(","); } return UPDATE_SQL.replace(TABLE, getDBField(objClass.getSimpleName())).replace(FIELDS, format(sb)); } /** * ?sql * * @param t * ??t?sql * **/ public String getDelete(T t) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; Object value = getFieldValue(t, field); if (isNullValue(value)) { continue; } sb.append(" and "); sb.append(field.getName()); sb.append("=:"); sb.append(field.getName()); } return DELETE_SQL.replace(TABLE, getDBField(objClass.getSimpleName())).replace(FIELDS, format(sb)); } private String format(StringBuilder sb) { if (sb.indexOf(",") > 0) { sb.deleteCharAt(sb.lastIndexOf(",")); } return sb.toString(); } /*** * rowMapper?map?? * * @param Class * objClass * @param map * Map<,?>,???map * @return RowMapper * */ public RowMapper<T> getRowMapper(final Map<String, String> map) { return new RowMapper<T>() { @SuppressWarnings("unchecked") @Override public T mapRow(ResultSet rs, int index) throws SQLException { Object obj = null; try { obj = objClass.newInstance(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; field.getName(); setValueToObj(field, obj, rs); } } catch (InstantiationException e) { LOG.debug(e.getMessage(), e); } catch (IllegalAccessException e) { LOG.debug(e.getMessage(), e); } revertMapping(map, obj, rs); return (T) obj; } }; } private void setValueToObj(Field field, Object obj, ResultSet rs) { String setName = getSetMethodName(field.getName()); String exceptionMsg = "???"; try { Method method = objClass.getMethod(setName, field.getType()); if (isString(field)) { method.invoke(obj, new Object[] { rs.getString(getDBField(field.getName())) }); } else if (isInt(field)) { method.invoke(obj, new Object[] { rs.getInt(getDBField(field.getName())) }); } else if (isDate(field)) { method.invoke(obj, new Object[] { rs.getTimestamp(getDBField(field.getName())) }); } else if (isBoolean(field)) { method.invoke(obj, new Object[] { rs.getBoolean(getDBField(field.getName())) }); } else { LOG.debug("Unsupported type"); } } catch (ReflectiveOperationException e) { LOG.debug(exceptionMsg + obj.getClass() + "@" + field, e); } catch (SQLException e) { LOG.debug(exceptionMsg + obj.getClass() + "@" + field, e); } } private void revertMapping(Map<String, String> map, Object obj, ResultSet rs) { if (map != null) { Set<Entry<String, String>> set = map.entrySet(); String exceptionMsg = "???"; for (Iterator<Entry<String, String>> it = set.iterator(); it.hasNext();) { Entry<String, String> entry = it.next(); try { Field field; field = objClass.getDeclaredField(entry.getKey()); Method method = objClass.getMethod(getSetMethodName(field.getName()), field.getType()); if (isString(field)) { method.invoke(obj, new Object[] { rs.getString(entry.getValue()) }); } else if (isInt(field)) { method.invoke(obj, new Object[] { rs.getInt(entry.getValue()) }); } } catch (ReflectiveOperationException e) { LOG.debug(exceptionMsg + entry, e); continue; } catch (SQLException e) { LOG.debug(exceptionMsg + entry, e); continue; } } } } /** * ??prepareStatment * * @throws SQLException * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * * */ public PreparedStatement setValues(PreparedStatement pst, final T t, String expectField) throws SQLException { int index = 0; for (int i = 0; i < fields.length; i++) { Field field = fields[i]; if (expectField.contains(field.getName())) { continue; } Object obj = null; String exceptionMsg = "??get??"; try { Method method = t.getClass().getMethod(getGetMethodName(field.getName())); obj = method.invoke(t); } catch (InvocationTargetException e) { LOG.debug(field.getName() + exceptionMsg, e); continue; } catch (NoSuchMethodException e) { LOG.debug(field.getName() + exceptionMsg, e); continue; } catch (SecurityException e) { LOG.debug(field.getName() + exceptionMsg, e); continue; } catch (IllegalAccessException e) { LOG.debug(field.getName() + exceptionMsg, e); continue; } catch (IllegalArgumentException e) { LOG.debug(field.getName() + exceptionMsg, e); continue; } if (isString(field)) { pst.setString(++index, (String) obj); } else if (isInt(field)) { pst.setInt(++index, (int) obj); } else { LOG.debug("Unsupported Type"); } } return pst; } /** * ?INSERT ? * * @param Class * class * */ public String getInsert(String expectField) { return INSERT_SQL.replace(TABLE, getDBField(objClass.getSimpleName())) .replace(FIELDS, getAllFieldStr(expectField)).replace(VALUES, getValueRepeat(expectField)); } /** * ?SELECT ? * * @return ? * */ public String getSelect(T t) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; Object value = getFieldValue(t, field); if (isNullValue(value)) { continue; } sb.append(" and "); sb.append(getDBField(field.getName())); sb.append("=:"); sb.append(field.getName()); sb.append(" "); } return SELECT_SQL.replace(TABLE, getDBField(objClass.getSimpleName())) + sb.toString(); } /** * t? ?? * * @param t * * @return Map<fieldKey,fieldValue> * * **/ public Map<String, Object> getParamMap(T t) { return getParamMap(t, false); } /** * t? ??,?? * * @param t * * @param isAll ??null * @return Map<fieldKey,fieldValue> * * **/ public Map<String, Object> getParamMap(T t, boolean isAll) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; Object value = getFieldValue(t, field); if (!isAll && isNullValue(value)) { continue; } if (isDate(field) && value != null) { value = new Timestamp(((Date) value).getTime()); } else if (isBoolean(field)) { if (value == null) { value = "0"; } else { value = (((boolean) value) ? "1" : "0"); } } map.put(field.getName(), value); } return map; } private Object getFieldValue(T t, Field field) { Object obj = null; String exceptionMsg = "?"; try { Method method = objClass.getDeclaredMethod(getGetMethodName(field.getName())); if (t == null) { return null; } obj = method.invoke(t); } catch (ReflectiveOperationException e) { LOG.debug(exceptionMsg + field.getName()); } return obj; } /** * ? * * @param expectField * ?","? * @return String xx_xx,xx_xx * */ private String getAllFieldStr(String expectField) { StringBuilder sb = new StringBuilder(); for (Field field : fields) { if (expectField.contains(field.getName()) || isNullValue(field)) { continue; } sb.append(getDBField(field.getName())); sb.append(","); } return format(sb); } /** * ?????,????? * * @return xx_xx * */ private String getDBField(String objField) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < objField.length(); i++) { char c = objField.charAt(i); if (isUpperCase(c)) { if (i == 0) { sb.append(up2low(c)); } else { sb.append("_").append(up2low(c)); } } else { sb.append(c); } } return sb.toString(); } /** * ??":xxXx" * * @param objClass * @return :xxXx,:xxXx * */ private String getValueRepeat(String expectField) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; if (expectField.contains(field.getName()) || isNullValue(field)) { continue; } sb.append(":").append(field.getName()).append(","); } return format(sb); } private boolean isString(Field field) { return field.getType().equals(String.class); } private boolean isInt(Field field) { return field.getType().equals(int.class) || field.getType().equals(Integer.class); } private boolean isBoolean(Field field) { return field.getType().equals(boolean.class) || field.getType().equals(Boolean.class); } private boolean isDate(Field field) { return field.getType().equals(Date.class); } private boolean isUpperCase(char c) { return c < UPPER_END_CODE && c > UPPER_START_CODE; } private String getGetMethodName(String fieldName) { return "get" + low2up(fieldName.charAt(0)) + fieldName.substring(1); } private String getSetMethodName(String fieldName) { return "set" + low2up(fieldName.charAt(0)) + fieldName.substring(1); } private char up2low(char c) { return (char) (c + DELTA_FROM_UPPER_TO_LOWER); } private char low2up(char c) { return (char) (c - DELTA_FROM_UPPER_TO_LOWER); } private boolean isNullValue(Object obj) { if (obj == null) { return true; } else if (obj instanceof Integer) { return (int) obj == 0; } return false; } }