获取数据【正是getXxx方法,当然,自动装配的时候能够直接写在字段上,但也只是针对getXxx方法,不会自动赋" />

Hibernate 注解之 @Temporal

      因为数据库中有个 Date类型的数量,在从数据库中 style="color: #ff0000;">获取数据【正是getXxx方法,当然,自动装配的时候能够直接写在字段上,但也只是针对getXxx方法,不会自动赋值】的时候能够动用这一个@Temporal的笺注举行机动格式化。

1. @Temporal

1.1 @Temporal的作用
  数据库中的Date类型,取到页面上是yyyy-MM-dd hh-mm-ss格式,利用@Temporal则足以博得本人想要的格式类型。@Temporal的定义如以下所示:

public @interface Temporal {
    TemporalType value() default TIMESTAMP;
}

默认为TemporalType.TIMESTAMP类型。

TemporalType枚举类型定义如下:

public enum TemporalType {
    DATE, //java.sql.Date
    TIME, //java.sql.Time
    TIMESTAMP //java.sql.Timestamp
}

java.sql.Date、java.sql.Time和java.sql.提姆estamp那二种档期的顺序分裂,它们表示时间的准确度分裂。三者的区分如表所示:

    类型                        说明
java.sql.Date           日期型,精确到年月日,例如“2008-08-08”

java.sql.Time           时间型,精确到时分秒,例如“20:00:00”

java.sql.Timestamp      时间戳,精确到纳秒,例如“2008-08-08 20:00:00.000000001”

示例
a. 如若在某类中有Date类型的习性,数据库中积存恐怕是'yyyy-MM-dd hh:MM:ss'要在询问时获得年月日,在该属性上标明。

@Temporal(TemporalType.DATE)
@Column(name = "applyDate", nullable = false, length = 10)
public Date getApplyDate() {
return applyDate;
}

上述代码在页面端取值:2017-04-12

b. 尽管在某类中有Date类型的性能,数据库中贮存大概是'yyyy-MM-dd hh:MM:ss'要取得时分秒,在该属性上标记 @Temporal(TemporalType.TIME) 会获得形如'HH:MM:SS' 格式的日子。

@Temporal(TemporalType.TIME)
@Column(name = "applyDate", nullable = false, length = 10)
public Date getApplyDate() {
return applyDate;
}

上述代码在页面端取值:22:50:30

c. 如若在某类中有Date类型的质量,数据库中蕴藏恐怕是'yyyy-MM-dd hh:MM:ss'要获得'是'yyyy-MM-dd hh:MM:ss',在该属性上标注@Temporal(TemporalType.TIMESTAMP) 会得到形如' yyyy-MM-dd hh:MM:ss ' 格式的日子。

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "applyDate", nullable = false, length = 10)
public Date getApplyDate() {
return applyDate;
}

上述代码在页面端取值:二零一二-04-12 22:51:34.0

@Temporal 申明的取值独有三种,如下图:

2. @Embedded和@Embeddable

在应用实体类生成对应的数据库表时,相当多的时候都会蒙受这种情况:在三个实体类中征引别的的实体类,一般遇上这种状态,大家接纳@OneToOne、@OneToMany、@ManyToOne、@ManyToMany这4个注脚非常多,但是好奇害死猫,除了这两个有未有其他使用状态,更上一层楼是贰个实体类要在多个分化的实体类中开展利用,而自己又没有需求独立生成叁个数码库表,那正是内需@Embedded、@Embeddable的时候了,上边分成4类来证实在多个实体类中援用其余的实体类的意况。
  使用的八个实体类如下:
Address类:

public class Address implements Serializable{
    private static final long serialVersionUID = 8849870114128959929L;

    private String country;
    private String province;
    private String city;
    private String detail;

    //setter、getter
}

Person类:

@Entity
public class Person implements Serializable{
    private static final long serialVersionUID = 8849870114127659929L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer age;

    private Address address;

    //setter、getter
}

1、 三个证明全不应用
  当那多少个注脚都不行使时,那么多少个实体类和上边的均等,那么生成的表结构如下:

图片 1

2、 只使用@Embeddable
  大家在Address实体类上加上@Embeddable注明,产生如下类:

@Embeddable
public class Address implements Serializable{
    private static final long serialVersionUID = 8849870114128959929L;

    private String country;
    private String province;
    private String city;
    private String detail;

    //setter、getter
}

而Person实体类不改变,生成的数码库表结构如下:

图片 2

能够阅览此次是把Address中的字段映射成数据库列嵌入到Person表中了,而那么些字段的档次和长短也选用暗许值。要是我们在Address中的字段中安装列的连带属性,则会遵照大家设定的值去变通,如下Address类:

@Embeddable
public class Address implements Serializable{
    private static final long serialVersionUID = 8849870114128959929L;

    @Column(nullable = false)
    private String country;
    @Column(length = 30)
    private String province;
    @Column(unique = true)
    private String city;
    @Column(length = 50)
    private String detail;
    //setter、getter
}

变迁的表结构如下:

图片 3

咱俩在Address中布局的性质全体成功映射到Person表中。

3. 只使用@Embedded

此间我们只在Person中选用@Embedded,如下:

@Entity
public class Person implements Serializable{
    private static final long serialVersionUID = 8849870114127659929L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer age;

    @Embedded
    private Address address;

    //setter、getter
}

Adddress类和最开始的两样POJO类一样,此时变动的表结构如下:

图片 4

能够见见那么些表结构和在Address中只利用@Embeddable注明时同样,在步入深一步试验,我们在Address中加入列属性,不过不利用@Embeddable注解会发生什么?Address类如下:

public class Address implements Serializable{
    private static final long serialVersionUID = 8849870114128959929L;

    @Column(nullable = false)
    private String country;
    @Column(length = 30)
    private String province;
    @Column(unique = true)
    private String city;
    @Column(length = 50)
    private String detail;
    //setter、getter
}

转移数据表结构如下:

图片 5

之所以只行使@Embedded和只行使@Embeddable发生的功效是一样的。

4. 三个评释全选用
  既然单独行使@Embedded只怕只利用@Embeddable都会发出效果,那么这八个都选取效果与利益也肯定是一样的,大家平时也是那样用的。所以在那有个别大家就不演示和下边一样的法力了,而是说三个深深的话题。

4.1 覆盖@Embeddable类中字段的列属性
  这里将要选拔别的的四个表明@AttributeOverrides和@AttributeOverride,这三个评释是用来掩饰@Embeddable类中字段的品质的。

  • @AttributeOverrides:里面只含有了@AttributeOverride类型数组;
  • @AttributeOverride:包蕴要掩盖的@Embeddable类中字段名name和新扩大的@Column字段的习性;

Person类如下:

@Entity
public class Person implements Serializable{
    private static final long serialVersionUID = 8849870114127659929L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer age;

    @Embedded
    @AttributeOverrides(
       {@AttributeOverride(name="country", 
             column=@Column(name = "person_country", length = 25, nullable = false)),
        @AttributeOverride(name="city", 
             column = @Column(name = "person_city", length = 15))
       })
    private Address address;

    //setter、getter
}

Address类如下:

@Embeddable
public class Address implements Serializable{
    private static final long serialVersionUID = 8849870114128959929L;

    @Column(nullable = false)
    private String country;
    @Column(length = 30)
    private String province;
    @Column(unique = true)
    private String city;
    @Column(length = 50)
    private String detail;
    //setter、getter
}

转移的数据表如下:

图片 6

能够看到我们的@AttributeOverrides和@AttributeOverride多少个注脚起作用了。

4.2 多层嵌入实体类属性
  上边装有的例子都以选用两层实体类嵌入,其实这种实体类的内置映射是足以应用多层的,具体的事比方下。
  我们新构造建设一个类Direction表示方位如下:

@Embeddable
public class Direction implements Serializable{

    @Column(nullable = false)
    private Integer longitude;
    private Integer latitude;
}

Address如下:

@Embeddable
public class Address implements Serializable{
    private static final long serialVersionUID = 8849870114128959929L;

    @Column(nullable = false)
    private String country;
    @Column(length = 30)
    private String province;
    @Column(unique = true)
    private String city;
    @Column(length = 50)
    private String detail;

    @Embedded
    private Direction direction;
}

Person类如下:

@Entity
public class Person implements Serializable{
    private static final long serialVersionUID = 8849870114127659929L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer age;

    @Embedded
    @AttributeOverrides(
          {@AttributeOverride(name="direction.latitude",
                column=@Column(name = "person_latitude")),
           @AttributeOverride(name="direction.longitude", 
                column = @Column(name = "person_longitude"))})
    private Address address;
}

转移的数据表如下:

图片 7

