关联(JPA注解关联)
数据库需求表:
图书详情表:
CREATE TABLE book_info
(
book_id
bigint(20) NOT NULL AUTO_INCREMENT,
book_name
varchar(100) DEFAULT NULL,
book_author
varchar(100) DEFAULT NULL,
book_price
double DEFAULT NULL,
book_date
bigint(20) DEFAULT NULL,
book_publish
varchar(100) DEFAULT NULL,
book_desc
varchar(200) DEFAULT NULL,
type_id
bigint(20) DEFAULT NULL,
PRIMARY KEY (book_id
),
KEY type_id
(type_id
),
CONSTRAINT FK2tmm8w07nk0i13mqlho6jdkcf
FOREIGN KEY (type_id
) REFERENCES book_type
(type_id
) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
图书分类表 :
CREATE TABLE book_type
(
type_id
bigint(20) NOT NULL AUTO_INCREMENT,
type_name
varchar(100) DEFAULT NULL,
type_desc
varchar(200) DEFAULT NULL,
PRIMARY KEY (type_id
)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;
开发流程
第一步:创建WEB项目,加入核心配置文件
注册多个实体
与之前保持一致
注意方言:org.hibernate.dialect.MySQL55Dialect
映射建表注意:
<property name="hibernate.hbm2ddl.auto" value="update" />
在DB中可先创建好表
第二步:创建注解的ORM映射实体类
手动建表注意POJO属性和表的字段映射一致,或者使用@Column可以做映射。
使用JPA实现的目标:
Hibernate的方式:有实体类和ORM映射文件
JPA目标:只有注解的实体类(包含ORM映射关系)
多对一:
@ManyToOne
@JoinColumn(name="type_id")//描叙关联字段
private BookType bookType;//多对一关系
一对多:
@OneToMany(mappedBy=“bookType”)//关联对象定义的变量,也就是多对一关系中对象的属性名称。在多对一关系的时候指定了字段,这里不需要再指定字段。
private Set<BookInfo> bookInfos = new HashSet<BookInfo>(0);//一对多关系
@Entity
@Table(name = "book_info")
public class BookInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "book_id")
private Long bookId;
@Column(name = "book_name")
private String bookName;
@Column(name = "book_author")
private String bookAuthor;
@Column(name = "book_price")
private Double bookPrice;
@Column(name = "book_date")
private Long bookDate;
@Column(name = "book_publish")
private String bookPublish;
@Column(name = "book_desc")
private String bookDesc;
@ManyToOne
@JoinColumn(name = "type_id")
private BookType bookType;//多对一的关联,一定不要定义单个的type_id字段。
public Long getBookId() {
return bookId;
}
public void setBookId(Long bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookAuthor() {
return bookAuthor;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
public Double getBookPrice() {
return bookPrice;
}
public void setBookPrice(Double bookPrice) {
this.bookPrice = bookPrice;
}
public Long getBookDate() {
return bookDate;
}
public void setBookDate(Long bookDate) {
this.bookDate = bookDate;
}
public String getBookPublish() {
return bookPublish;
}
public void setBookPublish(String bookPublish) {
this.bookPublish = bookPublish;
}
public String getBookDesc() {
return bookDesc;
}
public void setBookDesc(String bookDesc) {
this.bookDesc = bookDesc;
}
public BookType getBookType() {
return bookType;
}
public void setBookType(BookType bookType) {
this.bookType = bookType;
}
}
@Entity
@Table(name = "book_type")
public class BookType {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "type_id")
private Long typeId;
@Column(name = "type_name")
private String typeName;
@Column(name = "type_desc")
private String typeDesc;
//一对多
@OneToMany(mappedBy = "bookType")//这个名称和BookInfo中关联对象属性的名称一致
private Set<BookInfo> books = new HashSet<BookInfo>();
public Long getTypeId() {
return typeId;
}
public void setTypeId(Long typeId) {
this.typeId = typeId;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public String getTypeDesc() {
return typeDesc;
}
public void setTypeDesc(String typeDesc) {
this.typeDesc = typeDesc;
}
public Set<BookInfo> getBooks() {
return books;
}
public void setBooks(Set<BookInfo> books) {
this.books = books;
}
}
注册实体:
public class BookTypeDAO {
public void addType(BookType bookType){
EntityManager entityManager = JPAUtils.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(bookType);
transaction.commit();
entityManager.close();
}
public static void main(String[] args) {
BookType bookType = new BookType();
bookType.setTypeName("好好学习");
bookType.setTypeDesc("天天向善");
BookTypeDAO dao = new BookTypeDAO();
dao.addType(bookType);
}
}
public class BookInfoDAO {
public void addBook(BookInfo pojo){
EntityManager entityManager = JPAUtils.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(pojo);
transaction.commit();
entityManager.close();
}
public static void main(String[] args) {
BookInfo pojo = new BookInfo();
pojo.setBookName("Java入门到放弃");
pojo.setBookAuthor("二货");
pojo.setBookDesc("二一回");
pojo.setBookPublish("回收站");
pojo.setBookPrice(8.9);
pojo.setBookDate(System.currentTimeMillis());
//关联对象
BookType byId = new BookTypeDAO().findById(32L);
pojo.setBookType(byId);
BookInfoDAO dao = new BookInfoDAO();
dao.addBook(pojo);
}
}
注意图书关联了分类对象。
注解的检索方式
延迟检索:(一对多的默认检索方式)
@ManyToOne(fetch=FetchType.LAZY)
立即检索:(多对一的默认检索方式)
@OneToMany(mappedBy="friendtype",fetch=FetchType.EAGER)
多对一默认是立即检索
直接获取分类信息,打印分类信息不打印SQL。
public void findById(Long id){
EntityManager entityManager = JPAUtils.getEntityManager();
BookInfo bookInfo = entityManager.find(BookInfo.class, id);
//主表
System.out.println(bookInfo.getBookName());
System.out.println("============================");
//关联表
BookType bookType = bookInfo.getBookType();
System.out.println(bookType.getTypeName());
entityManager.close();
}
修改为延迟检索:
第一步:修改配置:
第二步:核心代码
打印关联表信息时,同时发出SQL语句查询。注意Idea需要用运行模式测试。
public BookType findById(Long typeID){
EntityManager entityManager = JPAUtils.getEntityManager();
BookType bookType = entityManager.find(BookType.class, typeID);
//主表
System.out.println(bookType.getTypeName());
System.out.println("============================");
//关联表
Set<BookInfo> books = bookType.getBooks();
for (BookInfo book : books) {
System.out.println(book.getBookName());
}
entityManager.close();
return bookType;
}
一对多默认是延迟检索:
观察SQL:
修改为立即检索:
第一步:POJO中加入立即检索
第二步:代码
public void findByTypeId(Long id){
EntityManager entityManager = JPAUitls.createSession();
BookType bookType = entityManager.find(BookType.class, id);
System.out.println(bookType.getTypeName());
System.out.println("====================================================");
System.out.println("分类对应的图书信息:");
Collection<BookInfo> bookInfosByTypeId = bookType.getBookInfosByTypeId();
for (BookInfo bookInfo : bookInfosByTypeId) {
System.out.println(bookInfo.getBookName()+"\t"+bookInfo.getBookAuthor());
}
entityManager.close();
}
观察: