当前位置: 首页 > news >正文

jpa

一、概述

java persistence api,jpa,是sun提出的java持久化规范。它提供了一种orm工具来管理java应用中的关系数据。jpa的总体思想和常见的orm框架大体一致。包括3方面的技术,orm映射元数据,支持xml和jdk5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架根据元元数据将实体对象持久化到数据表中;持久化api,用来操作实体对象,执行crud操作;查询语言,通过面向对象而不是面向数据库的查询语言查询数据。

二、入门案例

基于hibernate的案例。

步骤:

      1.创建一个java工程jpaabc

      2.自定义个jar库,放相关的jar

add library>user libray>user libraries>new>取个名字>add external jars>选择jar文件,注意路径中不要中文或空格>ok>finish

3.在src文件夹下创建META-INF文件夹,编写persistence.xml配置文件,文件名是固定的这个。

<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="jpaabc" transaction-type="RESOURCE_LOCAL" >

        <properties>

           <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect">

            <property name="hibernate.hbm2ddl.auto" value="update">

            <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver">

            <property name="hibernate.connection.username" value="root">

            <property name="hibernate.connection.password" value="1234">

            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa20181110? characterEncoding=UTF-8">

        </properties>

    </persistence-unit>

</persistence>

      4.编写实体类

**

 * person实体bean

 *

 * @author Administrator

 *

 */

@Entity

@Table(name = "t_person")

public class Person {

         @Id

         @Column(name = "id")

         @GeneratedValue(strategy = GenerationType.IDENTITY)

         private Integer id;

         @Column(name = "person_name", length = 10, nullable = false)

         private String name;

         @Column(name = "birthday")

         @Temporal(TemporalType.DATE) // 指定时间的格式

         private Date birthday;

         @Enumerated(EnumType.STRING)

         @Column(name = "gendar", length = 6, nullable = false)

         private Gendar gendar;



         @Lob

         private String info;

         @Lob

         @Basic(fetch = FetchType.LAZY) // 对于大文件属性字段延迟加载,优化性能

         private Byte[] file;

         @Transient

         private String picture;



         // 提供无参构造函数,供反射创建对象

         public Person() {

         }



         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 Date getBirthday() {

                   return birthday;

         }



         public void setBirthday(Date birthday) {

                   this.birthday = birthday;

         }



         public Gendar getGendar() {

                   return gendar;

         }



         public void setGendar(Gendar gendar) {

                   this.gendar = gendar;

         }



         public String getInfo() {

                   return info;

         }



         public void setInfo(String info) {

                   this.info = info;

         }



         public Byte[] getFile() {

                   return file;

         }



         public void setFile(Byte[] file) {

                   this.file = file;

         }



         public String getPicture() {

                   return picture;

         }



         public void setPicture(String picture) {

                   this.picture = picture;

         }



         @Override

         public String toString() {

                   return "Person [id=" + id + ", name=" + name + ", birthday=" + birthday + ", gendar=" + gendar + ", info="

                                     + info + ", file=" + Arrays.toString(file) + ", picture=" + picture + "]";

         }



}

      5.测试

/**

 * jpa测试类

 *

 * @author Administrator

 *

 */

public class PersonTest {

         /**

          * 测试保存

          */

         @Test

         public void save() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 获取事务管理类

                   EntityTransaction transaction = manager.getTransaction();

                   // 开启事务

                   transaction.begin();

                   // 提供存入的数据

                   Person person = new Person();

                   person.setName("张三");

                   person.setBirthday(new Date());

                   person.setGendar(Gendar.FEMALE);

                   person.setInfo("介绍下自己");

                   // 使用保存方法

                   manager.persist(person);

                   // 提交事务

                   transaction.commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 测试获取

          */

         @Test

         public void findPerson1() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 查找,find方法相当于hibernate的get方法

                   Person person = manager.find(Person.class, 1);

                   System.out.println(person);

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 测试获取

          */

         @Test

         public void findPerson2() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 查找,find方法相当于hibernate的load方法,只有在session关闭之前,第一次访问对象的属性时,才加载对象

                   // 第二个特点是,如果查询的数据不存在,则报出实体没找到异常

                   Person person = manager.getReference(Person.class, 2);

                   System.out.println(person);

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   // 如果关闭对象后,才第一次访问对象,则报出延迟加载异常

