hibernate注解JPA

 1.JPA与hibernate

 什么是JPA ? 

  java persistence api :java持久化api,同一的ORM规范,是由sun公司指定的规范接口,hibernate实现了JPA规范。

 

  我们可以使用javax.persistence下的注解,配置实体类,使用hibernate的session操作。在hibernate.cfg.xml中配置映射文件:

<mapping class="">

2. 如何搭建JPA环境

2.1 导入jar包

(1)required

(2)mysql数据库驱动

 

(3)JPA

2.2 配置文件

(1)在src目录下创建META-INF目录(java项目),在该目录下创建persistence.xml主配置文件,

 

  xsd约束在下面的目录下找:

 

 (2)配置持久化单元<persistence-unit>

<?xml version="1.0" encoding="UTF-8"?>
<!-- 主配置文件,名称必须为persistence.xml 放在META-INF下 -->
<!-- 导入xsd约束 -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
            http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
            <!-- 
                persistence-unit:用于配置持久化单元,可以配置多个
                    属性:name:指定持久化单元名称 如果配置多个,名称不能重复
                    transaction-type:用于指定事务类型
                        可选值:
                            RESOURCE_LOCAL:本地事务类型(我们一般用这个)
                            JTA:一般是在集群情况下使用(我们不管)
             -->
            <persistence-unit name="myJPAUnit" transaction-type="RESOURCE_LOCAL">
                <!-- 用于配置指定JPA规范的提供商   可以不配置 -->
                <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
                <!-- 用于指定使用JPA注解的实体类位置   可以不配置-->
                <class>cn.getword.domain.User</class>
                <class>cn.getword.domain.Student</class>
                <class>cn.getword.domain.Clazz</class>
                <!-- 主要配置 都来源于我们之间的 hibernate.cfg.xml文件中的配置 -->
                <properties>
                    <!-- 第一部分:连接数据库的信息 可以从源码包的project 的etc下的hibernate.properties文件中找到-->
                     <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
                     <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/db_hibernate2?characterEncoding=utf-8"/>
                     <property name="hibernate.connection.username" value="root"/>
                     <property name="hibernate.connection.password" value="123"/>
                     <!-- 配置数据库方言 -->
                     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
                     
                     <!-- 第二部分:hibernate配置的可选项  可以从源码包的project 的etc下的hibernate.properties文件中找到-->
                     <!-- 配置是否在控制台输出sql语句 -->
                     <property name="hibernate.show_sql" value="true"/>
                     <!-- 配置是否以格式化的方式输出sql语句 -->
                     <property name="hibernate.format_sql" value="false"/>
                     <!-- 配置DDL执行方式:
                             可选值:
                                 update:在运行的时候,判断实体类结构与表结构是否一致,如果不一致,就更新表结构
                                     如果表不存在,则创建 -->
                     <property name="hibernate.hbm2ddl.auto" value="update"/>
                     
                     <!-- 配置连接池的提供商 为c3p0-->
                    <!--  <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/> -->
     
                </properties>
            </persistence-unit>
</persistence>
View Code

 

 

(3)JPAUtil:获取数据库操作对象

package cn.getword.utils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtil {
    private static EntityManagerFactory factory;
    //对EntityManagerFactory进行初始化
    static {
        //参数是我们主配置文件中的持久化单元名称
        factory = Persistence.createEntityManagerFactory("myJPAUnit");
    }
    
    //提供获取EntityManager的方法
    public static EntityManager createEntityManager() {
        return factory.createEntityManager();
    }
    
    public static void main(String[] args) {
        createEntityManager();
    }
    
}
View Code

 

 

 

2.3 实体类注解

  由于hibernate遵循JPA规则,因此所有注解类都在javax.persistence包下。

@Entity
@Table(name = "tb_user")
public class User implements Serializable {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column(name = "username")
    private String username;
    @Column(name = "age")
    private Integer age;
    @Column(name = "deleted")
    private Integer deleted;
//get和set方法省略
}
View Code

 

 

@Entity():用于声明该类是一个实体类, 名称和HQL的实体类名对应

@Table()

@Id:主键字段

@Column():指定该属性在表中对应的字段名

  @Column(nullable=false,columnDefinition=”INT default 0”) 

  用注解设置属性的默认值时

  @Temporal(TemporalType.TIMESTAMP)
  @Column(updatable = false,nullable=false,length=20, unique=true)
  public Date getPubDate() {
    return pubDate;
  }
  • 默认值
  • unique索引 

 

 

@GeneratedValue(strategy="")  :主键生成策略

 

(1)一对多

package cn.getword.domain;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "tb_clazz")
public class Clazz implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column
    private String className;

    //实例化,可以防止空指针异常
    //targetEntity:目标对象
    // mappedBy:维护关系反转,值为对方实体类中定义的当前类的属性名【也就是Student类中定义的Clazz属性名】
    //cascade:级联操作
    // 默认是lazy加载
    @OneToMany(targetEntity = Student.class, mappedBy = "clazz2", cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    private Set<Student> students = new HashSet<>(0); //长度设为0

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    @Override
    public String toString() {
        return "Clazz{" +
                "id=" + id +
                ", className='" + className + '\'' +
                '}';
    }
}
Clazz.java

 

 

package cn.getword.domain;

