JPA关联

作者: 神豪VS勇士赢 | 来源:发表于2018-08-27 20:11 被阅读14次

    关联(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项目,加入核心配置文件
    注册多个实体
    与之前保持一致

    image.png

    注意方言:org.hibernate.dialect.MySQL55Dialect
    映射建表注意:
    <property name="hibernate.hbm2ddl.auto" value="update" />

    在DB中可先创建好表

    第二步:创建注解的ORM映射实体类
    手动建表注意POJO属性和表的字段映射一致,或者使用@Column可以做映射。
    使用JPA实现的目标:
    Hibernate的方式:有实体类和ORM映射文件

    image.png

    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;
    }
    }

    注册实体:

    image.png

    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();
    }

    修改为延迟检索:

    第一步:修改配置:

    image.png image.png image.png

    第二步:核心代码
    打印关联表信息时,同时发出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;
    }

    一对多默认是延迟检索:

    image.png

    观察SQL:

    image.png

    修改为立即检索:

    第一步:POJO中加入立即检索

    image.png

    第二步:代码

    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();
    }

    观察:

    相关文章

      网友评论

          本文标题:JPA关联

          本文链接:https://www.haomeiwen.com/subject/qxntwftx.html