我将使用 persistence.xml 定义两个 peristence-unit 元素(一个用于 SqlServer,另一个用于 Derby),其中包含 named-native-query 的专用 orm.xml。
persistence.xml
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="sqlserver-pu">
<mapping-file>META-INF/orm-sqlserver.xml</mapping-file>
...
</persistence-unit>
<persistence-unit name="derby-pu">
<mapping-file>META-INF/orm-derby.xml</mapping-file>
...
</persistence-unit>
</persistence>
orm-sqlserver.xml
<entity-mappings version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
<named-native-query name="findFirst" result-class="com.tyler.example.order">
<query>SELECT TOP 1 * FROM Order</query>
</named-native-query>
</entity-mappings>
orm-derby.xml
<entity-mappings version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
<named-native-query name="findFirst" result-class="com.tyler.example.order">
<query>SELECT * FROM Order FETCH FIRST ROW ONLY</query>
</named-native-query>
</entity-mappings>
通过这种方法,您可以提高代码的互操作性,因为实体(可跨数据库移植)与查询(特定于供应商)分离。您只需在运行时选择合适的持久性单元并执行给定的查询(它们必须具有相同的名称)。
我想到的另一种方法是使用具有不同 name 和 query 属性的 @NamedNativeQuery 注释为每个实体定义两次命名本机查询,但在运行时您可能需要一些“ifology”来确定一个合适的。