欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JdbcTemplate实体映射

程序员文章站 2022-06-22 12:46:52
JdbcTemplate实体映射 如果你需要使用JdbcTemplate将查询的数据映射成Java POJO,那么这篇文章适合你。 一个例子入门 下面是一个将表中一行记录映射成Map的例子,也是JdbcTemplate默认提供的功能。 然而,我们更希望得到的是下面这样的。 其中User中的属性与字段 ......

jdbctemplate实体映射

如果你需要使用jdbctemplate将查询的数据映射成java pojo,那么这篇文章适合你。

一个例子入门

下面是一个将表中一行记录映射成map的例子,也是jdbctemplate默认提供的功能。

list<map<string, object>> result = jdbctemplate.queryforlist("select id, name, age from tbl");

然而,我们更希望得到的是下面这样的。

list<user> result = jdbctemplate.queryforlist("select id, name, age from tbl", user.class);

其中user中的属性与字段一一对应,还能自动将下划线转成驼峰。

开始

实现思路是通过反射将字段映射到对象对应的属性。

核心代码

public <t> list<t> queryforlist(string sql, class<t> clazz, object... params) {
        final list<t> result = new arraylist<>();
        jdbctemplate.query(sql, params, rs -> {
            try {
                // 字段名称
                list<string> columnnames = new arraylist<>();
                resultsetmetadata meta = rs.getmetadata();
                int num = meta.getcolumncount();
                for (int i = 0; i < num; i++) {
                    columnnames.add(meta.getcolumnlabel(i + 1));
                }
                // 设置值
                do {
                    t obj = clazz.getconstructor().newinstance();
                    for (int i = 0; i < num; i++) {
                        // 获取值
                        object value = rs.getobject(i + 1);
                        // table.column形式的字段去掉前缀table.
                        string columnname = resolvecolumn(columnnames.get(i));
                        // 下划线转驼峰
                        string property = camelcaseutils.tocamelcase(columnname);
                        // 复制值到属性,这是spring的工具类
                        beanutils.copyproperty(obj, property, value);
                    }
                    result.add(obj);
                } while (rs.next());
            } catch (exception e) {
                throw new queryexception(e);
            }
        });
        if (collectionutils.isempty(result)) {
            return collections.emptylist();
        }
        return result;
    }

注意:

  • string columnname = resolvecolumn(columnnames.get(i))用来去掉字段的表前缀,比如t.id替换成id
  • string property = camelcaseutils.tocamelcase(columnname)用来将字段的下划线转成属性的驼峰形式,比如page_view转换成pageview
  • beanutils.copyproperty(obj, property, value)是用来复制值到对象的属性中,beanutils是spring的工具类,经常会使用到

下面是两个工具方法或类。

去掉表前缀

之所以去掉表前缀,是为了避免在sql中使用别名,导致sql过长。

private string resolvecolumn(string column) {
    final int notexistindex = -1;
    int index = column.indexof(".");
    if (index == notexistindex) {
        return column;
    }
    return column.substring(index + 1);
}

字段下划线转成属性的驼峰

当然,下划线转驼峰有很多更好的实现,这里不限制。如下是一个实现:

public final class camelcaseutils {

    private static final char separator = '_';

    private camelcaseutils() {
    }

    public static string tocamelcase(string input) {
        if (input == null) {
            return null;
        }
        input = input.tolowercase();
        int length = input.length();

        stringbuilder sb = new stringbuilder(length);
        boolean uppercase = false;
        for (int i = 0; i < length; i++) {
            char c = input.charat(i);
            if (c == separator) {
                uppercase = true;
            } else if (uppercase) {
                sb.append(character.touppercase(c));
                uppercase = false;
            } else {
                sb.append(c);
            }
        }

        return sb.tostring();
    }

}

使用

接下来就可以愉快的映射成pojo了:

list<user> result = queryforlist("select t.id, t.name, t.age, t.mobile_phone from tbl t where t.id < ?", user.class, 100l);

如果参数比较多,还是通过数组传入:

list<user> result = queryforlist("select t.id, t.name, t.age, t.mobile_phone from tbl t where t.id < ?", user.class, new object[]{100l});

下面定义pojo:

public class user implements serializabl {
    
    private long id;

    private string name;

    private integer age;

    private string mobilephone;

    // 省略到getters、setters
}

补充

映射成一个值

在count时,我们是希望返回一个值的,接下来是将结果映射成一个值。

public <t> t queryonecolumn(string sql, class<t> clazz, object... params) {
    t result;
    if (arrayutils.isempty(params)) {
        result = jdbctemplate.queryforobject(sql, clazz);
    } else {
        result = jdbctemplate.queryforobject(sql, params, clazz);
    }
    return result;
}

使用:

long total = queryonecolumn("select count(1) from tbl", long.class);