休眠类型初学者指南

基本映射概念

学习Hibernate时,许多人喜欢跳到父子关联,而无需掌握对象关系映射的基础知识。 在开始对实体关联进行建模之前,了解各个实体的基本映射规则非常重要。

休眠类型

休眠类型是SQL类型和Java原语/对象类型之间的桥梁。


这些是Hibernate默认支持的类型:

休眠类型(org.hibernate.type) JDBC类型 Java类型
StringType VARCHAR
物化球 CLOB
文字类型 LONGVARCHAR
角色类型 焦炭 字符或字符
布尔型 比特 布尔值或布尔值
NumericBooleanType 整数(例如0 =假和1 =真) 布尔值或布尔值
是否类型 CHAR(例如,“ N”或“ n” = false,“ Y”或“ y” = true) 布尔值或布尔值
TrueFalseType CHAR(例如,“ F”或“ f” =否,“ T”或“ t” =真) 布尔值或布尔值
字节类型 天音 字节或字节
短型 SMALLINT 短或短
整数类型 整数 整型或整型
长型 比金特 长或长
浮动类型 浮动 浮动或浮动
双重类型 双倍或双倍
BigIntegerType 数字 大整数
BigDecimalType 数字 大十进制
时间戳类型 时间戳 java.sql.Timestamp或java.util.Date
时间类型 时间 java.sql.Time
日期类型 日期 java.sql.Date
CalendarType 时间戳 java.util.Calendar或java.util.GregorianCalendar
CalendarType 日期 java.util.Calendar或java.util.GregorianCalendar
货币类型 VARCHAR java.util.Currency
语言环境类型 VARCHAR java.util.Locale
时区类型 VARCHAR java.util.TimeZone
网址类型 VARCHAR java.net.URL
类类型 VARCHAR java.lang.Class
BlobType BLOB java.sql.Blob
ClobType CLOB java.sql.Clob
BinaryType VARBINARY 字节[]或字节[]
BinaryType BLOB 字节[]或字节[]
BinaryType LONGVARBINARY 字节[]或字节[]
BinaryType LONGVARBINARY 字节[]或字节[]
CharArrayType VARCHAR char []或Character []
UUIDBinaryType 二进制 java.util.UUID
UUIDBinaryType CHAR或VARCHAR java.util.UUID
UUIDBinaryType PostgreSQL UUID java.util.UUID
SerializableType VARBINARY 可序列化

您将始终可以定义自己的自定义类型,我们将在以后的文章中看到。

嵌入式(aka组件)类型

您可以将多个列分组为特定的Java类型,该类型可以在整个域模型中重复使用。 如果映射的Java对象始终依赖于某些外部实体,则可以为此类域模型映射选择Embeddable类型。

一个Embeddable对象可以包含基本类型和关联映射,但不能包含@Id。 可嵌入对象及其拥有的实体将被持久保存/删除。

假设我们有下面的SQL表:

CREATE TABLE entity_event
  (
     id           BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
     entity_class VARCHAR(255),
     entity_id    BIGINT,
     message      VARCHAR(255),
     PRIMARY KEY (id)
  );

我们可以将entity_class和entity_id分组为一个Embeddable对象,该对象将在两个不同的拥有实体中使用。

Embeddable对象如下所示:

@Embeddable
public class EntityIdentifier implements Serializable {

    @Column(name = "entity_id", nullable = true)
    private Long entityId;

    @Column(name = "entity_class", nullable = true)
    private Class entityClass;

    public EntityIdentifier() {
    }

    public EntityIdentifier(Class entityClass, Long entityId) {
        this.entityClass = entityClass;
        this.entityId = entityId;
    }

    public Class getEntityClass() { return entityClass; }

    public void setEntityClass(Class entityClass) { this.entityClass = entityClass; }

    public Long getEntityId() { return entityId; }

    public void setEntityId(Long entityId) { this.entityId = entityId; }
}

关联的Entity表将继承Embeddable属性的关联列。

实体

实体与SQL表行的Java等效。 该实体必须包含一个@Id属性,该属性映射关联的表主键。

应用程序逻辑对实体属性进行更改,并向持久性上下文通知实体状态更改(持久,合并,删除)。 因此,持久性上下文会将所有实体更改转换为SQL语句。

假设我们有以下SQL表:

