• 如何使用 Jdbc 模板映射一对多


    我遇到了弗拉德在推特上提到的一个堆栈溢出问题。 如何在春季 jdbc 模板中映射一对多关系。

    第一个问题是,使用 RowMapper 接口实际上只能映射一对一的关系,因为它假定一个 ResultSet 行将映射到一个对象。

    正如RowMapper接口所述:

    用于在每行的基础上映射结果集的行... 此接口执行将每行映射到结果对象的实际工作

    为了能够映射通常使用联接恢复的一对多,您需要能够将多行聚合到一个对象中。ResultSetExtractor将允许跨 Merge 工作,然后返回一个集合。ResultSet

    对于结果集处理,RowMapper 通常是一个更简单的选择,它每行映射一个结果对象,而不是整个结果集映射一个结果对象。

    您可以使用根对象 ID 更改来检测新对象何时启动。 代码看起来像。

    1. List users = new ArrayList<>();
    2. User currentUser = null;
    3. while(rs.next()) {
    4. long id = rs.getLong("id");
    5. if (currentUser == null) { // initial object
    6. currentUser = mapUser(rs);
    7. } else if (currentUser.getId() != id) { // break
    8. users.add(currentUser);
    9. currentUser = mapUser(rs);
    10. }
    11. currentUser.addRole(mapRole(rs));
    12. }
    13. if (currentUser != null) { // last object
    14. users.add(currentUser);
    15. }

    这还不错,但随着您添加更多联接,复杂性会迅速增加。

    幸运的是,SimpleFlatMapper已经解决了这个问题。 您需要做的就是使用JdbcTemplateMapperFactory 创建 aage。ResultSetExtractor

    1. private final ResultSetExtractor> resultSetExtractor =
    2. JdbcTemplateMapperFactory
    3. .newInstance()
    4. .addKeys("id") // the column name you expect the user id to be on
    5. .newResultSetExtractor(User.class);

    您现在可以使用它来映射您的一对多。resultSetExtractor

    1. String query =
    2. "SELECT u.id as id, u.username, u.id as adverts_id, ad.text as adverts_text"
    3. + "FROM user u LEFT OUTER JOIN advert ad ON ad.account_id = ac.id order by id "
    4. List results = template.query(query, resultSetExtractor);

    请注意,sfm 使用根 id 中断作为其聚合的基础,因此查询的顺序很重要。

    6.2.0以来的更新是一个新选项允许使用无序结果集进行联接映射。unorderedJoin()

    如果要将角色列表保留在用户对象之外,该怎么办?

    无需使用User类和UserWithRole类,您只需将查询映射到ausing sfm元组或jOOL。Tuple2>

    1. private final ResultSetExtractor>> resultSetExtractor =
    2. JdbcTemplateMapperFactory
    3. .newInstance()
    4. .addKeys("id") // the column name you expect the user id to be on
    5. .newResultSetExtractor(new TypeReference>> {});

    然后

    1. String query =
    2. "SELECT u.id as id, u.username, u.id as adverts_id, ad.text as adverts_text"
    3. + "FROM user u LEFT OUTER JOIN advert ad ON ad.account_id = ac.id order by id "
    4. List>> results = template.query(query, resultSetExtractor);

    每个元组 2 都有用户及其关联的角色。

    总结

    您不需要使用复杂的 ORM 将 sql 查询映射到对象,即使有多个一对多关系也是如此。 SimpleFlatMapper已经为您处理了所有的复杂性,因此请放弃编写手动RowMapper,并花时间编写业务逻辑而不是样板映射代码。

  • 相关阅读:
    Verilog仿真跨模块调用内部信号的方法
    TheadLocal:当前线程的全局变量
    Anaconda、Conda、pip、Virtualenv的区别
    记录--使用Vue开发Chrome插件
    肝了五万字把SQL数据库从基础到高级所有命令写的明明白白,内容实在丰富,MySQL这一篇就够了
    HTTP协议详解
    L2搭载率连续两个月站上30%大关,车企加速产业链整合
    【软件测试】7年资深带你详探什么是测试开发?
    个人云存储:使用Cpolar和极简主义文件管理器构建的公网访问平台
    T1 卡牌选取
  • 原文地址:https://blog.csdn.net/allway2/article/details/127585808