文档章节

对SpringJDBC的简单扩展

Oneself丶x
 Oneself丶x
发布于 2015/12/22 21:26
字数 699
阅读 111
收藏 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
基于 Spring-JDBC 的 ORM 简单封装--zd-web-utils

一直以来关于持久层框架选择的讨论都比较多,网上查了下比较,大致得出的结果:hibernate太繁,springjdbc太简, mybatis 刚好,可见如今选用mybatis的势头也越来越明显。毕竟mybatis有DAO模版...

我是一只鱼_
2017/07/25
1K
4
SpringJDBC可以单独使用吗?

@苗哥 你好,想跟你请教个问题: 我现在在做一个应用,需要用到数据库,我之前使用过spring和springJDBC,然后感觉springJDBC实在是太方便了 - - 但是现在感觉无法熟练驾驭Spring,所以不打算...

Timco
2014/04/24
649
9
Snaker 2.0.0 发布,Java轻量级工作流引擎

Snaker是一个基于Java的开源工作流引擎,适用于企业应用中常见的业务流程。本着轻量、简单、灵巧理念设计,定位于简单集成,多环境支持 轻量:核心代码行数大约7000行,强大的扩展性,支持Spr...

Dead_knight
2014/07/21
15.8K
31

没有更多内容

加载失败,请刷新页面

加载更多

OSX | SafariBookmarksSyncAgent意外退出解决方法

1. 启动系统, 按住⌘-R不松手2. 在实用工具(Utilities)下打开终端,输入csrutil disable, 然后回车; 你就看到提示系统完整性保护(SIP: System Integrity Protection)已禁用3. 输入reboot回车...

云迹
今天
3
0
面向对象类之间的关系

面向对象类之间的关系:is-a、has-a、use-a is-a关系也叫继承或泛化,比如大雁和鸟类之间的关系就是继承。 has-a关系称为关联关系,例如企鹅在气候寒冷的地方生活,“企鹅”和“气候”就是关...

gackey
今天
4
0
读书(附电子书)|小狗钱钱之白色的拉布拉多

关注公众号,在公众号中回复“小狗钱钱”可免费获得电子书。 一、背景 之前写了一篇文章 《小狗钱钱》 理财小白应该读的一本书,那时候我才看那本书,现在看了一大半了,发现这本书确实不错,...

tiankonguse
今天
4
0
Permissions 0777 for ‘***’ are too open

异常显示: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ......

李玉长
今天
5
0
区块链10年了,还未落地,它失败了吗?

导读 几乎每个人,甚至是对通证持怀疑态度的人,都对区块链的技术有积极的看法,因为它有可能改变世界。然而,区块链技术问世已经10年了,我们仍然没有真正的用上区块链技术。 几乎每个人,甚...

问题终结者
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部