                   // System.out.println(person.getName());

                   emf.close();

         }



         /**

          * 测试获取

          */

         @Test

         public void updatePerson() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 获取事务管理类

                   EntityTransaction transaction = manager.getTransaction();

                   // 开启事务

                   transaction.begin();

                   // 现获取要更新的对象

                   Person person = manager.find(Person.class, 1);

                   person.setName("李四");

                   // 由于orm的持久对象的托管态的批处理机制,当关闭session时,可以自动更新数据到数据库

                   // manager.persist(person);

                   // System.out.println(person);

                   // 提交事务

                   transaction.commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 测试获取,游离态的实体对象,不能更新数据库

          */

         @Test

         public void updatePerson2() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 获取事务管理类

                   EntityTransaction transaction = manager.getTransaction();

                   // 开启事务

                   transaction.begin();

                   // 现获取要更新的对象

                   Person person = manager.find(Person.class, 1);

                   // 清楚实体管理器内的所有实体,也就是置为游离态

                   manager.clear();

                   person.setName("李五");

                   // 由于orm的持久对象的托管态的批处理机制,当关闭session时,可以自动更新数据到数据库

                   // manager.persist(person);

                   // System.out.println(person);

                   // 调用管理器的merge方法,将游离态的实体对象同步回管理器,可以将更新的数据到数据库

                   manager.merge(person);

                   // 提交事务

                   transaction.commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 测试删除

          */

         @Test

         public void deletePerson() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 获取事务管理类

                   EntityTransaction transaction = manager.getTransaction();

                   // 开启事务

                   transaction.begin();

                   // 现获取要删除的对象

                   Person person = manager.find(Person.class, 1);

                   // 删除对象

                   manager.remove(person);

                   // 提交事务

                   transaction.commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }

}

关于refresh方法,当用户通过find方法获取一条数据,在操作一条数据库期间,如果有另一个用户也操作修改了这条数据。那么,前面那个操作的用户,通过find方法是不能获取这条数据的最新数据的。因为,entitymanagy会把用户第一次find获取的数据结果放在一级缓存,如果后面又find一次,也是从一级缓存取得数据,而不是数据库。这时,使用refresh方法,这条数据,可以从数据库获取最新的数据结果。

三、jpa查询语句

使用上面入门案例的项目,在测试类中测试

/**

 * jpa测试类

 *

 * @author Administrator

 *

 */

public class PersonTest {

        

         /**

          * 测试查询语句

          */

         @Test

         public void query() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 查询语句

                   Query query = manager.createQuery("select p from Person p where p.id = ?1");

                   query.setParameter(1, 2);

                   // 获取查询结果

                   // List<Person> list = query.getResultList();

                   // System.out.println(list);

                   // 获取查询结果

                   Person person = (Person) query.getSingleResult();

                   System.out.println(person);

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 测试使用查询语句删除

          */

         @Test

         public void querydelete() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 查询语句

                   Query query = manager.createQuery("delete from Person p where p.id = ?1");

                   query.setParameter(1, 2);

                   // 执行更新

                   query.executeUpdate();

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 测试使用查询语句更新

          */

         @Test

         public void queryupdate() {

                   // 创建实体类管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaabc");

                   // 创建实体管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 查询语句

                   Query query = manager.createQuery("update Person p set p.name=:name where p.id=:id");

                   query.setParameter("name", "马六");

                   query.setParameter("id", 3);

                   // 执行更新

                   query.executeUpdate();

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }

}

四、一对多双向关联

jpa规范,一对多双向关联中,多方为关系维护端,负责外键记录的更新删除,关系被维护端没有维护外键字段的权利。

一方中的设置:

常用级联操作,类型有CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE。只有调用对应的方法,才能发生相应的级联操作,比如调用persist方法,设置的CascadeType.PERSIST起作用。

延迟加载设置,fetch=FetchType.LAZY。使用延迟加载,当获取了一方的数据时,不会立即获取到多方的数据,只有当操作多方数据才会获取多方的数据,前提是entitymanager没有被关闭。如果entitymanager被关闭了,那么会报出异常。如果是一对多,或者多对多,就是当对多时,加载方式的默认值是lazy,即延迟加载,目的是潜在提高效率。

