ORM的核心就是对象关系映射,所以弄清楚对象和数据库之间的关系至关重要。
这是我最近读文档和书的一些笔记,分成几个合理的部分,这是第一篇!后面的文章都会在类别ORM中进行发布!
@Entity注解的实体对象中的属性,在持久化到数据库的过程中,要经过转换为Hibernate类型,在转换为JDBC类型,以下是基本类型的转换:
Hibernate类型 | JDBC类型 | Java类型 |
---|---|---|
StringType | VARCHAR | java.lang.String |
BooleanType | BIT | java.lang.Boolean |
ByteType | TINYINT | java.lang.Byte |
BigIntegerType | NUMERIC | java.math.BigInteger |
BigDecimalType | NUMERIC | java.math.BigDecimal |
TimeStampType | TIMESTAMP | java.sql.TimeStamp |
DataType | DATE | java.sqlDate |
BLobType | BLOB | java.sql.Blob |
ClobType | CLOB | java.sql.CLOB |
除了BLOB和CLOB,其他的都会出现在本篇中吧。
主键
关于
@Entity(name="cilent")
public class Library{
@Id
@GeneratedValue //仅仅是个标记
private long id;
//@Basic 在id属性和name属性上都被忽略
private String name;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="book_id")
private Set<Book> books=new HashSet<>();
//基础的setter和getter省略
}
主键只需要标识用@Id
注解就好,不过我发现里面很有讲究:
关于@JoinColumn参考:CSDN-@JoinColumn
如果你在Session中取Id相同的两个对象两次,Hibernate在同一Session周期内保证对象相同。但是如果两个主键相同的对象如果在两个不同的Session中被访问,他们的相同就无法保证了。
例如:
//在两个Session访问主键相同的对象
Book book1=doInJPA(this::entityManagerFactory,entityManager->
{
return entityManager.find(Book.class,1L);
});
Book book2=doInJPA(this::entityManagerFactory,entityManager->
{
return entityManager,find(Book.class,1L);
});
assertFalse(book1=book2);
解决方案是重写equals
和hashCode()
方法,书籍出版的ISBN号能够唯一的标识一个书籍。那么重写的equals
和hashCode()
方法应该符合这一要求。然后因为根据ISBN号进行比较,最好将ISBN号注解为@NaturalId
.
注解ISBN
@NatralId
private String ISBN
重写的equals和hashCode
@Override
public boolean equals(Object o){
if(this==o){
return true;
}
if(o==null||getClass()!=o.getClass()){
return false;
}
Book book=(Book)o;
return Objects.equals(isbn,book.getISBN());
}
@Override
public int hashCode(){
return Objects.hash(ISBN);
}
版本控制
为了并发乐观锁中提供实施细粒度悲观锁的控制,你需要加一个@Version
,这个属性应该是long型。
@Version
public long version;
可嵌入的对象
两个对象之间会出现包含的关系,比如上例中的Library和Book,如果包含关系是一对一的,你只需要简单将Book类注解@Embeddle
@Embeddle
public class Book{
//符合POJO
}
但是需要注意的是,可嵌入对象中不能再定义集合类属性,也就是说可以嵌入其他可嵌入对象(也就是被@Embeddle
注解的对象),但是不能再定义集合类属性了。
映射时间
映射时间应该很常用,就记录一下:三种类型
- Date:2018-4-27
- Time:22:12:12
TimeStamp:2018-4-27 22:12:12:564(纳秒 )
你可利用注解Date对象实现你想要的这三种格式,只需要一个
TemporalType
枚举值。
@Temporal(TemporalType.DATE) //TIME||TIMESTAMP
private Date timestamp;