JPA一对多的双向关联

按照上一节的数据库设计 :   mysql设计外键关联

在Eclipse中创建工程名为(OneToMany)的JPA Project,创建的时候需要导入EclipseLink包。

配置persistence.xm文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 	  
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
	http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="OneToMany" transaction-type="RESOURCE_LOCAL">
		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
		<class>model.Teacher</class>
		<class>model.User</class>
		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/tzx"/>
			<property name="javax.persistence.jdbc.user" value="root"/> 
			<property name="javax.persistence.jdbc.password" value="123456"/>
		</properties>
	</persistence-unit>
</persistence>

其中OneToMany为工程名,model为包名。

User.java

package model;

import java.io.Serializable;

import javax.persistence.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 * The persistent class for the user database table.
 * 
 */
@Entity
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	private String id;

	private String pass;

	//bi-directional many-to-one association to Teacher
	@OneToMany(cascade = CascadeType.ALL,mappedBy="user" )//指向多的那方的pojo的关联外键字段    
	private Collection<Teacher> teachers = new ArrayList<Teacher>();

	public User() {
	}

	public String getId() {
		return this.id;
	}

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

	public String getPass() {
		return this.pass;
	}

	public void setPass(String pass) {
		this.pass = pass;
	}

	public Collection<Teacher> getTeachers() {
		return this.teachers;
	}

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

	public Teacher addTeacher(Teacher teacher) {
		getTeachers().add(teacher);
		teacher.setUser(this);

		return teacher;
	}

	public Teacher removeTeacher(Teacher teacher) {
		getTeachers().remove(teacher);
		teacher.setUser(null);

		return teacher;
	}

}

Teacher.java

package model;

import java.io.Serializable;
import javax.persistence.*;


/**
 * The persistent class for the teacher database table.
 * 
 */
