hibernate_注解

亦凉 2022-05-20 21:04 384阅读 0赞

@Entity

Po首先有一个Entity注解。标识此类为一个实体类。

@Table

Table注解的name属性指向数据库的表名

@Entity

@Table(name=”user”)

public class User implements java.io.Serializable {

@UniqueConstraint

唯一约束,其内部也会创建一个索引。

@Table(uniqueConstraints={

@UniqueConstraint(name=”index_name”,columnNames=”name”),

@UniqueConstraint(name=”index_nameage”,columnNames={ “name”,”age”})

})

其中columnNames为表的字段值。

@Index

索引

@Table(indexes=

{

@Index(name=”index_name”,columnList=”name”,unique=true),

@Index(name=”index_nameage”,columnList=”name,age”)

}

)

name属性为索引名称,

columnList为字段名

unique属性默认为false,表示普通索引。为true表示唯一约束索引,就和上面@UniqueConstraint一样了。

@Column

  1. @Column(name="name",length=20)
  2. **public** String getName() \{
  3. **return** name;
  4. \}

name属性为表的字段名

Length属性为字段长度

nullable属性为false表示不能为空,默认为true

unique属性为true表示唯一约束,会自动为其创建一个索引,如果上面已通过@UniqueConstraint创建了索引,将覆盖上面的索引。默认为false

insertable属性为false表示不能插入此字段,默认为true

updatable属性为false表示不能修改此字段,默认为true

columnDefinition属性为片段,注解在解析的时候将直接把片段中的内容放到sql语句中。如控制double类型精度,可以这么写:长度为10,精度为2(小数点后保留两位),默认值为0.00

@Column(name=”height”,columnDefinition=”double(10,2) default ‘0.00’”)

public Double getHeight() {

return height;

}

@Id @GeneratedValue

@Id // 主键

@GeneratedValue(strategy=GenerationType.IDENTITY)// 自增长

@Column(name=”ID”,unique=true)

public Long getId() {

  1. **return** id;

}

@Temporal

处理日期类型:

1、若只显示日期:即:yyyy-MM-dd

在属性的get方法设置:@Temporal(TemporalType.DATE)

2、显示日期与时间:即:yyyy-MM-dd hh:MM:ss

在属性的get方法设置: @Temporal(TemporalType.TIMESTAMP)

3、只显示时间:即:hh:MM:ss

在属性的get方法设置:@Temporal(TemporalType.TIME)

如:

@Temporal(TemporalType.DATE)

@Column(name=”birth_date”)

public Date getBirth() {

  1. **return** birth;

}

@MappedSuperclass

实体类基类,和@Table一样,但是不需要指向某一个表,也不需要在配置文件中加上mapping。

@MappedSuperclass

public class BaseEntity implements Serializable{

private static final long serialVersionUID = 1L;

private Long id;

  1. **private** String name;
  2. **private** Integer age;
  3. **private** Date birth;

父类如实现就可改为如下:

@Entity

@Table(name=”user”)

public class User extends BaseEntity {

  1. **private** Double height;

@Transient

@Transient表示该属性并非一个到数据库表的字段的映射,即此成员变量和数据库没有关系,可以用来对其他成员变量进行处理加工。

  1. @Transient
  2. **private** List<String> lists = **new** ArrayList<String>();

@Lob

LOB 代表大对象数据,包括 BLOB 和 CLOB 两种类型,前者用于存储大块的二进制数据,如图片数据,视频数据等,而后者用于存储长文本数据,如论坛的帖子内容,产品的详细描述等。

即:BLOB类型是字节类型,映射为实体中的类型可为byte[]、Byte[]。CLOB类型是长字符串类型,映射为实体中的类型可为char[]、Character[]、String类型。