设置关系的被维护端,指明是这个类中的哪个属性来被维护,也就是多方的类中的一方类对象定义的属性。使用mappedBy来设置。 mappedBy = "order"设置被维护端为这个对象的属性是order。

多方中的设置:

级联设置,一般不设置保存和删除,设置更新和刷新就可以。

加载设置,多对一,默认是立即加载。

可选性,optional,如果为true,那么外键值在表中可以为null;如果为false,则外键值在数据表中非空。

设置外键字段名称,@JoinColumn(name = "order_id")

例子,订单表和订单明细表的一对多关系案例

创建java项目,导入jar包,编写persistence.xml文件

编写order实体类

/**

 * 订单实体类

 *

 * @author Administrator

 *

 */

@Entity

@Table(name = "orders")

public class Order {



         @Id

         @Column(length = 32)

         private String orderId;

         @Column(nullable = false)

         private Float totalPrice = 0f;

         @OneToMany(cascade = { CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE,

                            CascadeType.REMOVE }, fetch = FetchType.LAZY, mappedBy = "order") // 默认就是懒加载,可以不设置延迟

         private Set<OrderItem> orderItems = new HashSet<OrderItem>();



         public String getOrderId() {

                   return orderId;

         }



         public void setOrderId(String orderId) {

                   this.orderId = orderId;

         }



         public Float getTotalPrice() {

                   return totalPrice;

         }



         public void setTotalPrice(Float totalPrice) {

                   this.totalPrice = totalPrice;

         }



         public Set<OrderItem> getOrderItems() {

                   return orderItems;

         }



         public void setOrderItems(Set<OrderItem> orderItems) {

                   this.orderItems = orderItems;

         }



}

订单明细实体类

/**

 * 订单项实体类

 *

 * @author Administrator

 *

 */

@Entity

@Table(name = "orderItem")

public class OrderItem {



         @Id

         @Column(name = "id")

         @GeneratedValue(strategy = GenerationType.AUTO)

         private Long id;

         @Column(length = 64, nullable = false)

         private String itemName;

         @Column(nullable = false)

         private Float price = 0f;

         @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false)

         @JoinColumn(name = "order_id")

         private Order order;



         public Long getId() {

                   return id;

         }



         public void setId(Long id) {

                   this.id = id;

         }



         public String getItemName() {

                   return itemName;

         }



         public void setItemName(String itemName) {

                   this.itemName = itemName;

         }



         public Float getPrice() {

                   return price;

         }



         public void setPrice(Float price) {

                   this.price = price;

         }



         public Order getOrder() {

                   return order;

         }



         public void setOrder(Order order) {

                   this.order = order;

         }



}

测试,添加订单,级联保存订单明细

/**

 * 测试一对多关联

 *

 * @author Administrator

 *

 */

public class One2ManyTest {



         @Test

         public void testSave() {

                   // 获取实体管理工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaone2many");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 获取事务管理对象

                   EntityTransaction transactionManager = manager.getTransaction();

                   // 开启事务

                   transactionManager.begin();

                   // 准备数据

                   Order order = new Order();

                   OrderItem item1 = new OrderItem();

                   item1.setItemName("硬盘");

                   item1.setPrice(120f);

                   item1.setOrder(order);

                   OrderItem item2 = new OrderItem();

                   item2.setItemName("内存卡");

                   item2.setPrice(20f);

                   item2.setOrder(order);

                   OrderItem item3 = new OrderItem();

                   item3.setItemName("线卡");

                   item3.setPrice(220f);

                   item3.setOrder(order);

                   order.setTotalPrice(item1.getPrice() + item2.getPrice() + item3.getPrice());

                   Set<OrderItem> items = new HashSet<>();

                   items.add(item1);

                   items.add(item2);

                   items.add(item3);

                   order.setOrderItems(items);

                   // 设置id

                   String id = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

                   id = id + "_" + UUID.randomUUID().toString().substring(0, 10);

                   order.setOrderId(id);

                   // 因为在一方设置了级联保存,所以保存一方就保存了多方

                   manager.persist(order);

                   // 提交事务

                   transactionManager.commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }

}

五、一对一双向关联

被维护端的设置:

需要在OneToOne注解中,设置mappedBy,设置维护方类中被维护方属性的值,比如,mappedBy = "idCard"。级联根据业务需要设置。

