一、Hibernate注解应用
1、 使用注解配置 PO对象
@Entity 实体类
@Table 生成目标表
@Id 主键
@GeneratedValue 主键生成策略
@Column 定义生成列
☆:注解开发优先使用 javax.persistence.* 包
package lsq.hibernate.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
//实体类
@Entity
// 设置生成表明
@Table(name = "book")
public class Book {
// 主键
@Id
// 主键生成策略
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// 普通属性可以使用@Column注解修饰,如果不写,列名就是属性名
@Column(name = "bookname", length = 20, unique = true, nullable = true)
private String name;
private Double price;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
* @Id、@GeneratedValue、@Column 可以修改属性,也可以放到属性get方法上
* 在hibernate.cfg.xml 配置注解类<mapping class="lsq.hibernate.domain.Book"/>
2、主键生成策略
@GeneratedValue(strategy = GenerationType.IDENTITY) --- 只支持四种策略
编写UUID 主键生成策略 Person
package lsq.hibernate.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name="person")
public class Person {
@Id
@GenericGenerator(name="myuuidgenerator",strategy="uuid")
@GeneratedValue(generator="myuuidgenerator")
private String id;//UUID
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3、其他属性
@Temporal 生成日期类型
@Transient 控制不生成
日期类型java.util.Date 对于MySQL 生成 datetime类,日期和时间都包括
* @Temporal(TemporalType.DATE) 数据表只保存日期
* @Temporal(TemporalType.TIME) 数据表只保存时间
* @Temporal(TemporalType.TIMESTAMP) 日期时间都保存
Hibernate 实体类中,所有get方法 属性, 都会在数据表 自动生成列
* 有时属性不想 生成列 @Transient 注解
4、一对多
配置Customer类:
package lsq.hibernate.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
@Table(name="customers")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
//targetEntity,类似<one-to-many class="">
//mappedBy,作用类似inverse=true
@OneToMany(targetEntity = Order.class, mappedBy = "customer")
//配置级联
@Cascade(value={CascadeType.SAVE_UPDATE})
private Set<Order> orders = new HashSet<Order>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
配置Orders
package lsq.hibernate.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String address;
@ManyToOne(targetEntity=Customer.class)
//添加外键列
@JoinColumn(name="customer_id")
private Customer customer;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
☆:jar冲突错误 java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()
* javaee.jar(myeclipse提供) 和 jpa的jar 冲突
* 解决 : 删除javaee.jar 中 javax.persistence 包
* 级联操作 @Cascade(value = { CascadeType.级别 })
DELETE_ORPHAN 已经过时 ,推荐使用 @OneToMany(orphanRemoval=true)
所有级联级别
@OneToMany(targetEntity = Order.class, mappedBy = "customer", orphanRemoval = true)
@Cascade(value = { CascadeType.ALL })
private Set<Order> orders = new HashSet<Order>();
5、多对多配置
@ManyToMany
* 注解配置多对多时,只需要一端配置中间表,另一端 mappedBy 放弃外键维护权
配置Course类:
package lsq.hibernate.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="courses")
public class Course {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String cname;
@ManyToMany(targetEntity = Student.class,mappedBy="courses")//把外键维护权交给对方
private Set<Student> students = new HashSet<Student>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
配置Student类:
package lsq.hibernate.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="students")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String sname;
@ManyToMany(targetEntity=Course.class)
//配置中间表
//joinColumns当前类在中间表中外键列名
//inverseJoinColumns对方类在中间表中外键列名
@JoinTable(name="student_course",joinColumns = {@JoinColumn(name="student_id")},inverseJoinColumns={@JoinColumn(name="course_id")})
private Set<Course> courses = new HashSet<Course>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
}
6、 抓取策略 (了解)
public class Customer {
// 抓取策略
@Fetch(FetchMode.SELECT)
@LazyCollection(LazyCollectionOption.TRUE)
private Set<Order> orders = new HashSet<Order>();
}
public class Order {
// 抓取策略
@Fetch(FetchMode.SELECT)
@LazyToOne(LazyToOneOption.FALSE)
private Customer customer;
}
关联级别抓取,配置@Fetch等价fetch属性, 关联集合 @LazyCollection , 关联单一对象 @LazyToOne
7、 NamedQuery 命名查询
@NamedQueries(value = { @NamedQuery(name = "findCustomerByName", query = "from Customer where name= ?") })
public class Customer {
...
}
程序代码:
Query query = session.getNamedQuery("findCustomerByName");
query.setParameter(0, "张三");
Customer customer = (Customer) query.uniqueResult();