我正在嘗試在 Spring Boot 中隔離 JPQL 查詢。
我在一個 SpringBoot 專案中。有很多方法可以從 @Query(...) 查詢物體本身,@Query(...) 在存盤庫方法(使用 HQL(query hibernate POO) 或 JPQL(query native POO) 。還有屬性(帶有查詢的file.properties) 方法名稱...
我正在尋找這種方式:我一直在閱讀:類似于 Java EE 的做法。 https://www.baeldung.com/jpa-query-parameters
我舉一個簡單的例子,以便大家欣賞。
注意:這個類不是從“JPA”擴展而來的。它是 JEE 中使用的帶有 @Repository 的常規 DAO。
@Override
public List<User> findAllUsersByRole(String roleName, Long roleID) {
TypedQuery<User> query = entityManager.createQuery(
" SELECT u FROM User u "
" RIGHT JOIN UserRoles ur ON ur.userId = u.id "
" RIGHT JOIN Role r ON r.id = ur.roleId "
" WHERE r.name like :roleName AND r.id =:roleID ", User.class);
//query.setParameter(1, roleName).getSingleResult();
//query.setParameter(1, roleID).getSingleResult();
query.setParameter("roleName", roleName);
query.setParameter("roleID", roleID);
List<User> user = query.getResultList();
return user;
}
Java 參考非常煩人。
問題是當有很多表和很多行時,這很麻煩(使用單引號“” ...,在這些情況下我錯過了 JS 插值),但有時,您需要“JPQL”中的原生內容來獲取具有某些方面的不同表。
我還閱讀了這篇文章以補充分離: https ://exchangetuts.com/clean-way-to-externalize-long-20-lines-sql-when-using-spring-jdbc-closed-1639816685252746
我讀過我可以這樣做:
<util:properties id="sqls" location="classpath:oracle/sqls.xml" />
.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Employee Queries</comment>
<string key="employee.insert">
INSERT INTO......
</string>
</properties>
.
@Autowired
@Qualifier("sqls")
private Properties sqls;
String sql = sqls.getProperty("employee.insert");
我遇到了“<util:properties id="sqls" location="classpath:oracle/sqls.xml" />”的問題。假設我“不能”創建 XML,我如何將它添加到 Spring Boot 背景關系并讓它為我檢測到它?
我的問題是,如何將 SpringBoot 中的 JPQL 代碼分離成一個 xml 檔案,就像這樣:
--------XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>User Queries</comment>
<entry key="user.get">
SELECT ....
</entry>
</properties>
------Java DAO(在 Spring Boot 中自定義)
注意:這個類不是從“JPA”擴展而來的。它是 JEE 中使用的帶有 @Repository 的常規 DAO。
...
@Autowired
@Qualifier("sqls")
private Properties sqls;
String sql = sqls.getProperty("user.get");
@Override
public List<User> findAllUsersByRole(String roleName, Long roleID) {
TypedQuery<User> query = entityManager.createQuery(sql)
query.setParameter("roleName", roleName);
query.setParameter("roleID", roleID);
List<User> user = query.getResultList();
return user;
}
...
我讀過這個,但我仍然不清楚。https://docs.spring.io/spring-boot/docs/1.0.1.RELEASE/reference/html/boot-features-external-config.html
- 我知道如何在 Spring/Springboot 中使用:
- 查詢的 JPA 方法命名約定
- 查詢 屬性的 JPA 方法命名約定
但是使用 entityManager 我無法將查詢隔離到另一個檔案。因此,本節對我有很大幫助。
我知道還有其他方法,但我只是在尋找 我在帖子中評論的方法。
uj5u.com熱心網友回復:
而不是通過提供基于 XML 的屬性檔案來重新發明一個蹩腳的輪子。使用適當的技術并撰寫一個orm.xml(這是 JPA 標準)并在其中撰寫命名查詢。
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_0.xsd" version="2.1">
<!-- JPA Named Native Queries -->
<named-native-query name="User.findAllUsersByRole">
<query>SELECT u FROM User u
RIGHT JOIN UserRoles ur ON ur.userId = u.id
RIGHT JOIN Role r ON r.id = ur.roleId
WHERE r.name like :roleName AND r.id =:roleID
</query>
</named-native-query>
</entity-mappings>
然后在您的 Java 代碼中僅參考此命名查詢
@Override
public List<User> findAllUsersByRole(String roleName, Long roleID) {
TypedQuery<User> query = entityManager.createNamedQuery("User. findAllUsersByRole", User.class);
query.setParameter("roleName", roleName);
query.setParameter("roleID", roleID);
return query.getResultList();
}
無需在屬性檔案、附加 XML 檔案等之上添加額外的東西。只需使用普通的 JPA 標準并在orm.xml.
如果您唯一要做的就是洗掉字串 concat upgrade 到較新的 Java 版本并只使用文本塊。不需要 concat 只需一大塊文本(就像在 JavaScript 中一樣)。
@Override
public List<User> findAllUsersByRole(String roleName, Long roleID) {
TypedQuery<User> query = entityManager.createQuery("""
SELECT u FROM User u
RIGHT JOIN UserRoles ur ON ur.userId = u.id
RIGHT JOIN Role r ON r.id = ur.roleId
WHERE r.name like :roleName AND r.id =:roleID""", User.class);
query.setParameter("roleName", roleName);
query.setParameter("roleID", roleID);
return query.getResultList();
}
uj5u.com熱心網友回復:
最后,我能夠合并多個 ORM,這很重要。我沒有用屬性來做這件事,因為它只是給出了太多的錯誤(SAXParse 錯誤、檔案、持久性......)。我從這個例子開始使用@Configuration 類來做到這一點:
具有多個 orm.xml 檔案的 Spring Data JPA
我得到了這樣的東西:
entityManagerFactoryBean.setMappingResources("META-INF/orms/custom-orm-1.xml", "META-INF/orms/custom-orm-2.xml","META-INF/orm.xml");
此時,JPQL 的行為會很奇怪(我想是因為它會丟失我忽略的某種型別的配置屬性)并且必須考慮具有駝峰大小寫的欄位/列 @Column(name = "mysql_column_name") , 如
firstName = 不會將其檢測為 first_name,而是將其檢測為 firstName。
在本節中,您必須輸入以便正確檢測到
@Column(name = "first_name")
private String firstName;
對于帶有 camelCase 的其他欄位/列也是如此。物體也一樣。
我想有一些屬性或屬性可以firstName -> first_name為您進行“”轉換。但對我來說,這不是問題。如果我找到它,我會發布它。但是,它與 @Column 和 @Table 以及它們各自的駝峰式外殼完美配合,我已經可以擁有我正在尋找這篇文章的內容了。
感謝 M. Deinum 的幫助。
-------------------- 已編輯 ----------
經過大量閱讀后,我找到了解決方案。似乎如果您宣告 LocalContainerEntityManagerFactoryBean,因為這種情況下沒有 @Autowired 能夠將屬性一一添加到它擁有的其他屬性中。所以你必須把它加回來,方言和策略。看了很多資料,得出了和我們的伙伴@genki98一樣的結論
EntityManager 不會將駱駝案翻譯成蛇案
@Bean
public LocalContainerEntityManagerFactoryBean businessEntityManagerFactory(DataSource businessDataSource) {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(businessDataSource);
emf.setPackagesToScan("com.xxx.yyy");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(Boolean.valueOf(env.getProperty("spring.jpa.show-sql")));
emf.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
properties.put("hibernate.format_sql", env.getProperty("spring.jpa.properties.hibernate.format_sql"));
properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.properties.hibernate.hbm2ddl.auto"));
properties.put("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy");
properties.put("hibernate.implicit_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
emf.setJpaPropertyMap(properties);
// Multiples ORMS mapping
emf.setMappingResources("META-INF/orms/custom-orm-1.xml", "META-INF/orms/custom-orm-2.xml","META-INF/orm.xml");
return emf;
}
如果你添加
Properties properties = new Properties();
....
entityManagerFactoryBean.setJpaProperties(properties);
你得到空值,你必須用 HashMap 來做。看起來entityManagerFactoryBean.setJpaProperties(properties);沒有正確合并:“ ollectionUtils.mergePropertiesIntoMap(jpaProperties, this.jpaPropertyMap);”
因此,用于 ORM 查詢的 Hibernate 方言可以正常作業,而無需將
@Column(name = "first_name")
private String firstName;
我希望這篇文章對我有所幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/515522.html
標籤:春天弹簧靴休眠jpa
上一篇:執行卡住:Hibernate OracleDBwithWallet:DriverManagerConnectionProviderImpl-HHH000115:Hibernate連接池大小:20(mi