在上头须要留心如下几点:

  • 在Person中定义Direction中的属性时,须求用”.”将富有有关的性质连接起来;
  • 在Direction中longitude属性定义为not null,不过出于应用了@AttributeOverride评释,当中尽管未有定义null属性,不过此时使用的是暗中同意的nullable属性,默感觉true;

图片 8

3. @Convert

介绍@Convert以前率先介绍实体性质类型转变器AttributeConverter。接口AttributeConverter<x, y>用于转化实体性质的,但id属性和关系属性不可用。它有多少个方法:

  • y convertToDatabaseColumn(x) 作用:将实体属性x转化为y存储到数据库中,即插入和换代操作时实践;
  • x convertToEntityAttribute(y) 成效:将数据库中的字段y转化为实体属性x,即查询操作时实践

而@Convert用于注脚在供给类型转变的字段上,将二个中坚数据类型调换为另壹在那之中坚数据类型。

【示例】
** 示例1**
步骤一:创建StatusEnum

public enum StatusEnum {

    ENABLE(1, "启用"), DISABLE(-1, "禁用"), DELETED(-2, "已删除");

    StatusEnum(Integer value, String description) {
        this.value = value;
        this.description = description;
    }
}

手续二:完成AttributeConverter<String, Integer>接口,将意味数字与汇报实行更换,当中实体类中的status字段为String类型。

public class StatusAttributeConverter implements AttributeConverter<String, Integer> {
    @Override
    public Integer convertToDatabaseColumn(String status) {
        try {
           //如果是数字,则直接返回(这里可以遍历StatusEnum的value来进一步验证)
           return Integer.parseInt(status);
        } catch (NumberFormatException e) {
           //如果不是数字,则通过StatusEnum来找到描述对应的数字
            for (StatusEnum type : StatusEnum.values()) { 
                if (status.equals(type.getDescription()))
                    return type.getValue();
            }
        }
        //如果StatusEnum里不存在代表数字或描述,则抛出异常
        throw new RuntimeException("Unknown StatusEnum: " + status);
    }

    @Override
    public String convertToEntityAttribute(Integer value) {
        //将数字转换为描述
        for (StatusEnum type : StatusEnum.values()) {
            if (value.equals(type.getValue())) {
                return type.getDescription();
            }
        }
        throw new RuntimeException("Unknown database value: " + value);
    }
}

步骤三:实体类

@Entity
@Table(name = "t_demo")
public class DemoEntity {
    @Convert(converter = StatusAttributeConverter.class)
    private String status; //状态:1 启用,-1 禁用,-2 已删除
}

示例2
将多在那之中坚数据类型调换为另几在那之中坚数据类型。

public class Demo
{
  @Column(length=2048, columnDefinition="text")
  @Convert(converter=com.sys.jpa.JSONObjectSerializeConvert.class)
  protected JSONObject smeta;

   //getter、setter
}

@Converter
public class JSONObjectSerializeConvert
    implements AttributeConverter<JSONObject, String>
{
    @Override
    public String convertToDatabaseColumn(JSONObject attribute)
    {
        return(
            attribute!=null ? attribute.toJSONString() : null
        );
    }

    @Override
    public JSONObject convertToEntityAttribute(String dbData)
    {
        return(
            dbData!=null ? JSON.parseObject(dbData) : null
        );
    }
}

若果有个别实体类的字段富含Date类型,那么数据库中应该积存的是 “yyyy-MM-dd hh:MM:ss”的方式,针对这种样式的寄存,@Temporal 有三种声明值对应。

style="font-size: large;">第一种:@Temporal(TemporalType.DATE)——》实体类会封装成日期“yyyy-MM-dd”的 Date类型。

style="font-size: large;">第三种:@Temporal(TemporalType.TIME)——》实体类会封装成时间“hh-MM-ss”的 Date类型。

style="font-size: large;">第三种:@Temporal(TemporalType.TIMESTAMP)——》实体类会封装成完整的年华“yyyy-MM-dd hh:MM:ss”的 Date类型。

 

二种评释:

写在字段上:

    @Temporal(TemporalType.TIMESTAMP)
    private Date birthday;

写在 getXxx方法上:

    @Temporal(TemporalType.DATE)
    @Column(name = "birthday", length = 10)
    public Date getBirthday() {
        return this.birthday;
    }

 

 

1

本文由开元棋牌发布于数据库,转载请注明出处:Hibernate 注解之 @Temporal

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。