添加方式:
一是写在属性字段上面
二十写在属性的get访问器的上面
有哪些属性级别注解?
@Id @SequenceGenerator @GeneratedValue @Column @Embedded @EmbeddedId @Lob @Version @Basic @Transient
@Id
@Id:必须。定义了映射到数据库表的主键的属性,一个实体类可以有一个或者多个属性被映射为主键,可置于主键属性或者getXxxx()前。
注意:如果有多个属性定义为主键属性,该实体类必须实现serializable接口。
先拷贝一份之前的例子,在getSid方法上边有@Id注解,也可以不写在这里,可以写在private int sid;
上边。也同样可以创建表
这个时候想给sname也作为主键
@Id
private int sid;
@Id
private String sname;
这时候Students类要实现Serializable接口。
但是这个时候还是无法将表创建成功,因为指定的第二个类型的主键sname是字符串类型,但是并没有指定它映射到数据库中字段的长度。String类型默认的长度是255,但是mysql规定如果这个字段是字符串类型,并且要作为主键,那么长度不能过长,如何来限定字段的长度?
需要用到@Column注解,表示字段类型,里边可以指定length,是映射成数据库表里的长度。
@Id
private int sid;
@Id
@Column(length=8)
private String sname;
@GeneratedValue
@GeneratedValue(strategy=GenerationType,generator=”“)
有两个属性,一个是策略属性一个是主键生成器,两个都是用来指定主键生成的策略,都是可选的。
strategy策略属性,它是我们JPA注解所定义的主键生成策略,取值有:
1.GenerationType.AUTO:根据底层数据库自动选择(默认)
比如mysql默认的主键的生成策略是自动增长类型,并且要求这个自动增长类型必须是整型
2.GenerationType.INDENTITY:根据数据库的Identity字段生成
3.GenerationType.SEQUENCE:使用Sequence来决定主键的取值
4.GenerationType.TABLE:使用指定表来决定主键取值,结合@TableGenerator使用
比如:
@Id
@TableGenerator(name=”tab_cat_gen”,allocationSize=1)
@GeneratedValue(Strategy.GenerationType.Table)
这里@Id表示这个字段是一个主键,@TableGenerator表示用这个主键生成的这个表叫做tab_cat_gen,allocationSize是分配的空间大小,@GeneratedValue表示这个主键是借助一张表来实现的。
回到例子中,只在sid属性上加上@Id注解,只是这样是无法保证一定是自动增长类型,还要加上组件生成策略,加上@GeneratedValue,就可以生成表,并且主键sid是自动增长的。
这里@GeneratedValue等同于@GeneratedValue(strategy=GenerationType.AUTO)
要注意,sid是int类型的,字符串类型的是不可以指定GenerationType.AUTO的。
那么如果private String sid
为String类型要怎么做?
按理来说,字符串类型的属性,其中的值应该是人为给定的,也就是手工赋值,那么注解如何配置。
还是要用@GeneratedValue,但是生成策略不可以用JPA的生成策略,要指定一个主键生成器:
@GeneratedValue(generator="sid")
然后要写一个Hibernate注解,@GenericGenerator,里边有两个常用属性,name和strategy。name和@GeneratedValue中指定的是一致的,strategy是一个字符串类型,固定的写法,手工赋值的话要写为assigned。
@GenericGenerator(name="sid",strategy="assigned")
同时String类型要指定长度,所以加上@Colume(length=8)
完整的应该是:
@Id
@GeneratedValue(generator="sid")
@GenericGenerator(name="sid",strategy="assigned")
@Column(length=8)
private int sid;
然后是在测试类中添加相应的代码:
@Test
public void addStudents(){
//创建配置对象
Configuration config = new Configuration().configure();
//创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//创建会话工厂对象
SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
//创建会话
Session session = sessionFactory.getCurrentSession();
//创建事务
Transaction tx = session.beginTransaction();
//创建学生对象
Address add = new Address("000000","XX省XX市","319284798752");
Students s = new Students("s0000001","某某人","男",new Date(),"主修",add);
session.save(s);
tx.commit();
}
可以成功创建表并添加记录,并且sid为自己手动赋值的s0000001.
@Column
可将属性映射到列,使用该注解来覆盖默认值。@Column描述了数据表中该字段的详细定义,这对于根据JPA注解生成数据库表结构的工具非常有作用。
常用属性:
name:可选,表示数据库表中该字段的名称,默认与属性名称一致
nullable:可选,该字段是否允许为null,默认为true
unique:可选,表示该字段是否是唯一标识,默认为false
length:可选,表示该字段的大小,仅对String类型有效,默认为255.(如果是主键不能使用默认值)。
insertable:可选,表示在ORM框架执行插入操作时,该字段是否应该出现INSERT语句中,默认为true
updateable:可选,表示在ORM框架执行更新操作时,该字段是否应该出现UPDATE语句中,默认为true。对于一经创建就不可以更改的字段,该属性非常有用,如对于birthday字段。
@Column这个注解用的并不多,一般会使用到的是length。
@Embedded
该注解表示该属性的类是嵌入类
注意:同时嵌入类也必须标志@Embeddable注解。
在学生实体类中,地址是一个嵌入类对象,可以在add属性上边添加@Embedded注解。在Address类上也加上了@Embeddable注解。
@Embedded
private Address add;
@EmbeddedId
这个注解通常是使用嵌入式主键类实现复合主键。
注意:嵌入式主键类必须实现Serializable接口、必须有默认的public无参数的构造方法、必须覆盖equals和hashCode方法。
写一个学生主键类,里边有两个属性,sid和id,分别代表身份证号和学号。类中还有无参构造函数和实现了父类的两个方法。
public class StudentsPK implements Serializable{
/**
*
*/
//生成的版本序列号
private static final long serialVersionUID = 1L;
private String id;
private String sid;
public StudentsPK(){
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return super.equals(obj);
}
}
然后要把Students类中是基本类型的sid这样的主键修改掉,改为复合主键,StudentsPK类型的pk,并且对后续的一些内容也要修改(构造方法,get/set方法)。
这个主键上可以加上注解:
@EmbeddedId
private StudentsPK pk;
同时主键类上也要加上@Embeddable注解。
测试类如下:
@Test
public void addStudents(){
//创建配置对象
Configuration config = new Configuration().configure();
//创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
//创建会话工厂对象
SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);
//创建会话
Session session = sessionFactory.getCurrentSession();
//创建事务
Transaction tx = session.beginTransaction();
//创建学生对象
Address add = new Address("000000","XX省XX市","319284798752");
//创建学生主键对象
StudentsPK pk = new StudentsPK();
pk.setId("123456789123456789");
pk.setSid("s0000001");
Students s = new Students(pk,"某某人","男",new Date(),"主修",add);
session.save(s);
tx.commit();
}
这样就可以成功创建表并且添加记录。
@Transient
可选,表示该属性并非一个要映射到数据库表里的字段,ORM框架将忽略该属性,如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则ORM框架默认其注解为@Basic。