编程修炼之hibernate2 领域建模

映射类型

hibernate中的type与JDBC和SQL的数据类型均不相同。Hibernate的类型分为2种:值类型,实体类型。
值类型由实体负责其生命周期,也就是说实体的状态是由值类型维护的,即JavaBean与属性的关系。

值类型

有3类:

  • 基本类型
  • Embeddable类型
  • 集合类型

实体类型

命名策略

  • @Column or @Table实现或者通过ImplicitNamingStrategy 实现
  • PhysicalNamingStrategy

ImplicitNamingStrategy

当实体没有显式地命名它映射到的数据库表时,我们需要隐式地确定该表名。或者当特定属性没有显式地命名它映射到的数据库列时,我们需要隐式地确定该列名。
在这里插入图片描述
pre-defined “short names” for the out-of-the-box implementations

  • default for org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl - an alias for jpa

jpa
for org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl - the JPA 2.0 compliant naming strategy

legacy-hbm
for org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl - compliant with the original Hibernate NamingStrategy

legacy-jpa
for org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl - compliant with the legacy NamingStrategy developed for JPA 1.0, which was unfortunately unclear in many respects regarding implicit naming rules

component-path
for org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl - mostly follows ImplicitNamingStrategyJpaCompliantImpl rules, except that it uses the full composite paths, as opposed to just the ending property part

  • reference to a Class that implements the org.hibernate.boot.model.naming.ImplicitNamingStrategy contract

  • FQN of a class that implements the org.hibernate.boot.model.naming.ImplicitNamingStrategy contract

PhysicalNamingStrategy

自定义物理映射关系

@Entity(name = "Contact")
public static class Contact {

	@Id
	private Integer id;

	private Name name;

	private String notes;

	private URL website;

	private boolean starred;

	//Getters and setters are omitted for brevity
}

@Embeddable
public class Name {

	private String first;

	private String middle;

	private String last;

	// getters and setters omitted
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

@Basic

在这里插入图片描述
optional 字段能否为空
fetch 是否懒加载

@Entity(name = "Product")
public class Product {
	@Id
	@Basic
	private Integer id;
	@Basic
	private String sku;
	@Basic
	private String name;
	@Basic
	private String description;
}

@Column

@Entity(name = "Product")
public class Product {

	@Id
	private Integer id;

	private String sku;

	private String name;

	@Column( name = "NOTES" )
	private String description;
}

BasicTypeRegistry

告诉hibernate类型的映射关系。

@Entity(name = "Product")
public class Product {

	@Id
	private Integer id;

	private String sku;

	@org.hibernate.annotations.Type( type = "nstring" )
	private String name;

	@org.hibernate.annotations.Type( type = "materialized_nclob" )
	private String description;
}

自定义类型的使用参考文档

映射枚举值

@Enumerated or @MapKeyEnumerated

public enum PhoneType {
    LAND_LINE,
    MOBILE;
}
@Entity(name = "Phone")
public static class Phone {

	@Id
	private Long id;

	@Column(name = "phone_number")
	private String number;

	@Enumerated(EnumType.ORDINAL)
	@Column(name = "phone_type")
	private PhoneType type;

	//Getters and setters are omitted for brevity

}

对于ordinal类型:

NULL
For null values

0
For the LAND_LINE enum

1
For the MOBILE enum
相当于执行sql:

INSERT INTO Phone (phone_number, phone_type, id)
VALUES ('123-456-78990', 2, 1)
@Entity(name = "Phone")
public static class Phone {

	@Id
	private Long id;

	@Column(name = "phone_number")
	private String number;

	@Enumerated(EnumType.STRING)
	@Column(name = "phone_type")
	private PhoneType type;

	//Getters and setters are omitted for brevity

}

INSERT INTO Phone (phone_number, phone_type, id)
VALUES ('123-456-78990', 'MOBILE', 1)

但是对于一些场景,我看可能想做更进一步的自定义转换:
如,M,F表示男女 YN表示是否

public enum Gender {

    MALE( 'M' ),
    FEMALE( 'F' );

    private final char code;

    Gender(char code) {
        this.code = code;
    }

    public static Gender fromCode(char code) {
        if ( code == 'M' || code == 'm' ) {
            return MALE;
        }
        if ( code == 'F' || code == 'f' ) {
            return FEMALE;
        }
        throw new UnsupportedOperationException(
            "The code " + code + " is not supported!"
        );
    }

    public char getCode() {
        return code;
    }
}


@Entity(name = "Person")
public static class Person {

	@Id
	private Long id;

	private String name;

	@Convert( converter = GenderConverter.class )
	public Gender gender;

	//Getters and setters are omitted for brevity

}

@Converter
public static class GenderConverter
		implements AttributeConverter<Gender, Character> {

	public Character convertToDatabaseColumn( Gender value ) {
		if ( value == null ) {
			return null;
		}

		return value.getCode();
	}

	public Gender convertToEntityAttribute( Character value ) {
		if ( value == null ) {
			return null;
		}

		return Gender.fromCode( value );
	}
}

映射LOBS

JDBC的LOB包括:
java.sql.Blob

java.sql.Clob

java.sql.NClob

java类型经常为String, char[], byte[], etc,此类大对象需要权衡性能。

@Entity(name = "Product")
public static class Product {

    @Id
    private Integer id;

    private String name;

    @Lob
    private byte[] image;

    //Getters and setters are omitted for brevity

}

时间类型

@Column(name = "`timestamp`")
@Temporal(TemporalType.TIMESTAMP)
private Date timestamp;

AttributeConverters

@Converter
public class PeriodStringConverter
        implements AttributeConverter<Period, String> {

    @Override
    public String convertToDatabaseColumn(Period attribute) {
        return attribute.toString();
    }

    @Override
    public Period convertToEntityAttribute(String dbData) {
        return Period.parse( dbData );
    }
}


@Entity(name = "Event")
public static class Event {

    @Id
    @GeneratedValue
    private Long id;

    @Convert(converter = PeriodStringConverter.class)
    @Column(columnDefinition = "")
    private Period span;

    //Getters and setters are omitted for brevity

}


INSERT INTO Event ( span, id )
VALUES ( 'P1Y2M3D', 1 )

SQL限定符

@Entity(name = "Product")
public static class Product {

	@Id
	private Long id;

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

	@Column(name = "`number`")
	private String number;

	//Getters and setters are omitted for brevity

}
JPA方式:
@Entity(name = "Product")
public static class Product {

	@Id
	private Long id;

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

	@Column(name = "\"number\"")
	private String number;

	//Getters and setters are omitted for brevity

}

hibernate也可以全职设置

<property
    name="hibernate.globally_quoted_identifiers"
    value="true"
/>

@CreationTimestamp annotation
@UpdateTimestamp annotation

类转换(加密解密) @ColumnTransformer

@Entity(name = "Employee")
public static class Employee {

	@Id
	private Long id;

	@NaturalId
	private String username;

	@Column(name = "pswd")
	@ColumnTransformer(
		read = "decrypt( 'AES', '00', pswd  )",
		write = "encrypt('AES', '00', ?)"
	)
	private String password;

	private int accessLevel;

	@ManyToOne(fetch = FetchType.LAZY)
	private Department department;

	@ManyToMany(mappedBy = "employees")
	private List<Project> projects = new ArrayList<>();

	//Getters and setters omitted for brevity
}

@Where 过滤 @Filter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值