어노테이션은 또한 pureQuery StaticBinder가 인터페이스에서 바인드 조작을 수행할 때 사용하는 옵션을 제어하는 메타데이터를 포함할 수도 있습니다.
@ColumnOverride(propertyName="extension", column="PHONE") public class EmployeeNewCo extends Employee {...
구문 다이어그램에서 사용되는 규칙을 이해하려면 구문 다이어그램 읽는 방법을 참조하십시오.
>>-@ColumnOverride--(--propertyName--=--"--property--",--column--=--"--name--")-><
>>-@ColumnOverrides--(------------------------------------------> .-,----------------------------------------------------------------------------. V | >--{----@ColumnOverride--(--propertyName--=--"--property--",--column--=--"--name--")-+--}--> >--)-----------------------------------------------------------><
@ColumnOverride 어노테이션의 배열이 @ColumnOverrides 어노테이션의 괄호 안의 중괄호 안에 표시됩니다.
>>-@Table--(--name--=--name_of_table----------------------------> >--+---------------------------------+--)---------------------->< | (1) | '-------schema--=--name_of_schema-'
Bean의 모든 특성에 대해 기본 테이블 이름을 지정하는 클래스 레벨로 지정된 선택적 어노테이션입니다. 어노테이션은 결합을 포함하는 SQL문의 중첩된 Bean을 작성할 때 필요하지 않습니다. 그러나 어노테이션은 Bean 정의를 단순화합니다.
@Column 어노테이션에서 지정된 테이블 이름으로 기본 테이블 이름을 겹쳐쓸 수 있습니다.
@Table 어노테이션은 @JoinColumn 어노테이션의 기본 테이블 이름을 지정하지 않습니다.
인라인 스타일의 @ColumnOverride 및 @ColumnOverrides와 달리 @Table 어노테이션은 데이터 액세스 오브젝트(DAO) 스타일 및 인라인 스타일 모두에서 서브클래스에 의해 상속됩니다.
pureQuery는 공용 필드 및 공용 get() 또는 set() 메소드에서만 특성 레벨 어노테이션을 인식합니다. 이는 개인용 또는 보호 필드에서 해당 어노테이션을 인식하지 않습니다.
구문 다이어그램에서 사용되는 규칙을 이해하려면 구문 다이어그램 읽는 방법을 참조하십시오.
이 어노테이션은 특성이 맵핑되는 데이터베이스 오브젝트의 SQL 열을 지정합니다. 이 어노테이션은 공용 필드 및 공용 메소드에서만 사용할 수 있습니다. 다른 위치에 사용하는 경우 pureQuery는 이를 무시합니다.>>-@Column--(--name--=--name_of_column--+-------------------------+->< '-table--=--name_of_table-'
다음 두 가지 이유 중 하나로 @Column 어노테이션을 사용할 수 있습니다.
@Column(name="DEPTNO") public String deptNum;
@Column(name="EMPNO") public String getEmpNum() { return empNum; }
예제
select a.col1, b.col1 from a, b where a.id=b.id;쿼리 결과를 보유하는 Bean에 있는 해당 특성의 setA_col1 및 setB_col1 메소드에는 두 col1 열이 표시되는 테이블의 이름을 제공하는 @Column 어노테이션이 필요합니다.
public class JoinExample{ private int a_col1; private int b_col1; @Column (name="col1", table="a") public void setA_col1 (int a_col1) { this.a_col1 = a_col1; } public int getA_col1 () { return a_col1; } @Column (name="col1", table="b") public void setB_col1 (int b_col1) { this.b_col1 = b_col1; } public int getB_col1 () { return b_col1; } }
>>-@Format--(--fomatterClass--=--formatter_class----------------> >--+-----------------------------------------+--)-------------->< '-, -formattingOptions--=--pattern-string-'
이 어노테이션은 필요한 변환을 수행하기 위해 호출되는 포맷터를 포함하는 클래스 및 포맷 옵션을 지정합니다. pureQuery 메소드에서 입력 또는 출력으로 지정되는 Bean 오브젝트의 필드에서 이 어노테이션을 사용할 수 있습니다. 이는 DAO 스타일 및 인라인 스타일 모두에 적용됩니다.
이 포맷터 클래스는 문자열 필드를 입력 변수에 적절한 JDBC DateTime 유형으로 변환하며 리턴된 JDBC 유형을 출력에 대한 문자열 변수로 변환 및 형식화합니다.
다음 예는 시작 날짜 필드를 형식화합니다.
class MyBean { … @Format(formatter=com.ibm.pdq.Dateformatter.class, formattingOtions=”style=LONG; timezone=UTC”) String startDate; … }
Java 기본은 널(NULL) 값을 나타낼 수 없으므로 어노테이션은 Java 기본 필드에 적용되지 않습니다.
@Required 어노테이션이 지정되지 않는 경우 기본 동작은 입력 매개변수의 Java 널(NULL)을 인식하고 해당 호스트 변수 값을 SQL 널(NULL)로 설정하는 것입니다.
@Required 어노테이션이 SQL 매개변수에 대한 입력으로 사용되는 필드에 지정되고 필드가 액세스될 때 해당 필드가 Java 널(NULL) 값을 포함하는 경우 pureQuery가 예외를 처리하며 SQL 조작이 시도되지 않습니다.
다음 예에서는 customerAddress 값에 널(NULL)이 아닌 값이 포함되어야 합니다.
@Required String customerAddress;
테이블 조인을 포함하는 SQL 쿼리의 경우 쿼리에서 데이터를 리턴하는 중첩된 Bean 세트를 작성할 수 있습니다. Bean의 계층 구조는 데이터베이스에서 데이터의 관계형 구조를 복제합니다. 중첩된 Bean이 있는 pureQuery 어노테이션을 지정하여 테이블 및 열 관계를 지정합니다. pureQuery Runtime은 Bean을 쿼리의 결과로 채웁니다. 테이블 조인에 사용되는 중첩된 Bean에 대한 정보는 테이블 조인을 포함하는 중첩된 Bean 및 SQL 쿼리의 내용을 참조하십시오.
특성 레벨 어노테이션
>>-@Id---------------------------------------------------------><
이 어노테이션은 어노테이션이 있는 특성이 동일한 클래스의 Bean 간 등식을 판별하기 위해 pureQuery Runtime이 사용하는 ID 컬럼을 나타냄을 표시합니다. 이 어노테이션은 Bean의 특성에 사용됩니다. ID 컬럼은 상위 Bean에 하위 Bean을 링크하는 열입니다. pureQuery Runtime이 중첩된 Bean을 생성할 수 있게 하려면 최소 하나의 @Id 어노테이션을 상위 레벨 Bean에 지정해야 합니다. 데이터베이스의 일치하는 열은 기본 또는 외부 키 열로 선언할 필요가 없습니다.
@Column 어노테이션을 @Id 어노테이션과 함께 사용하여 키 열에 ResultSet 오브젝트를 맵핑하는 열 이름 및 테이블 이름을 지정할 수 있습니다.
하위 Bean에서 @Id 어노테이션 또는 @JoinPoint 어노테이션을 사용하여 하위 Bean에 상위 Bean을 링크하는 ID 컬럼을 정의할 수 있습니다. 두 어노테이션이 모두 지정되면 @JoinPoint 어노테이션 정보가 사용되고 @Id 어노테이션은 무시됩니다. @JoinPoint 어노테이션은 해당 상위 Bean의 Bean에 대한 참조에 지정되고 @Id 어노테이션은 Bean 자체에 지정됩니다.
Bean에 복합 키가 있는 경우 다중 @Id 어노테이션이 하위 Bean에 지정되어야 하거나 키가 상위 Bean의 @JoinPoint 어노테이션과 함께 지정되어야 합니다. @JoinPoint 어노테이션에서 키는 propertyName 요소가 있는 @JoinColumn 어노테이션으로 지정되어야 합니다.
Bean이 중첩된 Bean을 처리할 때 Bean이 같은지 여부를 판별하기 위해 pureQuery Runtime은 @Id 어노테이션이 있는 Bean 특성을 검사합니다. @Id 어노테이션이 있는 모든 특성이 같은 경우 Bean이 같다고 간주됩니다. @Id 어노테이션이 있는 Bean 특성은 데이터베이스에서 기본 또는 키일 필요가 없으나 동일한 클래스의 Bean 간 등식을 판별하기에 충분해야 합니다.
>>-@JoinColumn--(--name--=--name_of_column----------------------> >--+--------------------------+---------------------------------> '-table--=--name_of_column-' >--+-----------------------------------+--)-------------------->< '-propertyName--=--name_of_property-'
이 어노테이션은 상위 Bean 특성 이름이 테이블 이름 또는 ResultSet 오브젝트의 열 레이블과 일치하지 않을 때 하위 Bean의 ID 컬럼으로 ResultSet 오브젝트의 열을 지정합니다. 이 어노테이션은 하위 Bean의 어노테이션으로 상위 Bean에 지정됩니다. 하위 Bean은 단일 Bean 또는 Bean의 목록입니다.
@JoinColumn 어노테이션은 @JoinPoint 어노테이션에만 지정될 수 있습니다.
비어 있는 문자열("")을 name 요소의 값으로 지정하는 경우 pureQuery Runtime은 특성이 일치하지 않는 경고를 생성하지 않고 이 특성에서 중첩된 Bean 지원을 사용할 수 없습니다. 특정 하위 Bean 또는 Bean의 목록을 채우지 않으려는 경우 서브클래스에 비어 있는 문자열을 지정하십시오.
>>-@JoinPoint---------------------------------------------------> >--+-----------------------------------------------------------------------------------------+->< '-(--+--------------------------------------------------+--+-------------------------+--)-' '-+------------+--array_of_@JoinColumn_annotations-' '-columnPrefix--=--prefix-' +-joinCol--=-+ '-value--=---'
최소한 하나의 @JoinPoint 어노테이션이 최상위 레벨 Bean, 즉 메소드 또는 인라인 API의 리턴 값인 Bean에 지정되어야 합니다. 어노테이션은 pureQuery Runtime에 의한 중첩된 Bean 세트의 생성을 사용 가능하게 합니다.
어노테이션은 Bean 또는 Bean 목록을 포함하는 특성에만 정의될 수 있습니다. 선택적 @JoinColumn 어노테이션은 하위 Bean의 ID 컬럼에 맵핑되는 ResultSet 오브젝트 열을 정의합니다. 선택적 columnPrefix 요소는 하위 Bean의 각 특성에 추가될 열 접두부를 지정합니다. 하위 Bean에 복합 키가 있는 경우 둘 이상의 ResultSet 오브젝트 열을 키 컬럼으로 지정해야 합니다.
어노테이션은 Bean 또는 Bean 목록을 포함하는 특성에만 정의될 수 있습니다. 선택적 요소(@JoinColumn 어노테이션 배열 또는 columnPrefix 요소)가 하나도 지정되지 않은 경우, 모든 ResultSet 맵핑 및 ID 컬럼 정의를 하위 Bean에서 가져옵니다.
@JoinColumn 어노테이션의 배열은 선택사항이며 하위 Bean 특성에 적용됩니다. 둘 이상의 @JoinColumn 어노테이션 배열은 중괄호({})로 묶어야 합니다.
@JoinColumn 어노테이션이 지정되지 않으면 pureQuery Runtime은 참조된 하위 Bean @Id 어노테이션을 사용하여 하위 Bean ID 컬럼에 맵핑되는 ResultSet 열을 판별합니다. 하위 Bean에 하나 이상의 @Id 어노테이션이 포함되어 있지 않은 경우 경고가 생성되며 하위 Bean이 무시됩니다.
joinCol 요소는 value 요소와 서로 독점입니다. 각 하나를 지정할 수 있지만 모두 지정할 수는 없습니다. 요소는 columnPrefix 요소가 지정될 때 필요합니다.
columnPrefix 요소의 값은 하위 Bean의 각 특성에 접두사로 추가되는 문자열을 지정합니다. 접두부를 사용하여 pureQuery Runtime이 고유 클래스 및 특성을 생성합니다. 접두부는 동일한 Bean 클래스를 재귀 없이 중첩된 Bean 구조의 동일한 레벨 또는 다른 레벨에서 사용하도록 허용합니다. 이러한 접두부가 있는 특성이 고유한지 확인하십시오. 접두부가 클래스에 추가되고 나면 접두부는 모든 Bean 및 접두부가 있는 클래스의 Bean 특성에 적용됩니다. 접두부는 부가적이며 필요한 만큼 중첩할 수 있습니다. columnPrefix 요소의 값은 상위 Bean @JoinColumn 어노테이션에 정의된 열 레이블이 아닌 하위 Bean에만 적용됩니다.
열 접두부는 쿼리가 하위 Bean을 채우는 열을 리턴하는 경우에만 적용됩니다.
@JoinPoint({ @JoinColumn (name = "DEPTNO", table = "DEPARTMENT", propertyName="empDepartment"), @JoinColumn (name = "EMPNO", table = "EMPLOYEE", propertyName="employeeId") }) public List<Employee> getListofDeptEmployees ();
첫 번째 @JoinColumn 어노테이션은 DEPTNO 열을 DEPARTMENT 테이블에서 직원 Bean의 특성 empDepartment로 맵핑합니다.
ResultSet 오브젝트에서 열 레이블 WORKDEPT를 사용하려고 선택한 경우 ResultSet 오브젝트에 열 레이블 WORKDEPT가 있으면 propertyName = "empDepartment" 요소를 지정할 필요가 없습니다. 특성 WORKDEPT는 직원 Bean의 어노테이션 @Column (name = "WORKDEPT")에 의해 작성되었습니다.
@JoinPoint(value = { @JoinColumn (name = "DEPTNO", table = "DEPARTMENT", propertyName="empDepartment"), @JoinColumn (name = "EMPNO", table = "EMPLOYEE", propertyName="employeeId") }) public List<Employee> getListofDeptEmployees ();
@JoinPoint(columnPrefix = "DE", joinCol = { @JoinColumn (name = "DEPTNO", table = "DEPARTMENT", propertyName="empDepartment"), @JoinColumn (name = "EMPNO", table = "EMPLOYEE", propertyName="employeeId") }) public List<Employee> getListofDeptEmployees ();
부서 직원을 나타낼 DE의 columnPrefix는 직원 Bean의 모든 특성 앞에 접두부로 추가되며 문자열 DE는 직원 Bean의 부서 목록을 의미하는 ResultSet (AS절 기준)의 모든 직원 열에 추가됩니다.
접두부는 또한 해당 직원 Bean의 모든 하위 Bean에 적용됩니다.
예를 들어 직원 Bean에 하위 부서 Bean이 포함되면 직원 Bean에 있는 부서 Bean의 모든 특성 앞에 DE가 접두부로 추가됩니다.
접두부 추가는 ResultSet 오브젝트에 있는 레벨만큼 계속됩니다. 하위 부서 Bean에 있는 직원 Bean 목록의 두 번째 레벨에는 DEDE가 접두부로 추가됩니다.
접두부는 또한 중첩된 Bean 구조의 모든 직원 Bean이 아닌 해당 직원 Bean의 모든 하위 Bean에 적용됩니다. 예를 들어, 접두부는 프로젝트 Bean의 직원 Bean 목록에 사용되지 않습니다.
@JoinPoint public List<Emp> emps; @JoinPoint(columnPrefix="m_") public Emp manager;
columnPrefix="m_" 요소를 지정하여 m_이 접두부로 추가된 직원 테이블의 열을 Emp 관리자 필드에 맵핑할 수 있습니다.
CREATE TABLE HRDEPT.EMPLOYEE( EMPNO CHAR(6) NOT NULL, FIRSTNME VARCHAR(12) NOT NULL, MIDINIT CHAR(1), LASTNAME VARCHAR(15), WORKDEPT CHAR(2), PHONENO CHAR(4), HIREDATE DATE, PRIMARY KEY(EMPNO))컬럼 이름 중 일부는 생략되거나 Java 이름 지정 규칙을 따르지 않습니다.
직원 Bean에 대한 다음 정의는 @Column 어노테이션을 사용하여 com.company.Employee 클래스의 오브젝트 사용자에게 더 의미있는 이름을 제공합니다.
public class Employee { private String employeeId; private String firstName; private String middleInitial; private String lastName; private String departmentId; private String extension; private Date hireDate; @Column(name = "EMPNO") public String getEmployeeId () { return employeeId; } public void setEmployeeId (String employeeId) { this.employeeId = employeeId; } @Column(name = "FIRSTNME") public String getFirstName () { return firstName; } public void setFirstName (String firstName) { this.firstName = firstName; } @Column(name = "MIDINIT") public String getMiddleInitial () { return middleInitial; } public void setMiddleInitial (String middleInitial) { this.middleInitial = middleInitial; } public String getLastName () { return lastName; } public void setLastName (String lastName) { this.lastName = lastName; } @Column(name = "WORKDEPT") public String getDepartmentId () { return departmentId; } public void setDepartmentId (String departmentId) { this.departmentId = departmentId; } @Column(name = "PHONENO") public String getExtension () { return extension; } public void setExtension (String extension) { this.extension = extension; } public Date getHireDate () { return hireDate; } public void setHireDate (Date hireDate) { this.hireDate = hireDate; } }
애플리케이션이 데이터베이스에 대해 조금 다른 스키마로 실행되는 경우, 테이블은 다음과 같이 정의됩니다.
CREATE TABLE HRDEPTNEWCO.EMPLOYEE( EMPNO CHAR(6) NOT NULL, FIRSTNME VARCHAR(12) NOT NULL, MIDINIT CHAR(1), LASTNAME VARCHAR(15), WORKDEPT CHAR(2), PHONE CHAR(4), HIREDATE DATE, PRIMARY KEY(EMPNO))
직원 Bean의 서브클래스를 작성하여 새 테이블 정의를 사용하여 작업할 수 있도록 이전 어노테이션을 겹쳐쓸 수 있습니다. 서브클래스의 시작은 다음 예와 비슷할 수 있습니다.
@ColumnOverride(propertyName="extension", column="PHONE") public class EmployeeNewCo extends Employee {...
@Id @GeneratedKey @Column(name = "EMPNO") public String getEmployeeId () { return employeeId; } public void setEmployeeId (String employeeId) { this.employeeId = employeeId; } @Id @Column(name = "WORKDEPT") public String getDepartmentId () { return departmentId; } public void setDepartmentId (String departmentId) { this.departmentId = departmentId; }
@JoinPoint({ @JoinColumn (name = "DEPTNO", table = "DEPARTMENT", propertyName="workDept"), @JoinColumn (name = "EMPNO", table = "EMPLOYEE", propertyName="employeeId") }) public List<Employee> getListofDeptEmployees ();
첫 번째 @JoinColumn 어노테이션에서 DEPARTMENT 테이블의 DEPTNO 열은 직원 Bean의 workDept 특성에 맵핑됩니다. ResultSet의 열 레이블 WORKDEPT가 사용된 경우 열 레이블 WORKDEPT가 ResultSet에 있으면 propertyName="workDept"가 필요하지 않습니다. WORKDEPT 특성은 직원 Bean의 @Column(이름 = "WORKDEPT") 어노테이션에 의해 작성됩니다.