hibernate_注解

@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

    @Column(name="name",length=20)  

    public String getName() {  

        return name;  

    }  

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() {  

    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() {  

    return birth;  

}  

 

@MappedSuperclass

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

@MappedSuperclass

public class BaseEntity implements Serializable{

private static final long serialVersionUID = 1L;

private Long id;  

    private String name;  

    private Integer age;  

    private Date birth;

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

@Entity

@Table(name="user")

public class User extends BaseEntity {

    private Double height;  

 

@Transient

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

    @Transient

    private List<String> lists = new ArrayList<String>();

 

@Lob

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

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

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

    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表:

 

School表:

 

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

User类中:

private List<String> 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<String> getSchooles() {

return schooles;

}

public void setSchooles(List<String> schooles) {

this.schooles = schooles;

}

 

写测试用例如下:

List<User> 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);

}

}

 

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

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

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值