物件-目錄對應 (ODM)
物件關聯對應框架(例如 Hibernate 和 JPA)讓開發人員能夠使用註解將關聯式資料庫表格對應到 Java 物件。Spring LDAP 專案透過 LdapOperations
中的許多方法,針對 LDAP 目錄提供類似的功能
-
<T> T findByDn(Name dn, Class<T> clazz)
-
<T> T findOne(LdapQuery query, Class<T> clazz)
-
<T> List<T> find(LdapQuery query, Class<T> clazz)
-
<T> List<T> findAll(Class<T> clazz)
-
<T> List<T> findAll(Name base, SearchControls searchControls, Class<T> clazz)
-
<T> List<T> findAll(Name base, Filter filter, SearchControls searchControls, Class<T> clazz)
-
void create(Object entry)
-
void update(Object entry)
-
void delete(Object entry)
註解
使用物件對應方法管理的實體類別,必須使用來自 org.springframework.ldap.odm.annotations
套件的註解進行標註。可用的註解如下:
-
@Entry
:類別層級註解,指示實體對應的objectClass
定義。(必要) -
@Id
:指示實體 DN。宣告此屬性的欄位必須是javax.naming.Name
類別的衍生物。(必要) -
@Attribute
:指示目錄屬性到物件類別欄位的對應。 -
@DnAttribute
:指示 DN 屬性到物件類別欄位的對應。 -
@Transient
:指示該欄位為非持久性,應被OdmManager
忽略。
受管理的類別必須宣告 @Entry
和 @Id
註解。@Entry
用於指定實體對應的物件類別,以及(選擇性地)類別所代表 LDAP 項目的目錄根。所有欄位已對應的物件類別都必須宣告。請注意,當建立受管理類別的新項目時,僅使用宣告的物件類別。
為了使目錄項目被視為與受管理實體匹配,目錄項目宣告的所有物件類別都必須由 @Entry
註解宣告。例如,假設您的 LDAP 樹狀結構中有具有以下物件類別的項目:inetOrgPerson,organizationalPerson,person,top
。如果您僅對變更 person
物件類別中定義的屬性感興趣,則可以使用 @Entry(objectClasses = { "person", "top" })
註解您的 @Entry
。但是,如果您想要管理 inetOrgPerson
物件類別中定義的屬性,則需要使用以下內容:@Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "top" })
。
所有實體欄位都依據其欄位名稱對應到 LDAP 屬性。剩餘的註解 — @Id
、@Attribute
、@Transient
和 @DnAttribute
— 影響該對應的發生方式。
首先,@Id
註解將項目的辨別名稱對應到欄位。該欄位必須是 javax.naming.Name
的實例。
其次,@Attribute
註解將實體欄位對應到 LDAP 屬性。當屬性名稱與欄位名稱不同時,這非常方便。若要使用 @Attribute
,您必須宣告欄位對應到的屬性名稱。您可以選擇性地包含 LDAP 屬性的語法 OID,以保證精確匹配。最後,@Attribute
也提供型別宣告,讓您可以指示 LDAP JNDI 提供者是否將屬性視為二進位或字串型。
第三,@Transient
註解指示給定的實體欄位不對應到 LDAP 屬性。
最後,@DnAttribute
註解額外將實體欄位對應到項目辨別名稱的組件。
考慮具有以下註解的類別
@DnAttribute(name="uid")
String uid;
以及如下所示的 DN
uid=carla,dc=springframework,dc=org
然後 Spring LDAP 將使用 uid=carla
填充 uid
,而不是尋找 uid
屬性。
Only fields of type `String` can be annotated with `@DnAttribute`. Other types are not supported.
您可以選擇性地提供索引,如下所示
@DnAttribute(index=1)
String uid;
@DnAttribute(index=0)
String department;
這對於具有多個組件的 DN 非常方便
uid=carla,department=engineering,dc=springframework,dc=org
當建立或尋找要更新或刪除的實體時,使用 index
也允許 Spring LDAP 為您計算 DN。對於更新情境,如果屬於辨別名稱一部分的屬性已變更,這也會自動處理樹狀結構中項目的移動。
Note that while both attributes are present on `@DnAttribute`, if `index` is specified, then `name` is ignored.
請記住,預設情況下,所有欄位都會對應到 LDAP 屬性。@DnAttribute 不會變更此行為;換句話說,標註了 @DnAttribute 的欄位也將對應到 LDAP 屬性,除非您也使用 @Transient 註解該欄位。 |
執行
當所有組件都已正確組態和註解時,可以按如下方式使用 LdapTemplate
的物件對應方法
@Entry(objectClasses = { "person", "top" }, base="ou=someOu")
public class Person {
@Id
private Name dn;
@Attribute(name="cn")
@DnAttribute(value="cn", index=1)
private String fullName;
// No @Attribute annotation means this will be bound to the LDAP attribute
// with the same value
private String description;
@DnAttribute(value="ou", index=0)
@Transient
private String company;
@Transient
private String someUnmappedField;
// ...more attributes below
}
public class OdmPersonRepo {
@Autowired
private LdapTemplate ldapTemplate;
public Person create(Person person) {
ldapTemplate.create(person);
return person;
}
public Person findByUid(String uid) {
return ldapTemplate.findOne(query().where("uid").is(uid), Person.class);
}
public void update(Person person) {
ldapTemplate.update(person);
}
public void delete(Person person) {
ldapTemplate.delete(person);
}
public List<Person> findAll() {
return ldapTemplate.findAll(Person.class);
}
public List<Person> findByLastName(String lastName) {
return ldapTemplate.find(query().where("sn").is(lastName), Person.class);
}
public Stream<Person> streamFindByLastName(String lastName) {
return ldapTemplate.findStream(query().where("sn").is(lastName), Person.class);
}
}
ODM 和辨別名稱作為屬性值
LDAP 中的安全群組通常包含多值屬性,其中每個值都是系統中使用者的辨別名稱。在 DirContextAdapter
和辨別名稱作為屬性值 中討論了處理這些屬性時涉及的困難。
ODM 也支援 javax.naming.Name
屬性值,使群組修改變得容易,如下列範例所示
@Entry(objectClasses = {"top", "groupOfUniqueNames"}, base = "cn=groups")
public class Group {
@Id
private Name dn;
@Attribute(name="cn")
@DnAttribute("cn")
private String name;
@Attribute(name="uniqueMember")
private Set<Name> members;
public Name getDn() {
return dn;
}
public void setDn(Name dn) {
this.dn = dn;
}
public Set<Name> getMembers() {
return members;
}
public void setMembers(Set<Name> members) {
this.members = members;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addMember(Name member) {
members.add(member);
}
public void removeMember(Name member) {
members.remove(member);
}
}
當您透過使用 setMembers
、addMember
和 removeMember
修改群組成員,然後呼叫 ldapTemplate.update()
時,屬性修改會透過使用辨別名稱相等性來計算,這表示在判斷辨別名稱是否相等時,會忽略辨別名稱的文字格式。