对SpringJDBC的简单扩展

原创
2015/12/22 21:26
阅读数 337
public <T> int save(T t) {
    return batchSave(Collections.singletonList(t));
}

public <T> int batchSave(List<T> list) {
    BeanBatchSavePSCC<T> pscc = new BeanBatchSavePSCC<>(list);
    return getJdbcTemplate().execute(pscc, pscc);
}

public <T> int update(T t) {
    return batchUpdate(Collections.singletonList(t));
}

protected <T> int update(T t, String where, Object... values) {
    BeanBatchUpdatePSCC<T> pscc = new BeanBatchUpdatePSCC<>(Collections.singletonList(t), where, values);
    return getJdbcTemplate().execute(pscc, pscc);
}

public <T> int batchUpdate(List<T> list) {
    BeanBatchUpdatePSCC<T> pscc = new BeanBatchUpdatePSCC<>(list);
    return getJdbcTemplate().execute(pscc, pscc);
}

public <T> List<T> list(Class clazz){
    return getJdbcTemplate().query("select * from table", BeanRowMapper.createRowMapper(clazz));
}

public class BeanBatchSavePSCC<T> implements PreparedStatementCreator, PreparedStatementCallback<Integer> {

    private Class clazz;
    private PropertyDescriptor[] pds;
    private Map<Integer, Method> methodMap;
    private List<T> list;
    private Method methodSetterPK;

    public BeanBatchSavePSCC(List<T> list) {
        this.list = list;
        if (list == null || list.isEmpty()) {
            throw new NullPointerException("");
        }
        this.clazz = list.get(0).getClass();
        methodMap = new HashMap<>();
        pds = BeanUtils.getPropertyDescriptors(clazz);
    }

    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        PreparedStatement statement = con.prepareStatement(getInsertSql(), Statement.RETURN_GENERATED_KEYS);
        for (T t : list) {
            for (Map.Entry<Integer, Method> entry : methodMap.entrySet()) {
                Object value = ReflectionUtils.invokeMethod(entry.getValue(), t);
                statement.setObject(entry.getKey(), value);
            }
            statement.addBatch();
        }
        statement.executeBatch();
        return statement;
    }

    /**
     * 返回更新数量
     *
     * @param statement
     * @return
     * @throws SQLException
     * @throws DataAccessException
     */
    @Override
    public Integer doInPreparedStatement(PreparedStatement statement) throws SQLException, DataAccessException {
        ResultSet rs = statement.getGeneratedKeys();
        int index = 0;
        while (rs.next()) {
            Object id = rs.getObject(1);
            ReflectionUtils.invokeMethod(methodSetterPK, list.get(index), id);
            index++;
        }
        JdbcUtils.closeResultSet(rs);
        return list.size();
    }

    protected String getInsertSql() {
        StringBuilder sql = new StringBuilder("INSERT INTO ");
        sql.append(FieldUtils.underscoreName(clazz.getName()));
        sql.append("(");
        int index = 1;
        for (PropertyDescriptor pd : pds) {
            String name = pd.getName();
            if (!name.equals("class")) {
                Method method = pd.getReadMethod();
                if (method.getAnnotation(PK.class) != null && methodSetterPK == null) {
                    methodSetterPK = pd.getWriteMethod();
                }
                methodMap.put(index, method);
                sql.append("`").append(FieldUtils.underscoreName(name)).append("`,");
                index++;
            }
        }
        sql.deleteCharAt(sql.lastIndexOf(",")).append(")");
        sql.append(" VALUES ").append("(");
        for (int i = 1; i < index; i++) {
            sql.append("?,");
        }
        sql.deleteCharAt(sql.lastIndexOf(",")).append(");");
        System.out.println(sql.toString());
        return sql.toString();
    }
}

public class BeanBatchUpdatePSCC<T> implements PreparedStatementCreator, PreparedStatementCallback<Integer> {

    private Class clazz;
    private PropertyDescriptor[] pds;
    private Map<Integer, Method> methodMap;
    private List<T> list;
    private Method pkReadMethod;
    private String where;
    private Object[] values;

