jpa 如何在Spring JDBC中创建对象之间的关系?

63lcw9qa  于 12个月前  发布在  Spring
关注(0)|答案(3)|浏览(201)

我想实现从JPA到Spring JDBC的关系。例如,假设我有Account和Advert对象。根据JPA,Account和Advert之间的关系是 @OneToMany

账户类别:

public class Account {

private Long id;
private String username;
private Set<Advert> adverts = new HashSet<Advert>();

// getters + setters
}

字符串

广告类别:

public class Advert {

private Long id;
private String text;
private Account account;

// getters + setters
}

账户Map器:

public class AccountMapper implements RowMapper<Account> {

public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
    Account account = new Account();
    account.setId(rs.getLong("id"));
    account.setUsername(rs.getString("username"));
    return account;
}
}


现在,我正在尝试为Advert类创建一个Map器。我如何将Advert类中的帐户变量Map到一行?非常感谢

pw9qyyiw

pw9qyyiw1#

你可以在不影响应用程序性能的情况下使用Hibernate,只需查看这个Hibernate tutorial,其中有数百个与Map实体相关的示例。
至于在JDBC中这样做,你需要做以下步骤:
1.您需要对所有选定的列使用别名,以便ID列不会冲突。
1.您可以定义两个行Map器,并使用从Advert到Account的联接,然后将其传递给AccountMapper:

public class AdvertMapper implements RowMapper<Advert> {

     public Advert mapRow(ResultSet rs, int rowNum) throws SQLException {
         Advert advert = new Advert();
         advert.setId(rs.getLong("advert_id"));
         advert.setText(rs.getString("advert_text"));
         return advert;      
     }
 }

 public class AccountMapper implements RowMapper<Account> {

     private final AdvertMapper advertMapper;

     public AccountMapper(AdvertMapper advertMapper) {
         this.advertMapper = advertMapper;
     }

     public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
         Account account = new Account();
         account.setId(rs.getLong("account_id"));
         account.setUsername(rs.getString("account_username"));

         Advert advert = this.advertMapper.mapRow(rs, rowNum);
         advert.setAccount(account);
         account.getAdverts().add(advert);

         return account;
     }
 }

字符串
AccountMapper使用AdvertMapper从连接的数据创建数据包。
与Hibernate相比,Hibernate为您解析了所有这些Map。

a64a0gku

a64a0gku2#

好吧,如果你不使用ORM......你就没有对象关系Map!毕竟所有的ORM都是因为这个原因而创建的:-)
更重要的是,ORM让你不必编写大量的样板代码。使用直接JDBC而不是JPA是一种代码优化。像任何其他代码优化一样,它应该在适当的时候使用。它相关:

  • 使用少量不希望依赖ORM的表的库(例如:spring security中的user、roles和ACL)
  • 在大型应用程序中发现瓶颈

我的建议应该是首先使用JPA或隐藏在DAO层中的本地休眠,然后仔细分析您的性能问题,并在JDBC中重写最昂贵的部分。
当然,您可以直接在JDBC中编写DAO实现,但编写时间要长得多。
我几乎忘记了最重要的部分:在ORM中Map类和关系,在JDBC中编写独立的SQL查询。

llmtgqce

llmtgqce3#

解决一对一的情况很容易,正如Vlad回答的那样,如果你想将一对多Map为你的帐户- Advert建议你不能用RowMapper这样做,因为你会试图将ResultSet的多行Map到一个帐户,许多Advert。
你也可以手动完成,或者你也可以使用http://simpleflatmapper.org,它提供了从ResultSet到POJO的Map,支持一对多。要注意的是,如果你真的想要那些,双向关系不是很好,这是可能的,但它们不会是同一个示例。
检出http://simpleflatmapper.org/0104-getting-started-springjdbc.htmlhttps://arnaudroger.github.io/blog/2017/02/27/jooq-one-to-many.html
你将需要一个ResutlSetExtractor -它是线程安全的,所以只需要一个示例-,

private final ResultSetExtractor<List<Account>> mapper = 
        JdbcTemplateMapperFactory
            .newInstance()
            .addKeys("id") // assuming the account id will be on that column 
            .newResultSetExtractor(Account.class);

    // in the method
    String query = 
        "SELECT ac.id as id, ac.username, ad.id as adverts_id, ad.text as adverts_text"
        + "FROM account ac LEFT OUTER JOIN advert ad ON ad.account_id = ac.id order by id " 
        // the order by id is important here as it uses the break on id on the root object 
        // to detect new root object creation

    List<Account> results = template.query(query, mapper);

字符串
与你应该得到一个列表的帐户与列表的广告填充.但广告不会有帐户.

相关问题