  1. 值得注意的是:在不同的数据库中,大对象对应的字段类型是不尽相同的,如 DB2 对应 BLOB/CLOBMySql 对应 BLOB/LONGTEXTSqlServer 对应 IMAGE/TEXT。需要指出的是,有些数据库的大对象类型可以象简单类型一样访问,如 MySql LONGTEXT 的操作方式和 VARCHAR 类型一样。在一般情况下, LOB 类型数据的访问方式不同于其它简单类型的数据,我们经常会以流的方式操作 LOB 类型的数据。此外,LOB 类型数据的访问不是线程安全的,需要为其单独分配相应的数据库资源,并在操作完成后释放资源。
  2. **private** String content;// 存放大内容

private byte[] image;// 存放图片

private Blob image2;// 存放图片

@Lob

@Column(name=”content”)// 不要指定长度,mysql中就是longtext类型,有4M大小

public String getContent() {

return content;

}

@Lob

@Column(name=”image”)

public byte[] getImage() {

return image;

}

@Lob

@Column(name=”image2”)

public Blob getImage2() {

return image2;

}

注:在使用@Lob注解的时候可能会报一个错:(ILjava/io/Reader;J)

是因为JDBC驱动版本太低,mysql-connector-java-5.0.8-bin.jar

更新为5.1以上的版本,如:mysql-connector-java-5.1.6-bin.jar

应用:

读取本地图片,保存到记录:

{

Transaction tx = session.beginTransaction();

User user = new User();

try {

File file = new File(“d://good.png”);

byte[] bytes = new byte[(int)file.length()];

FileInputStream inputStream = new FileInputStream(file);

inputStream.read(bytes);

inputStream.close();

// 保存byte[]

user.setImage(bytes);

// 保存blob

user.setImageBolb(Hibernate.getLobCreator(session).createBlob(bytes));

session.save(user);

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

tx.commit();

}

查询记录,保存byte[]、blob到本地图片:

{

User user = (User)session.get(User.class, 1);// 取主键为1的记录

try {

FileOutputStream outputStream = new FileOutputStream(“e://test.png”);

// byte[]字段

byte [] bytes = user.getImage();

// blob字段

int nLength = (int) user.getImageBolb().length();

byte[] bytes = user.getImageBolb().getBytes(0, nLength);

outputStream.write(bytes);

outputStream.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

@Basic

对于一些特殊的属性,比如长文本型text、字节流型blob型的数据,在加载Entity时,这些属性对应的数据量比较大,有时创建实体时如果也加载的话,可能严重造成资源的占用。要想解决这些问题,此时就需要设置实体属性的加载方式为惰性加载(LAZY)。

@Lob

@Basic(fetch=FetchType.LAZY)

@Column(name=”image”)

public byte[] getImage() {

return image;

}

Fetch默认为FetchType.EAGER

即立即加载数据。

LAZY为懒加载,即使用session.get后此字段为null,只有当用到此字段时才去获取真正的数据。

@CollectionTable

关联表内容。如:school表中有个外键userId,指向user表的主键。那么user表中就可以如下定义以获取其对应的学校。

表结构如下:

User表:

70

School表:

70 1

即:gary毕业自一中和武大,mini毕业自北大。

在User类中:

private List schooles;

// schooles中的类型为String

@ElementCollection(targetClass=String.class)

// @CollectionTable 的name为表名,@JoinColumn 中的name为 school表中的外键名, referencedColumnName为user表中的主键

@CollectionTable(name=”school”,joinColumns={ @JoinColumn(name=”userId”,nullable=false,referencedColumnName=”id”)})

// 映射到school表的schoolname字段

@Column(name=”schoolname”)

public List getSchooles() {

return schooles;

}

public void setSchooles(List schooles) {

this.schooles = schooles;

}

写测试用例如下:

List users = session.createQuery(“from User”).list();

for (User u : users) {

System.out.println(u.getId() + “===” + u.getName());

for (String school : u.getSchooles()){

System.out.println(“毕业学校:”+school);

}

}

70 2

可以发现,同样是:List users = session.createQuery(“from User”).list();

如果输出的时候不输出school,则输出如下:

70 3

少了两次查询,可见这种查询是懒加载的。

发表评论

表情:
评论列表 (有 0 条评论,384人围观)

还没有评论,来说两句吧...

相关阅读

    相关 hibernate_注解

    @Entity Po首先有一个Entity注解。标识此类为一个实体类。   @Table Table注解的name属性指向数据库的表名 @Entity @Table

    相关 hibernate注解使用

    hibernate默认使用xml映射文件来关联实体和数据库表,随着系统的越来越复杂,每增加一个实体类,就需要配置一个xml映射文件,一般的系统少说也有十几个实体类,多的可能会有