net.duckling.falcon.api.orm.DAOUtils.java Source code

Java tutorial

Introduction

Here is the source code for net.duckling.falcon.api.orm.DAOUtils.java

Source

/*
 * 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;
    }
}