正常 , 声明和专家模式。 在本文中,我将重点介绍声明式SQL模式。 这种智能模式允许框架根据视图层要求的属性在运行时自动构建SQL查询。 此外,根据要求的属性,框架不仅会构建Select子句 但是整个查询。 因此, From子句仅包含提供询问的属性所需的实体,并且作为VO执行的结果,仅创建了那些实体并将其存储在实体缓存中。 广泛建议使用声明式SQL模式,它已成为JDeveloper 12c的默认模式。 但是,我们应该谨慎使用这种方法,因为我们会遇到一个小陷阱,我将在本文中重点介绍。

在我的示例中,有一个基于员工和部门实体的简单VO:

sql server 2016 查询 许可证 过期_java VO设置为使用声明性SQL模式。

ViewController项目中有几页,包含一个包含雇员的表(主要)和一个包含雇员的详细信息的表单(详细信息):

sql server 2016 查询 许可证 过期_sql_02 这两个页面共享相同的VEmployees

因此,让我们在这种环境下玩一些考虑三个简单的用例。

用例#1。

sql server 2016 查询 许可证 过期_sql_03

sql server 2016 查询 许可证 过期_spring_04

在这种情况下,一切都非常清楚。 VO通过以下查询检索所有必需的属性:

SELECT Employees.EMPLOYEE_ID,
                Employees.FIRST_NAME,  
                Employees.LAST_NAME,
                Employees.DEPARTMENT_ID,
                Departments.DEPARTMENT_NAME,
                Departments.DEPARTMENT_ID AS DEPARTMENT_ID1
FROM EMPLOYEES Employees, DEPARTMENTS Departments
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID

因此,当我们从表格转到详细信息表格时,VO当前行的所有属性都已填充,并且没有多余的事情发生。

用例2。

sql server 2016 查询 许可证 过期_java_05

sql server 2016 查询 许可证 过期_spring_06

在这种情况下,SQL查询如下所示:

SELECT Employees.EMPLOYEE_ID,
                Employees.FIRST_NAME,  
                Employees.LAST_NAME,
                Employees.DEPARTMENT_ID,
                Departments.DEPARTMENT_ID AS DEPARTMENT_ID1
FROM EMPLOYEES Employees, DEPARTMENTS Departments
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID

因此,尚未选择DepartmentName。 但是,部门实体已创建,并且存储在实体缓存中。 但是这些实体只有一个填充的属性DepartmentId。 这些实体中的其余属性为空。 当我们从表格转到详细信息表格时,由于未填充当前VO行的DepartmentName属性,该框架遇到了问题,它迫使实体实例从数据库中检索自身。 实体实例会触发以下查询,以填充其具有的所有属性:

SELECT DEPARTMENT_ID,
               DEPARTMENT_NAME,
               MANAGER_ID,
               LOCATION_ID
FROM DEPARTMENTS Departments WHERE DEPARTMENT_ID=:ID

用例#3。

sql server 2016 查询 许可证 过期_java_07

sql server 2016 查询 许可证 过期_java_08

在这种情况下,VO执行以下查询:

SELECT Employees.EMPLOYEE_ID,
               Employees.FIRST_NAME,  
               Employees.LAST_NAME,
               Employees.DEPARTMENT_ID
 FROM EMPLOYEES Employee

因此,from子句中没有部门,并且由于执行VO而没有创建任何部门实体。 当我们转到详细信息表格时,框架无法强制实体实例从数据库中检索DepartmentName。 因为该实例不存在。

因此,详细信息表单包含一个空白的DepartmentName属性。 此外,在12c中,在这种情况下,我们将获得一个例外:

sql server 2016 查询 许可证 过期_spring_09

实际上,这就是我在本文开头提到的陷阱。 为了解决此用例中的问题,我们可以将DepartmentId1属性添加到表的树绑定定义中:

<tree IterBinding="VEmployeesIterator" id="VEmployees">
  <nodeDefinition
       DefName="com.adfpractice.blog.declarativemodeexample.model.VEmployees"
       Name="VEmployees0">
    <AttrNames>
      <Item Value="EmployeeId"/>
      <Item Value="FirstName"/>
      <Item Value="LastName"/>
      <Item Value="DepartmentId"/>
      <Item Value="DepartmentId1"/>
    </AttrNames>
  </nodeDefinition>
</tree>

像使用案例2一样,这将获得执行查询的框架。

Select子句中包含属性,并且始终在From子句中包含Departments实体。

而已!

翻译自: https://www.javacodegeeks.com/2015/02/declarative-sql-mode-pitfall.html