    public BeanBatchUpdatePSCC(List<T> list) {
        this.list = list;
        init();
    }

    public BeanBatchUpdatePSCC(List<T> list, String where, Object... values) {
        this.list = list;
        this.where = where;
        this.values = values;
        init();
    }

    private void init() {
        if (list == null || list.isEmpty()) {
            throw new NullPointerException("");
        }
        this.clazz = list.get(0).getClass();
        methodMap = new HashMap<>();
        pds = BeanUtils.getPropertyDescriptors(clazz);
    }

    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        String sql = getUpdateSql();
        PreparedStatement statement = con.prepareStatement(sql);
        for (T t : list) {
            int index = 1;
            for (Map.Entry<Integer, Method> entry : methodMap.entrySet()) {
                Object value = ReflectionUtils.invokeMethod(entry.getValue(), t);
                statement.setObject(entry.getKey(), value);
                index ++;
            }
            if (where != null) {
                for (Object value : values) {
                    statement.setObject(index, value);
                    index++;
                }
            } else if (pkReadMethod != null) {
                Object value = ReflectionUtils.invokeMethod(pkReadMethod, t);
                statement.setObject(methodMap.size() + 1, value);
            }
            statement.addBatch();
        }
        statement.executeBatch();
        return statement;
    }

    /**
     * 返回更新数量
     *
     * @param statement
     * @return
     * @throws SQLException
     * @throws DataAccessException
     */
    @Override
    public Integer doInPreparedStatement(PreparedStatement statement) throws SQLException, DataAccessException {
        return list.size();
    }

    protected String getUpdateSql() {
        StringBuilder sql = new StringBuilder("UPDATE ");
        sql.append(FieldUtils.underscoreName(clazz.getName()));
        sql.append(" SET ");
        int index = 1;
        String pkColumn = null;
        for (PropertyDescriptor pd : pds) {
            String name = pd.getName();
            if (!name.equals("class")) {
                Method method = pd.getReadMethod();
                if (method.getAnnotation(PK.class) != null && pkColumn == null) {
                    pkColumn = FieldUtils.underscoreName(name);
                    pkReadMethod = method;
                    continue;
                }
                methodMap.put(index, method);
                sql.append("`").append(FieldUtils.underscoreName(name)).append("`=?,");
                index++;
            }
        }
        sql.deleteCharAt(sql.lastIndexOf(","));
        if (where != null) {
            sql.append(" WHERE ").append(where).append(";");
        } else if (pkColumn != null) {
            sql.append(" WHERE `").append(pkColumn).append("`=?;");
        } else {
            throw new NullPointerException("");
        }
        System.out.println(sql.toString());
        return sql.toString();
    }
}

//用户查询后转换成pojo
public class BeanRowMapper extends BeanPropertyRowMapper {

    public BeanRowMapper(Class clazz){
        super(clazz);
    }

    /**
     * java属性和数据库字段对应方法
     *
     * @param name
     * @return
     */
    @Override
    protected String underscoreName(String name) {
        return super.underscoreName(name);
    }

    public static BeanRowMapper createRowMapper(Class clazz) {
        return new BeanRowMapper(clazz);
    }
}

public class FieldUtils {

    public static String underscoreName(String name) {
        if (!StringUtils.hasLength(name)) {
            return "";
        }
        name = name.substring(name.lastIndexOf(".") + 1);
        StringBuilder result = new StringBuilder();
        result.append(name.substring(0, 1).toLowerCase(Locale.US));
        for (int i = 1; i < name.length(); i++) {
            String s = name.substring(i, i + 1);
            String slc = s.toLowerCase(Locale.US);
            if (!s.equals(slc)) {
                result.append("_").append(slc);
            } else {
                result.append(s);
            }
        }
        return result.toString();
    }

}


展开阅读全文
加载中

作者的其它热门文章

0
9 收藏
分享
打赏
0 评论
9 收藏
0
分享
返回顶部
顶部