CREATE TABLE entity_attribute
  (
     id           BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
     entity_class VARCHAR(255),
     entity_id    BIGINT,
     name         VARCHAR(255),
     VALUE        VARCHAR(255),
     PRIMARY KEY (id)
  );
 CREATE TABLE entity_event
  (
     id           BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
     entity_class VARCHAR(255),
     entity_id    BIGINT,
     message      VARCHAR(255),
     PRIMARY KEY (id)
  );

我们可以利用EntityIdentifier Embeddable类型,因为两个表都包含entity_class和entity_id列。

@Entity
@Table(name = "entity_attribute")
public class EntityAttribute {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private String value;

    private EntityIdentifier entityIdentifier;

    public Long getId() { return id; }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public String getValue() { return value; }

    public void setValue(String value) { this.value = value; }

    public EntityIdentifier getEntityIdentifier() { return entityIdentifier; }

    public void setEntityIdentifier(EntityIdentifier entityIdentifier) { this.entityIdentifier = entityIdentifier; }
}

@Entity
@Table(name = "entity_event")
public class EntityEvent {

    @Id
    @GeneratedValue
    private Long id;

    private String message;

    private EntityIdentifier entityIdentifier;

    public Long getId() { return id; }

    public String getMessage() { return message; }

    public void setMessage(String message) { this.message = message; }

    public EntityIdentifier getEntityIdentifier() { return entityIdentifier; }

    public void setEntityIdentifier(EntityIdentifier entityIdentifier) { this.entityIdentifier = entityIdentifier; }
}

测试时间

我们将为给定产品创建一个EntityEvent和一个EntityAttribute,以查看Embeddable如何与拥有的实体一起持久保存:

@Test
public void testEntityIdentifier() {
	doInTransaction(new TransactionCallable<Void>() {
		@Override
		public Void execute(Session session) {
			Product product = new Product("LCD");
			session.persist(product);
			EntityEvent productEvent = new EntityEvent();
			productEvent.setMessage(String.format("Product %s added", product.getName()));
			productEvent.setEntityIdentifier(new EntityIdentifier(
					product.getClass(),
					product.getId()
			));
			session.persist(productEvent);
			EntityAttribute productAttribute = new EntityAttribute();
			productAttribute.setName("AD_CAMPAIGN");
			productAttribute.setValue("LCD_Sales");
			productAttribute.setEntityIdentifier(new EntityIdentifier(
					product.getClass(),
					product.getId()
			));
			session.persist(productAttribute);
			assertSame(1, session.createQuery("select ea from EntityAttribute ea where ea.entityIdentifier = :entityIdentifier")
					.setParameter("entityIdentifier", new EntityIdentifier(product.getClass(), product.getId()))
					.list().size());
			return null;
		}
	});
}
Query:{[
INSERT INTO product
            (id,
             name)
VALUES      (DEFAULT,
             ?)  
][LCD]} 

Query:{[
INSERT INTO entity_event
            (id,
             entity_class,
             entity_id,
             message)
VALUES      (DEFAULT,
             ?,
             ?,
             ?)  
][com.vladmihalcea.hibernate.masterclass.laboratory.entityidentifier.Product,1,Product LCD added]} 

Query:{[
INSERT INTO entity_attribute
            (id,
             entity_class,
             entity_id,
             name,
             VALUE)
VALUES      (DEFAULT,
             ?,
             ?,
             ?,
             ?)  
][com.vladmihalcea.hibernate.masterclass.laboratory.entityidentifier.Product,1,AD_CAMPAIGN,LCD_Sales]} 

Query:{[
SELECT entityattr0_.id           AS id1_0_,
       entityattr0_.entity_class AS entity_c2_0_,
       entityattr0_.entity_id    AS entity_i3_0_,
       entityattr0_.name         AS name4_0_,
       entityattr0_.VALUE        AS value5_0_
FROM   entity_attribute entityattr0_
WHERE  entityattr0_.entity_class = ?
       AND entityattr0_.entity_id = ?  
][com.vladmihalcea.hibernate.masterclass.laboratory.entityidentifier.Product,1]}

结论

在了解实体关联之前,我们仍然需要涵盖许多概念。 在跳到更高级的主题之前,您应该始终花一些时间来理解基本概念。 我的下一篇文章将介绍实体标识符和所有可用的生成器技术。

翻译自: https://www.javacodegeeks.com/2014/06/a-beginners-guide-to-hibernate-types.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值