Hibernate注解开发通过实现JPA(Java Persistence API)规范,使用注解和配置文件进行开发。
PO类注解配置
用 @Entity
定义实体类,@Table
描述表与实体类的关系,@Id
声明主键,@GeneratedValue(strategy=GenerationType.)
用于设置主键生成策略,如果要使用uuid等Hibernate框架的主键生成策略,要先使用@GeneraticGenerator(name="myuuid",strategy="uuid")
,再@GeneratedValue(generator="myuuid")
,默认相当于native。@Column
用来定义列,@Temporoal
用来声明日期,最后要在hibernate.cfg.xml中配置PO的映射。例子:
@Entity//定义实体类
@Table(name="t_book",catalog="hibernatetest")
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="name",length=255,nullable=true)
private String name;
@Temporal(TemporalType.TIMESTAMP)
private Date publicationDate;
// @Type(type="double")
private Double price;
@Entity
@Table(name="t_person",catalog="hibernateTest")
public class Person {
@Id
@GenericGenerator(name="myuuid",strategy="uuid")
@GeneratedValue(generator="myuuid")
private String id;
@Type(type="string")
private String name;
@Transient
private Date birthday ;
<mapping class="domain.annocation.Book"/>
<mapping class="domain.annocation.Person"/>
test
@Test
public void test1(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Book book = new Book();
book.setName("挪威的森林");
book.setPrice(23.5d);
book.setPublicationDate(new Date());
Person person = new Person();
person.setName("直子");
person.setBirthday(new Date());
session.save(book);
session.save(person);
session.getTransaction().commit();
session.close();
}
一对多
以昨天的Customer和Order为例,
@Entity
@Table(name="t_customer",catalog="hibernatetest")
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
@OneToMany(targetEntity=Order.class,mappedBy="c",cascade=CascadeType.ALL,orphanRemoval=true)
private Set<Order> orders = new HashSet<>();
@Entity
@Table(name="t_order",catalog="hibernatetest")
public class Order {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private Double money;
private String receiveInfo;
@ManyToOne(targetEntity=Customer.class)
@JoinColumn(name="customer_id")
private Customer c;
Customer c = new Customer();
c.setName("绿子");
Order o1 = new Order();
Order o2 = new Order();
o1.setMoney(12d);
o2.setMoney(21d);
o1.setReceiveInfo("东京");
o2.setReceiveInfo("大阪");
o1.setC(c);
o2.setC(c);
c.getOrders().add(o1);
c.getOrders().add(o2);
session.save(c);
结果
多对多
多对多的关系会产生一张中间表,我们用学生和老师为例,用@ManyToMany
来配置多对多,只需要在一端配置中间表,另一端设置mappedBy来表示对外键的维护权。
@Entity
@Table(name="t_teac",catalog="hibernatetest")
public class Teacher {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
@ManyToMany(targetEntity=Student.class,mappedBy="teachers")
private Set<Student> students = new HashSet<>();
@Entity
@Table(name="t_stu",catalog="hibernatetest")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
@ManyToMany(targetEntity=Teacher.class)
@JoinTable(name="s_t",joinColumns={@JoinColumn(name="student_id")},
inverseJoinColumns={@JoinColumn(name="teacher_id")})
@Cascade(CascadeType.ALL)//在Student中配置级联
private Set<Teacher> teachers = new HashSet<>();
注意这里的Cascade和CascadeType都应该是org.hibernate.annotations包下的。
Test
@Test
public void test3(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Teacher t1 = new Teacher();
Teacher t2 = new Teacher();
t1.setName("teacher1");
t2.setName("teacher2");
Student s1 = new Student();
Student s2 = new Student();
s1.setName("student1");
s2.setName("student2");
s1.getTeachers().add(t1);
s1.getTeachers().add(t2);
s2.getTeachers().add(t1);
s2.getTeachers().add(t2);
session.save(s1);
session.save(s2);
session.getTransaction().commit();
session.close();
}
结果
一对一
一对一映射分为两种,在任意一方添加外键的外键映射,还有直接通过一方的主键映射。
外键映射
以公民和身份证为例:
@Entity
@Table(name="t_idcard",catalog="hibernatetest")
public class IDCard {
@Id
@GenericGenerator(name="i_uuid",strategy="uuid")
@GeneratedValue(generator="i_uuid")
private String id;
private String cardNum;
@OneToOne(targetEntity=Citizen.class)
@JoinColumn(name="citizen_id")
@Cascade(CascadeType.SAVE_UPDATE)
@Entity
@Table(name="t_citizen",catalog="hibernatetest")
public class Citizen {
@Id
@GenericGenerator(name="c_uuid",strategy="uuid")
@GeneratedValue(generator="c_uuid")
private String id;
private String name;
@OneToOne(targetEntity=IDCard.class,mappedBy="citizen")
private IDCard idcard;
@Test
public void test4(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Citizen citizen = new Citizen();
citizen.setName("渡边");
IDCard idcard = new IDCard();
idcard.setCardNum("123321123212321123");
idcard.setCitizen(citizen);
session.save(idcard);
session.getTransaction().commit();
session.close();
}
结果
- 主键映射
@Id
@GenericGenerator(name="i_uuid",strategy="uuid")
@GeneratedValue(generator="i_uuid")
private String id;
private String cardNum;
@OneToOne(targetEntity=Citizen.class)
@JoinColumn(name="citizen_id")
@PrimaryKeyJoinColumn
@Cascade(CascadeType.SAVE_UPDATE)
@Id
@GenericGenerator(name="myForeign",strategy="foreign",
parameters={@Parameter(name="property",value="idcard")})
@GeneratedValue(generator="myForeign")
private String id;
private String name;
@OneToOne(targetEntity=IDCard.class,mappedBy="citizen")
@PrimaryKeyJoinColumn
private IDCard idcard;
@Test
public void test5(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Citizen citizen = new Citizen();
citizen.setName("渡边");
IDCard idcard = new IDCard();
idcard.setCardNum("123321123212321123");
idcard.setCitizen(citizen);
citizen.setIdcard(idcard);//这里要做双向关联
session.save(idcard);
session.getTransaction().commit();
session.close();
}
结果