文档章节

对SpringJDBC的简单扩展

Oneself丶x
 Oneself丶x
发布于 2015/12/22 21:26
字数 699
阅读 114
收藏 9
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();
    }

}


© 著作权归作者所有

Oneself丶x

Oneself丶x

粉丝 34
博文 23
码字总数 8233
作品 2
海淀
高级程序员
私信 提问
关于ORM选型问题,分享下我对spring jdbc的使用经验

由于不太喜欢hibernate和mybatis,更多使用spring jdbc来开发,针对spring jdbc一些不便捷的地方,做了写整合,写了sborm,具体可以看项目介绍。 osc项目地址:http://www.oschina.net/p/sb...

franticwind
2015/03/30
1K
16
SpringJDBC

Spring的JDBC框架 Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发。 Spring主要提供JDBC模板方式、关系数据库对象化方式、SimpleJdbc方式、事务管理来简化JDBC编程 Spring提供了3个模...

宛珩
2016/07/20
24
0
MiniDao持久层 Vs Mybatis

MiniDao简介及特征 MiniDao是Jeecg自己的持久化解决方案,集成Hibernate实体维护和Mybaits SQL分离的两大优点。具有以下特征 l O/R mapping不用设置xml,零配置便于维护 不需要了解JDBC的知识...

Jeecg
2013/09/11
1K
1
MiniDao持久层 Vs Mybatis

MiniDao简介及特征 MiniDao是Jeecg自己的持久化解决方案,集成Hibernate实体维护和Mybaits SQL分离的两大优点。具有以下特征 l O/R mapping不用设置xml,零配置便于维护 不需要了解JDBC的知识...

Jeecg
2013/09/09
15
0
请教大家对Spring jdbc 的日志记录问题及如何增强JdbcTemplate

本人使用Spring JDBC 来操作数据库,其中一个方法是这样写的: 这样写是很简洁,但是有一个问题,没有SQL执行异常时对SQL本身的日志记录,于是又有了以下写法: 这种写法简直是反人类,本人试...

胖子没烦恼
2014/09/17
2.6K
7

没有更多内容

加载失败,请刷新页面

加载更多

中国龙-扬科
23分钟前
2
0
使用vuex的state状态对象的5种方式

vuex是一个专门为vue.js设计的状态管理模式,并且也可以使用devtools进行调试。 下面给大家来贴一下我的vuex的结构 下面是store文件夹下的state.js和index.js内容 //state.jsconst state =...

peakedness丶
27分钟前
1
0
NetCore MVC Demo

地址:http://114.116.9.72:5411

whltian
34分钟前
1
0
Netty handle方法周期 (四)

写了一个练习之后,发现自定义的助手类每次肯定是必须的,对于不同的业务逻辑需求,会写相对应的逻辑 最简单的查看Handle生命周期的方式,就是重写上级方法,看名字差不多应该可以知道方法的作用 ...

_大侠__
39分钟前
7
0
vue主动刷新页面及列表数据删除后的刷新实例

1.场景 在处理列表时,常常有删除一条数据或者新增数据之后需要重新刷新当前页面的需求。 2.遇到的问题 1. 用vue-router重新路由到当前页面,页面是不进行刷新的 2.采用window.reload(),或者...

前端小攻略
50分钟前
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部