@Entity
@NamedQuery(name="Teacher.findAll", query="SELECT t FROM Teacher t")
public class Teacher implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	private String name;

	private String gender;

	//bi-directional many-to-one association to User
	@JoinColumn(name = "user_id")//设置对应数据表的列名和引用的数据表的列名    
	@ManyToOne(cascade=CascadeType.ALL)
	private User user;

	public Teacher() {
	}

	public String getName() {
		return this.name;
	}

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

	public String getGender() {
		return this.gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public User getUser() {
		return this.user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}

TestDAO.java封装数据操作

package simple;

import java.util.List;

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

import model.Teacher;
import model.User;

public class TestDAO {
	private static final String PERSISTENCE_UNIT_NAME = "OneToMany";
	private static EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
	EntityManager en = factory.createEntityManager();
	public TestDAO(){
		
	}
	//增减信息
	public void addUser(User user){
		en.getTransaction().begin();
		en.persist(user);
		en.getTransaction().commit();
	}
	public void addTeacher(Teacher teacher){
		en.getTransaction().begin();
		en.persist(teacher);
		en.getTransaction().commit();
	}
	//删除信息
	public void removeUser(User user){
		en.getTransaction().begin();
		en.remove(user);
		en.getTransaction().commit();
	}
	public void removeTeacher(Teacher teacher){
		en.getTransaction().begin();
		en.remove(teacher);
		en.getTransaction().commit();
	}
	public void deleteUser(){
		en.getTransaction().begin();
		String deleteQL="delete from User";
		Query deleteQuery=en.createQuery(deleteQL);
		deleteQuery.executeUpdate();
		en.getTransaction().commit();
	}
	public void deleteTeacher(){
		en.getTransaction().begin();
		String deleteQL="delete from Teacher";
		Query deleteQuery=en.createQuery(deleteQL);
		deleteQuery.executeUpdate();
		en.getTransaction().commit();
	}
	//更新信息
	public void updateUser(User user){
		en.getTransaction().begin();
		String sql = "update User u set u.pass='" + user.getPass() + "' where u.id='" + user.getId() + "'";
		en.createQuery(sql).executeUpdate();
		en.refresh(user);
		en.getTransaction().commit();
	}
	public void updateTeacher(Teacher teacher){
		en.getTransaction().begin();
		en.refresh(teacher);
		en.getTransaction().commit();
	}
	//查询信息
	public List<User> getAllUsers(){
		en.getTransaction().begin();
		List<User> userList = en.createQuery("SELECT u FROM User u").getResultList();
		en.getTransaction().commit();
		return userList;
	}
	public List<Teacher> getAllTeachers(){
		en.getTransaction().begin();
		List<Teacher> teacherList = en.createQuery("SELECT t FROM Teacher t").getResultList();
		en.getTransaction().commit();
		return teacherList;
	}	
	public List<User> getUsers(String sql){
		en.getTransaction().begin();
		List<User> userList = en.createQuery(sql).getResultList();
		en.getTransaction().commit();
		return userList;
	}
}

TestJDBC.java

package simple;

import java.util.Iterator;
import java.util.List;

import model.Teacher;
import model.User;

public class TestJDBC {
	public static void showUserList(List<User>list){
		  System.out.println("-----用户 列表-----");
		  
		for(Iterator<User> i=list.iterator();i.hasNext();){
			User user=i.next();
			System.out.print(user.getId()+": "+user.getPass()+ ",老师有:");
			for(Iterator<Teacher> j=user.getTeachers().iterator();j.hasNext();){
				Teacher teacher = j.next();
				System.out.print(teacher.getName() + "-");
			}
			System.out.println();
		}
	}
	public static void showTeacherList(List<Teacher>list){
		  System.out.println("-----用户 列表-----");
		  
		for(Iterator<Teacher> i=list.iterator();i.hasNext();){
			Teacher teacher=i.next();
			System.out.println(teacher.getName()+": "+teacher.getGender()+ ",学生为:" + teacher.getUser().getId() + "\n");
		}
	}
	public static void showMessage(){
		TestDAO tDao = new TestDAO();
		//显示所有老师信息
		System.out.println("显示所有老师信息~!");
		showTeacherList(tDao.getAllTeachers());
		//显示所有User信息
		System.out.println("显示所有User信息~!");
		showUserList(tDao.getAllUsers());
	}
	public static void main(String[] args){
		TestDAO testDAO = new TestDAO();
		System.out.println("所有数据清理~!");
		//删除所有User和Teacher信息
		testDAO.deleteUser();
		testDAO.deleteTeacher();
		User temp1 = new User();
		temp1.setId("小明");
		temp1.setPass("111111");
		User temp2 = new User();
		temp2.setId("小六");
		temp2.setPass("222222");
		//添加user信息
		testDAO.addUser(temp1);
		testDAO.addUser(temp2);
		//显示所有User信息
		System.out.println("显示所有User信息~!");
		showUserList(testDAO.getAllUsers());
		
		Teacher tea1 = new Teacher();
		Teacher tea2 = new Teacher();
		tea1.setName("数学");
		tea1.setGender("男");
		tea2.setName("英语");
		tea2.setGender("女");
		Teacher tea3 = new Teacher();
		Teacher tea4 = new Teacher();
		tea3.setName("化学");
		tea3.setGender("男");
		tea4.setName("物理");
		tea4.setGender("女");
		//添加Teacher信息
		testDAO.addTeacher(tea1);
		testDAO.addTeacher(tea2);
		testDAO.addTeacher(tea3);
		testDAO.addTeacher(tea4);
		temp1.addTeacher(tea1);
		temp1.addTeacher(tea2);
		temp2.addTeacher(tea3);
		temp2.addTeacher(tea4);
//		testDAO.addTeacher(tea1);
//		testDAO.addTeacher(tea2);
//		testDAO.addTeacher(tea3);
//		testDAO.addTeacher(tea4);
		testDAO.addUser(temp1);
		testDAO.addUser(temp2);
		showMessage();
		//连级查询JPAL语言
		String sql = "select u from User u,in (u.teachers) t where t.name = '化学'";
		List<User> temp = testDAO.getUsers(sql);
		System.out.println("化学老师的学生为:" + temp.get(0).getId() + ":" + temp.get(0).getPass());
		//修改小六信息
		temp2.setPass("xiaoliu");
		testDAO.updateUser(temp2);
		showMessage();
		//删除小六信息
		testDAO.removeUser(temp2);
		showMessage();
	}
}

cascade = CascadeType.ALL可以解释为:

CascadeType.REFRESH:级联刷新,也就是说,当你刚开始获取到了这条记录,那么在你处理业务过程中,这条记录被另一个业务程序修改了(数据库这条记录被修改了),那么你获取的这条数据就不是最新的数据,那你就要调用实体管理器里面的refresh方法来刷新实体,所谓刷新,大家一定要记住方向,它是获取数据,相当于执行select语句的(但不能用select,select方法返回的是EntityManager缓存中的数据,不是数据库里面最新的数据),也就是重新获取数据。 

CascadeType.PERSIST:级联持久化,也就是级联保存。保存User的时候也保存Teacher,如果在数据库里已经存在与需要保存的Teacher相同的name记录,则级联保存出错。

CascadeType.MERGE:  级联更新,也可以叫级联合并;当对象User处于游离状态时,对对象User里面的属性作修改,也修改了User里面的Teacher,当要更新对象User时,是否也要把对Teacher的修改同步到数据库呢?这就是由CascadeType.MERGE来决定的,如果设了这个值,那么User处于游离状态时,会先update User,然后for循环update Teacher,如果没设CascadeType.MERGE这个值,就不会出现for循环update Teacher语句。所以说,级联更新是控制对User的更新是否会波及到Teacher对象。也就是说对User进行update操作的时候,Teacher是否也要做update操作呢?完全是由CascadeType.MERGE控制的。

CascadeType.REMOVE:当对User进行删除操作的时候,是否也要对Teacher对象进行级联删除操作呢?是的则写,不是的则不写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值