维护端的设置:

在OneToOne注解中,设置optional为false。级联根据需要设置。

人和身份证一对一的案例。

人实体类

/**

 * 人的实体类

 *

 * @author Administrator

 *

 */

@Entity

public class Person {



         @Id

         @GeneratedValue(strategy = GenerationType.IDENTITY)

         private Long id;

         @Column(length = 16, nullable = false)

         private String name;

         @OneToOne(optional = false, cascade = CascadeType.ALL)

         @JoinColumn(name = "idcard_id")

         private IDCard idCard;



         public Long getId() {

                   return id;

         }



         public void setId(Long id) {

                   this.id = id;

         }



         public String getName() {

                   return name;

         }



         public void setName(String name) {

                   this.name = name;

         }



         public IDCard getIdCard() {

                   return idCard;

         }



         public void setIdCard(IDCard idCard) {

                   this.idCard = idCard;

         }



}

身份证实体类

/**

 * 身份证实体类

 *

 * @author Administrator

 *

 */

@Entity

public class IDCard {

         @Id

         @GeneratedValue(strategy = GenerationType.IDENTITY)

         private Long id;

         @Column(length = 18, nullable = false)

         private String idNumber;

         @OneToOne(mappedBy = "idCard", cascade = { CascadeType.PERSIST, CascadeType.MERGE,

                            CascadeType.REFRESH }, optional = false)

         private Person person;



         public Long getId() {

                   return id;

         }



         public void setId(Long id) {

                   this.id = id;

         }



         public String getIdNumber() {

                   return idNumber;

         }



         public void setIdNumber(String idNumber) {

                   this.idNumber = idNumber;

         }



         public Person getPerson() {

                   return person;

         }



         public void setPerson(Person person) {

                   this.person = person;

         }



}

注意,作为被维护端的实体中,optional = false,可以省略,因为维护端已经设置了外键。

测试

/**

 * 测试一对一双向关联

 * @author Administrator

 *

 */

public class One2OneTest {



         @Test

         public void save() {

                   // 准备数据

                   Person person = new Person();

                   person.setName("张思");

                   IDCard idCard = new IDCard();

                   idCard.setPerson(person);

                   String idnumber = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

                   idCard.setIdNumber(idnumber);

                   person.setIdCard(idCard);

                   // 获取工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaone2one");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 保存人

                   manager.persist(person);

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



}

六、多对多双向关联

被维护端的设置:

级联设置,根据业务要求,慎重设置级联删除。

使用mappedBy,设置被维护端。

加载,对端默认是懒加载,可以不设置。

维护端设置:

级联设置,根据需要,慎重级联删除。

设置中间表,比如,@JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"), joinColumns = @JoinColumn(name = "student_id"))

关系维护端可以操作外键,关系被维护端没有权力修改外键。

学生和老师的多对多案例

学生实体类

/**

 * 学生实体类

 *

 * @author Administrator

 *

 */

@Entity

public class Student {



         @Id

         @GeneratedValue(strategy = GenerationType.IDENTITY)

         private Integer id;

         @Column(length = 16, nullable = false)

         private String name;

         @ManyToMany(cascade = CascadeType.REFRESH)

         @JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"), joinColumns = @JoinColumn(name = "student_id"))

         private Set<Teacher> teachers = new HashSet<Teacher>();



         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<Teacher> getTeachers() {

                   return teachers;

         }



         public void setTeachers(Set<Teacher> teachers) {

                   this.teachers = teachers;

         }



         /**

          * 添加教师

          */

         public void addTeacher(Teacher teacher) {

                   this.teachers.add(teacher);

         }



         /**

          * 删除教师

          */

         public void removeTeacher(Teacher teacher) {

                   if (this.teachers.contains(teacher)) {

                            this.teachers.remove(teacher);

                   }

         }



}

教师实体类

/**

 * 教师实体类

 *

 * @author Administrator

 *

 */

@Entity

public class Teacher {



         @Id

         @GeneratedValue(strategy = GenerationType.IDENTITY)

         private Integer id;

         @Column(length = 16, nullable = false)

         private String name;

         @ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers")

         private Set<Student> students = new HashSet<Student>();



         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<Student> getStudents() {

                   return students;

         }



         public void setStudents(Set<Student> students) {

                   this.students = students;

         }