import javax.persistence.*;
import javax.print.attribute.standard.MediaSize;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "tb_student")
public class Student implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column
    private String stuName;
    @Column
    private Integer age;
    // 目标类  级联操作
    @ManyToOne(targetEntity = Clazz.class, cascade = {CascadeType.ALL})
    // 外键关系  外键名称   依赖表的主键名称
    @JoinColumn(name = "clazz_id", referencedColumnName = "id")
    private Clazz clazz2;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Clazz getClazz2() {
        return clazz2;
    }

    public void setClazz2(Clazz clazz2) {
        this.clazz2 = clazz2;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", stuName='" + stuName + '\'' +
                ", age=" + age +
                '}';
    }
}
Student.java

 

 

   Clazz:一的一方

@OneToMany(targetEntity = , mappedBy="")   

  mappedBy:维护关系权利反转

第一:mappedBy这个注解只能够用在@OntToOne,@OneToMany,@manyToMany中,不能够用在@manyToOne中;

第二,这个注解看网上的意思可以简单地理解为:这个注解用在主表的一方,就是被引用的一方;

第三,这个注解是与@JoinColumn这个注解是互斥的,因为@JoinColumn这个注解使用在拥有外键的表的一方,就是从表的一方。

第四,这个注解的属性值是:指向另外一个类中定义的一个属性。这里指的是Student类中定义的Clazz属性名(clazz2)。

    student:多的一方

@ManyToOne(targetEntity=)

@JoinColumn(name="", referenceColumnName="")  外键名称,依赖表id名称

 

(2)多对多

package cn.getword.domain;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "tb_student")
public class Student implements Serializable {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @Column(name = "s_id", length = 32)
    private String sid;
    @Column
    private String stuName;
    @Column
    private Integer age;
    // 目标类  级联操作
    @ManyToOne(targetEntity = Clazz.class, cascade = {CascadeType.ALL})
    // 外键关系  外键名称   依赖表的主键名称
    @JoinColumn(name = "clazz_id", referencedColumnName = "cid")
    private Clazz clazz2;


    @ManyToMany
    @JoinTable(name = "tb_teacher_student", joinColumns = {
            @JoinColumn(name = "sid", referencedColumnName = "s_id"), // 当前实体类对应的表中的字段【主键】提供给中间表作为外键
    }, inverseJoinColumns = {
            @JoinColumn(name = "tid", referencedColumnName = "t_id")// 对方放弃权利的实体类对应的表中的字段【主键】提供给中间表作为外键
    })
    private Set<Teacher> teachers = new HashSet<>(0);

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Clazz getClazz2() {
        return clazz2;
    }

    public void setClazz2(Clazz clazz2) {
        this.clazz2 = clazz2;
    }

    public Set<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(Set<Teacher> teachers) {
        this.teachers = teachers;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + sid +
                ", stuName='" + stuName + '\'' +
                ", age=" + age +
                '}';
    }
}
Student.java

 

  

package cn.getword.domain;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "tb_teacher")
public class Teacher implements Serializable {
    @Id
    @GeneratedValue(generator = "uuid")  // 使用名为uuid的生成器
    @GenericGenerator(name = "uuid", strategy = "uuid")  // 声明一个名为uuid的生成器,生成策略为uuid
    @Column(name = "t_id", length = 32)
    private String tid;
    @Column
    private String name;


    @ManyToMany(mappedBy = "teachers")
    private Set<Student> students = new HashSet<Student>(0);

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    public String getTid() {
        return tid;
    }

    public void setTid(String tid) {
        this.tid = tid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
Teacher.java

 

 

  Teacher:放弃维护关系

@ManyToMany(mappedBy="teachers")  必须有一方放弃维护关系的权利

 

  Student:维护关系

@ManyToMany(cascade = )

@JoinTable():

@JoinTable(name = "tb_teacher_student", joinColumns = {
@JoinColumn(name = "sid", referencedColumnName = "s_id"), // 当前实体类对应的表中的字段【主键】提供给中间表作为外键
}, inverseJoinColumns = {
@JoinColumn(name = "tid", referencedColumnName = "t_id")// 对方放弃权利的实体类对应的表中的字段【主键】提供给中间表作为外键
})

 

 

uuid错误:

  原因:字段长度太大,mysql容不下,需要把编码设为utf8,把主键长度设为固定长度

 

 

 

 2.4 JPA工具类

package cn.getword.utils;

import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtil {
    private static EntityManagerFactory factory;
    //对EntityManagerFactory进行初始化
    static {
        //参数是我们主配置文件中的持久化单元名称
        factory = Persistence.createEntityManagerFactory("myJPAUnit");
    }
    
    //提供获取EntityManager的方法
    public static EntityManager createEntityManager() {
        return factory.createEntityManager();
    }

    @Test
    public void test() {
        EntityManager entityManager = JPAUtil.createEntityManager();
    }
    
}
JPAUtil.java

 

 

 2.5 操作

   一般不使用JPA操作,仅仅使用JPA的注解,对于数据库操作还是使用hibernate提供的session。

 

 

 3. JPA配置和hibernate操作结合

   使用JPA的注解、hibernate的操作。day31/hibernate_jpa3

 3.1 实体类

   和JPA一样

3.2 配置文件

  还是hibernate主配置文件:hibernate.cfg.xml

  需要修改的是:<mapping class="" />

3.3 数据库操作不变

 

 

 

end

posted @ 2018-10-11 11:25  fight139  阅读(421)  评论(0编辑  收藏  举报