我想实现从JPA到Spring JDBC的关系。例如,假设我有Account和Advert对象。根据JPA,帐户和广告之间的关系是 @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
}
AccountMapper:
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类创建一个Mapper。如何将广告类中的帐户变量映射到行?非常感谢
答案 0 :(得分:5)
您可以在不影响应用程序性能的情况下使用Hibernate,只需查看此Hibernate tutorial数百个与映射实体相关的示例。
至于在JDBC中执行此操作,您需要执行以下步骤:
您需要对所有选定的列使用别名,以便ids列不会发生冲突。
您可以定义两个行映射器并使用从广告到帐户的连接并将其传递给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进行比较,其中所有这些映射都已为您解决。
答案 1 :(得分:4)
好吧,如果你不使用ORM ......你没有对象关系映射!在创建所有ORM之后: - )
更严重的是,ORM使您无需编写大量样板代码。使用直接JDBC而不是JPA是代码优化。与任何其他代码优化一样,应在适当时使用它。 与相关:
我的建议应该是首先使用隐藏在DAO层中的JPA或本机休眠。然后仔细分析您的性能问题并重写JDBC中最昂贵的部分。
当然,您可以直接在JDBC中编写DAO实现代码,但写入时间会更长。
我几乎忘记了基本部分:在ORM中映射类和关系,在JDBC中编写独立的SQL查询。
答案 2 :(得分:1)
解决一对一案件很容易就像弗拉德回答的那样,如果你想将一个到多个地图作为你的账户 - 广告建议你做不到 使用RowMapper,因为您将尝试将ResultSet的多行映射到一个帐户,许多广告。
您也可以手动执行此操作,或者也可以使用http://simpleflatmapper.org提供从ResultSet到POJO的映射,并提供一对多支持。 请注意,如果你真的想要那些可能的双向关系并不是很好,但他们不会成为同一个实例。
结帐 http://simpleflatmapper.org/0104-getting-started-springjdbc.html 和 https://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);
你应该得到一个帐户列表,其中填写了广告列表。但是广告没有帐户。