         /**

          * 重写hashCode和equals方法

          */

         @Override

         public int hashCode() {

                   final int prime = 31;

                   int result = 1;

                   result = prime * result + ((id == null) ? 0 : id.hashCode());

                   return result;

         }



         @Override

         public boolean equals(Object obj) {

                   if (this == obj)

                            return true;

                   if (obj == null)

                            return false;

                   if (getClass() != obj.getClass())

                            return false;

                   Teacher other = (Teacher) obj;

                   if (id == null) {

                            if (other.id != null)

                                     return false;

                   } else if (!id.equals(other.id))

                            return false;

                   return true;

         }



}

测试

/**

 * 多对多关联测试

 *

 * @author Administrator

 *

 */

public class Many2ManyTest {



         /**

          * 添加学生和老师

          */

         @Test

         public void save() {

                   // 获取工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpamany2many");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 准备数据

                   Teacher teacher1 = new Teacher();

                   teacher1.setName("张师");

                   Teacher teacher2 = new Teacher();

                   teacher2.setName("李师");

                   Teacher teacher3 = new Teacher();

                   teacher3.setName("王师");

                   Student student1 = new Student();

                   student1.setName("刘雪");

                   Student student2 = new Student();

                   student2.setName("孙雪");

                   manager.persist(teacher1);

                   manager.persist(teacher2);

                   manager.persist(teacher3);

                   manager.persist(student1);

                   manager.persist(student2);

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 建立学生和老师的关系

          */

         @Test

         public void setStudentAndTeacher() {

                   // 获取工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpamany2many");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 获取要建立关系的学生

                   Student student1 = manager.find(Student.class, 1);

                   Student student2 = manager.find(Student.class, 2);

                   // 获取要建立关系的老师

                   Teacher teacher1 = manager.find(Teacher.class, 1);

                   Teacher teacher2 = manager.find(Teacher.class, 2);

                   Teacher teacher3 = manager.find(Teacher.class, 3);

                   // 为学生添加老师

                   student1.addTeacher(teacher1);

                   student1.addTeacher(teacher2);

                   student2.addTeacher(teacher2);

                   student2.addTeacher(teacher3);

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 解除学生和老师的关系

          */

         @Test

         public void removeTeacherFromStudent() {

                   // 获取工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpamany2many");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 获取要建立关系的学生

                   Student student1 = manager.find(Student.class, 2);

                   // 获取要建立关系的老师

                   Teacher teacher1 = manager.find(Teacher.class, 2);

                   // 为学生解除老师

                   student1.removeTeacher(teacher1);

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 删除被维护端数据,直接删除是无法删除的,需要先解除维护端与被维护端的关系,再删除

          */

         @Test

         public void deleteTeacher() {

                   // 获取工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpamany2many");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 获取要删除的对象

                   Teacher teacher1 = manager.getReference(Teacher.class, 2);

                   // 先解除关系

                   Query query = manager.createQuery("select s from Student s");

                   List<Student> students = query.getResultList();

                   for (Student student : students) {

                            student.removeTeacher(teacher1);

                   }

                   // 删除老师的数据

                   manager.remove(teacher1);

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



         /**

          * 删除维护端数据,直接删除即可,不需要手动解除外键约束

          */

         @Test

         public void deleteStudent() {

                   // 获取工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpamany2many");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 获取要删除的对象

                   Student student = manager.getReference(Student.class, 2);

                   // 删除学生的数据

                   manager.remove(student);

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }

}

七、联合主键

也称复合主键,有的事物,需要通过两个字段来作为主键,比如飞机航线,需要一个发出地和目的地作为主键确定一条航线;一场球赛,需要两个队伍作为主键,确定这场比赛。

需要定义一个复合主键类,要求是:1,有无参构造方法;2,重写hashCode和equals方法;3,继承Serializable接口。类上添加注解@Embeddable,表示可以嵌入到另一个类中。

在使用复合主键的实体类中,将复合主键属性添加注解@EmbeddedId

飞机航线的案例

复合主键类

/**

 * 复合主键类

 *

 * @author Administrator

 *

 */

@Embeddable

public class AirlinePK implements Serializable {



         @Column(length = 3)

         private String originalCity;

         @Column(length = 3)

         private String destCity;



         public AirlinePK() {

         }



         public String getOriginalCity() {

                   return originalCity;

         }



         public void setOriginalCity(String originalCity) {

                   this.originalCity = originalCity;

         }



         public String getDestCity() {

                   return destCity;

         }



         public void setDestCity(String destCity) {

                   this.destCity = destCity;

         }



         @Override

         public int hashCode() {

                   final int prime = 31;

                   int result = 1;

                   result = prime * result + ((destCity == null) ? 0 : destCity.hashCode());

                   result = prime * result + ((originalCity == null) ? 0 : originalCity.hashCode());

                   return result;

         }



         @Override

         public boolean equals(Object obj) {

                   if (this == obj)

                            return true;

                   if (obj == null)

                            return false;

                   if (getClass() != obj.getClass())

                            return false;

                   AirlinePK other = (AirlinePK) obj;

                   if (destCity == null) {

                            if (other.destCity != null)

                                     return false;

                   } else if (!destCity.equals(other.destCity))

                            return false;

                   if (originalCity == null) {

                            if (other.originalCity != null)

                                     return false;

                   } else if (!originalCity.equals(other.originalCity))

                            return false;

                   return true;

         }



}

航线实体类

/**

 * 航线类

 *

 * @author Administrator

 *

 */

@Entity

public class Airline {



         @EmbeddedId

         private AirlinePK id;

         @Column(length = 32)

         private String name;



         public AirlinePK getId() {

                   return id;

         }



         public void setId(AirlinePK id) {

                   this.id = id;

         }



         public String getName() {

                   return name;

         }



         public void setName(String name) {

                   this.name = name;

         }



}

测试

/**

 * 测试复合主键类的使用

 *

 * @author Administrator

 *

 */

public class CompositePKTest {



         @Test

         public void test() {

                   // 获取工厂

                   EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpacompositepk");

                   // 获取管理类

                   EntityManager manager = emf.createEntityManager();

                   // 开启事务

                   manager.getTransaction().begin();

                   // 准备数据

                   AirlinePK aPk = new AirlinePK();

                   aPk.setOriginalCity("pek");

                   aPk.setDestCity("sha");

                   Airline airline = new Airline();

                   airline.setId(aPk);

                   airline.setName("北京-上海");

                   manager.persist(airline);

                   // 提交事务

                   manager.getTransaction().commit();

                   // 关闭管理类

                   manager.close();

                   // 关闭工厂

                   emf.close();

         }



}

 

 

相关文章:

  • LintCode(22)将一个嵌套集合按照原顺序处理为Integer集合
  • [one_demo_16]直接插入排序的demo
  • [one_demo_17]使用传统方式实现线程间通信的例子
  • ThreadLocal
  • [one_demo_18]js定时器的示例
  • Java8部分新特性
  • jvm简介
  • mybatis使用foreach处理List中的Map
  • log4j2的配置文件
  • 一个用java的NIO实现的socket的客户端和服务端的demo
  • 使用java的nio的pipe实现两个线程间传送数据的demo
  • org.hibernate.TransactionException: nested transactions not supported异常
  • elasticsearch
  • rancher简介
  • InfluxDB+cAdvisor+Grafana容器管理
  • angular组件开发
  • ECS应用管理最佳实践
  • java8 Stream Pipelines 浅析
  • JavaScript HTML DOM
  • Kibana配置logstash,报表一体化
  • Koa2 之文件上传下载
  • leetcode46 Permutation 排列组合
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • PAT A1017 优先队列
  • PHP 小技巧
  • Sublime text 3 3103 注册码
  • Zepto.js源码学习之二
  • 仿天猫超市收藏抛物线动画工具库
  • 复杂数据处理
  • 前端技术周刊 2019-02-11 Serverless
  • 如何进阶一名有竞争力的程序员?
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 微信小程序设置上一页数据
  • 优秀架构师必须掌握的架构思维
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #stm32整理(一)flash读写
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (6)添加vue-cookie
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (六)软件测试分工
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • ??javascript里的变量问题
  • [1159]adb判断手机屏幕状态并点亮屏幕
  • [ccc3.0][数字钥匙] UWB配置和使用(二)
  • [HDU]2161Primes
  • [HTML]Web前端开发技术29(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • [iOS]-NSTimer与循环引用的理解