转载

Java for Web学习笔记(一零八):Spring框架中使用JPA(8)再谈Entity数据映射

timestamp或datetime的匹配

存放毫秒

在数据库中缺省的精度为秒,如果需要存放毫秒甚至更好,可以如下:

CREATE TABLE Ticket (
  TicketId BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  UserId BIGINT UNSIGNED NOT NULL,
  Subject VARCHAR(255) NOT NULL,
  Body TEXT,
-- 精度为0.000001秒
  DateCreated TIMESTAMP(6) NULL,
  CONSTRAINT Ticket_UserId FOREIGN KEY (UserId)  REFERENCES UserPrincipal (UserId) ON DELETE CASCADE
) ENGINE = InnoDB;

-- 精度为毫秒
`DateCreated` datetime(3) NULL DEFAULT NULL,

匹配为java.sql.Timestamp

这是可以直接匹配

private Timestamp dateCreated;

@Basic
public Timestamp getDateCreated() {
	return dateCreated;
}

public void setDateCreated(Timestamp dateCreated) {
	this.dateCreated = dateCreated;
}

但java.sql.Timestamp不是很好使用,一般我们可以将其转换为Instant

Instant instant = Instant.now();
entity.setDateCreated(new Timestamp(now().toEpochMilli()));

和LocalDateTime的转换

目前并不支持和LocalDateTime的直接转换,但是我们可以通过一些小技巧,让用起来,就如同直接转换那样。

@Entity
public class TestEntity implements Serializable{
    private LocalDateTime createTime;

    // 采用private,也就是数据库的列的匹配并不直接开发出来,对使用者隐藏。
    @Basic
    @Column(name="create_time")
    private String getCreateTimeStr() {
        return createTime== null ? null : createTime.toString();
    }

    // setter同样采用private,这里的转换某种意义上是不规范的,没有考虑ISO8601中时区Z等携带信息,正式代码中需要补齐,这里只是简单测试
    @Basic
    @Column(name="create_time")
    private void setCreateTimeStr(String createTimeStr) {
        try{
            if(StringUtils.isBlank(createTimeStr))
                this.createTime =  null;
            else
                this.createTime =  LocalDateTime.parse(createTimeStr.replace(' ', 'T'));
        }catch(Exception e){
            this.createTime = null;
        }
    }	

    @Transient
    public LocalDateTime getCreateTime() {
        return createTime;
    }

    @Transient
    public void setCreateTime(LocalDateTime createTime) {
        this.createTime= createTime;
    }
    ......
}

采用Convert进行转换

前面的LocalDateTime的转换其实正规的应该使用Converter,下面以json存储的转换为对象为例子。假设是数据库的某一列使用text,存放的是json数据。我们可以用类似上面讲述的方式直接获取对象。

@Entity
public class TestPage implements Serializable{	
	private long id;
	private String userName;
	private String emailAddress;
	private Address address; //将数据库中以json text存放的信息和对象直接管理
	
	... ...	
	
	@Convert(converter=AddressConverter.class)
	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}
	
	public static class AddressConverter implements AttributeConverter<Address, String> {
		private static final Gson gson = new Gson();
		@Override
		public String convertToDatabaseColumn(Address attribute) {		
			return gson.toJson(attribute);
		}

		@Override
		public Address convertToEntityAttribute(String dbData) {
			return gson.fromJson(dbData, Address.class);
		}		 
	 }
}

关于gson

gson是json解析器,非常好使用。下面是其在pom.xml引入

<dependency>
    	<groupId>com.google.code.gson</groupId>
    	<artifactId>gson</artifactId>
    	<version>2.7</version>
</dependency>

我们希望直接将"time":"2018-01-12T09:47:51.411"直接映射为LocalDateTime。同样这里的转换代码只是为了测试便利,没有考虑ISO8601中时区Z等携带信息,正式代码中需要补齐。

public static Gson createGson(){
	return new GsonBuilder()
		.registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
		    @Override
		    public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
	    		return LocalDateTime.parse(json.getAsJsonPrimitive().getAsString());
	   	 }	    	    
		}).registerTypeAdapter(LocalDateTime.class,new JsonSerializer<LocalDateTime>() {
			@Override
			public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
				return new JsonPrimitive(src.toString());
			}
		}).create();
}
相关链接: 我的Professional Java for Web Applications相关文章
原文  http://blog.csdn.net/flowingflying/article/details/79199320
正文到此结束
Loading...