Hibernate注解对象映射

std*_*all 1 java annotations dao hibernate

我对 hibernate 很陌生,我正在尝试将我拥有的 JDBC 项目转换为 Hibernate。

我正在使用注释,我设法注释了基本的东西,但是,我现在被困在更重的对象上,我不知道如何注释它们。这是类:

@Entity
@Table(name = "person")
public class Person {

    public Person{

    }

    // THIS WILL BE SOON INJECTED BY SPRING
    private static transient PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
    private static transient EmailValidator validator = EmailValidator.getInstance();

    @Id
    @Column(name = "person_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "private_name", nullable = false, length = 20)
    private String privateName;

    @Column(name = "middle_name", length = 20)
    private String middleName;

    @Column(name = "family_name", nullable = false, length = 20)
    private String familyName;

    @Column(name = "age", nullable = false)
    private int age;

    @Column(name = "address1", nullable = false)
    private String address1;

    @Column(name = "address2")
    private String address2;

    //How do I annotate this ? --> Google LIBPHONENUMBER

    private PhoneNumber phone;

    // How do I annotate this ? --> This is a normal PNG image file.
    private File image;
Run Code Online (Sandbox Code Playgroud)

编辑:该文件以前被映射为 BLOB。PhoneNumber 以前作为 String 持久化,并使用 PhoneNumber 构造函数将其转换为 Phonenumber。

Jef*_*eff 6

关于使用@Lob 的其他注释对于文件类型是正确的。如果您可以更改架构以不在数据库中保存文件数据,那么您可能应该这样做也是正确的。

要将 PhoneNumber 类映射到数据库字段,您将需要使用 Hibernate 自定义 UserType。它基本上告诉 Hibernate 如何为它还不知道的类做 object<-->db 映射。在 Person 中告诉 PhoneNumber 字段使用自定义用户类型很容易:

@Type(type = PhoneNumberType.CLASS_NAME)
@Column
private PhoneNumber phone;
Run Code Online (Sandbox Code Playgroud)

这假设了电话号码的非常简单的一列存储。

要编写 PhoneNumberType,您需要实现 UserType。它看起来势不可挡,有汇编/反汇编/深拷贝,但你关心的主要部分是 nullSetGet/Set、returnedClass 和 sqlTypes。你最终会在你的自定义类型中得到一些这样的代码:

@Override
public Class<?> returnedClass() {
    return PhoneNumber.class;
}

@Override
public int[] sqlTypes() {
    return new int[] { Types.VARCHAR };
}

@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
    final String value = rs.getString(names[0]);
    return /* PhoneNumber instance created from string. */
}

@Override
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
    if (value == null) {
        st.setNull(index, Types.VARBINARY);
        return;
    }

    st.setString(index, ((PhoneNumber) value).toString());
}
Run Code Online (Sandbox Code Playgroud)

您可以通过 google、stackoverflow 和 hibernate javadocs 找到有关如何实现其他方法的大量信息。做起来并不难。

更新:多列用户类型

实施CompositeUserType而不仅仅是UserType. 有一些您关心的方法更改。首先,您需要定义多个属性名称和类型:

public String[] getPropertyNames() {
    return new String[] { "number", "code" };
}

public Type[] getPropertyTypes() {
    return new Type[] { StandardBasicTypes.STRING,
                        StandardBasicTypes.STRING };
}
Run Code Online (Sandbox Code Playgroud)

还有getPropertyValue/setPropertyValue要实施。您的 nullSafeXxxx 实现将更改为读取和写入两个属性而不是一个:

@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
    // Access column in order defined in getPropertyNames()
    final String number = rs.getString(names[0]);
    final String code = rs.getString(names[1]);
    return /* PhoneNumber instance created from number and country code. */
}
Run Code Online (Sandbox Code Playgroud)