hibernate持久化对象解析2(一对多)

问题?Hibernate持久化对象的解析2

 hibernate的总结:

一、hibernate的组成部分
    持久化类
      实现对应的序列化接口

如:public class Classes implements Serializable(这就是序列化接口)

   案例:

一那方的持久化类:

package cn.itcast.hibernate.domain;

import java.io.Serializable;
import java.util.Set;

public class Classes implements Serializable {
	private Long cid;
	private String cname;
	private String description;
	private Set<Student> student;
	
	public Long getCid() {
		return cid;
	}
	public void setCid(Long cid) {
		this.cid = cid;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	
}

多那方的持久化类:

package cn.itcast.hibernate.domain;

import java.io.Serializable;

public class Student implements Serializable {
	private Long sid;
	private String sname;
	private String description;
	
	public Long getSid() {
		return sid;
	}
	public void setSid(Long sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	
}


必须有默认的构造函数(默认情况下是不用写的,因默认有,但是如果写了带参数的构造函数,就需要些一个默认的构造函数了。它的主要作用是在进行事务提交的时候,将数据存储然后提交到数据库。)
      持久化类的属性不能使用关键字
      标示符
二、 映射文件写法是:(持久化类名.hbm.xml)
         属性类型:type一般使用Java类型,当然hibernate类型效率高一点儿。查看下载的hibernate文档/hibernate-release-5.0.2.Final/documentation/mappingGuide/en-US/html/index.html
       
        主键的产生器(id标签)

<span style="white-space:pre">		</span><id name="cid" length="5" type="java.lang.Long">
			<generator class="increment"></generator>
		</id>
        类型有:increment 、identity 、 assigned(orical中用) 、uuid
    id :描述主属性 

   prototype:描述一般属性
    set:set元素对应类中的set集合
    通过set元素使classes表与student表建立关联

 cascade  对象与对象之间的关系(set的属性)
            inverse  对象与外键之间的关系(set的属性)


   key是通过外键的形式让两张表建立关联
    one-to-many是通过类的形式让两个类建立关联

inverse  维护关系(classes是否维护student之间的关系,inverse在哪个映射文件,就是誰维护。如果为tru e,进行级联操作的时候就不会同时更新外键了)
  true      不维护关系     
  false     维护关系
  default   false(默认维护,一般情况下我们采用级联操作的时候,就出现外键也添加了,就是因为这
   个原因。 不过既然进行级联操作,也就意味着我们是需要两个有关系的。所以,我们选择默认值)

		<set name="student" cascade="save-update" >
			<!-- 
				key是用来描述外键
			 -->
			<key column="cid"></key>
			<one-to-many class="cn.itcast.hibernate.domain.Student"/>
		</set>

案例:一那方的映射文件

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="cn.itcast.hibernate.domain.Classes">
		<id name="cid" length="5" type="java.lang.Long">
			<generator class="increment"></generator>
		</id>
		<property name="cname" length="20" type="java.lang.String"></property>
		
		<property name="description" length="100" type="java.lang.String"></property>
		<!-- 
			set元素对应类中的set集合
			通过set元素使classes表与student表建立关联
			   key是通过外键的形式让两张表建立关联
			   one-to-many是通过类的形式让两个类建立关联
			
			cascade 进行级联操作
			   save-update
			   	1、当 保存班级的时候,对学生进行怎么样的操作
			   	     如果学生对象在数据库中没有对应的值,这个时候会执行save操作
			   	     如果学生对象在数据库中有对应的值,这个时候会执行update操作
			   delete   在删除一这个对象时,随便删掉多里面的外键
			   all		在删除一时删除多中的外键,再进行更新一的时候更新多中的外键
			inverse  维护关系(classes是否维护student之间的关系,
					inverse在哪个映射文件,就是誰维护。如果为true,进行级联操作的时候就不会同时更新外键了)
			   true      不维护关系     
			   false     维护关系
			   default   false(默认维护,一般情况下我们采用级联操作的时候
			 				  ,就出现外键也添加了,就是因为这个原因。
			 				  不过既然进行级联操作,也就意味着我们是需要两个有关系的。所以,我们选择默认值)
			-->
		<set name="student" cascade="save-update" >
			<!-- 
				key是用来描述外键
			 -->
			<key column="cid"></key>
			<one-to-many class="cn.itcast.hibernate.domain.Student"/>
		</set>
	</class>
</hibernate-mapping>

多的那方的映射文件

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="cn.itcast.hibernate.domain.Student">
		<id name="sid">
			<generator class="increment"></generator>
		</id>
		<property name="sname" length="20"></property>
		<property name="description" length="100"></property>
	</class>
</hibernate-mapping>
这个文件中没有描述类型,是因为Java有默认的类型String类型,而sid有由另外一个持久化类决定了。


三、配置文件(格式:hibernate.cfg.xml  注:一个hibernate项目里就只有这一个配置文件)
          1: 数据库的链接信息
          2:存放了映射文件的信息
          3:其他信息:hibernate内部功能的信息
          如:<property name="show_sql">true</property>

<property name="hbm2ddl.auto">update</property>

配置文件的案例:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<!-- 
		一个session-factory只能连接一个数据库,一般我们也只写一个。
	-->
<session-factory>
	<!-- 
		数据库的用户名
	-->
	<property name="connection.username">root</property>
	<!-- 
		数据库的密码
	-->
	<property name="connection.password">root</property>
	<!-- 
		数据库的url:itcast_sh_hibernate是你用的数据库
	-->
	<property name="connection.url">
		jdbc:mysql://localhost:3306/itcast_sh_hibernate
	</property>
	<!-- @hbm2ddl.auto
		作用:根据持久化类和映射文件生成表
		validate:验证持久化类在映射文件中描述正不正确,只验证
		create-drop:hibernate容器开启的时候生成表,关闭的时候删除表(不用)
		create:hibernate容器开启的时候生成表(不用)
		update:表示hibernate开启的时候,先检查持久化类和映射问件和表到底对应不对应,
		不对应的话,我新建一个表。对应的话,验证描述正不正确(validate)
	-->
	<property name="hbm2ddl.auto">update</property>

	<!-- 
		显示hibernate内部生成的sql语句
	-->
	<property name="show_sql">true</property>

	<!--@mapping resource
		表示和映射文件相对应
	-->
	<mapping resource="cn/itcast/hibernate/domain/Classes.hbm.xml" />
	<mapping resource="cn/itcast/hibernate/domain/Student.hbm.xml" />

</session-factory>
</hibernate-configuration>


三、hibernate的流程
    Configuraction:加载了配置文件
    SessionFactory:建立sessionFactory连接池
                    配置文件的信息、映射文件的信息、持久化类的信息

<span style="white-space:pre">		</span>Configuration configuration=new Configuration();
		configuration.configure();
		SessionFactory sessionfactory=configuration.buildSessionFactory();
不过这个我们一般都写成工具类,然后在其他要用的地方,继承就可以了。

如:

package cn.itcast.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	public static SessionFactory sessionfactory;
	static{
		Configuration configuration=new Configuration();
		configuration.configure();
		sessionfactory=configuration.buildSessionFactory();
	}
}
    Session
        1、crud的操作都是由session完成的
        2、事务是由session开启的
        3、两个不同的session只能用各自的事务
        4、session决定了对象的状态
        5、 创建完一个session,相当于打开了一个数据库的链接
    Transaction
        1、事务默认不是自动提交的,一般是手动提交的(在单独的hibernate中)。
        2、必须由session开启,开始事物session.beginStransaction
        3、必须和当前的session绑定( 两个session不可能共用一个事务)

package cn.itcast.hibernate.test;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.hibernate.util.HibernateUtil;

public class UpdateClass extends HibernateUtil {
	@Test
	public void testSaveClasses(){
		Session session=sessionfactory.openSession();
		Transaction transaction=session.beginTransaction();
		//进行crud操作
		transaction.commit();
		session.close();
	}
	
}


3、对象的状态的转化

         
4、hibernate的原理:
      根据客户端的crud代码,参照映射文件,生成sql语句,利用jdbc技术进行数据库的操作


五、根据以上的持久化类和映射文件及配置文件、工具类,写一个测试一对多的案例:

package cn.itcast.hibernate.test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.hibernate.domain.Classes;
import cn.itcast.hibernate.domain.Student;
import cn.itcast.hibernate.util.HibernateUtil;

/**
 * 1、新建一个班级
 * 1、新建一个班级
 * 3、新建一个班级的时候同时新建一个学生
 * 4、已经存在一个班级,新建一个学生,建立学生与班级之间的关系
 * 5、已经存在一个学生,新建一个班级,把学生加入到该班级
 * 6、把一个学生从一个班级转移到另一个班级
 * 7、解析一个班级和一个学生之间的关系
 * 8、解除一个班级和一些学生之间的关系
 * 9、解除该班级和所有的学生之间的关系
 * 10、已经存在一个班级,已经存在一个学生,建立该班级与该学生之间的关系
 * 11、已经存在一个班级,已经存在多个学生,建立多个学生与班级之间的关系
 * 12、删除学生
 * 13、删除班级
 *     删除班级的时候同时删除学生
 *     在删除班级之前,解除班级和学生之间的关系
 * @author Think
 *
 */
public class OneToManySingleTest extends HibernateUtil {
	@Test
	public void testSaveClasses(){
		// 1、新建一个班级
		Session session=sessionfactory.openSession();
		Transaction transaction=session.beginTransaction();
		Classes classes=new Classes();
		classes.setCname("Mr_Li13");
		classes.setDescription("牛逼异火!");
		session.save(classes);
		transaction.commit();
		session.close();
	}
	
	@Test
	public void testSaveStudent(){
		// 1、新建一个班级
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Student student = new Student();
		student.setSname("班长");
		student.setDescription("老牛:很牛");
		session.save(student);
		transaction.commit();
		session.close();
	}
	
	@Test
	public void testSaveClasses_Student(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Classes classes = new Classes();
		classes.setCname("传智上海云二期:");
		classes.setDescription("很牛X");
		
		Student student = new Student();
		student.setSname("班长");
		student.setDescription("老牛:很牛X");
		
		session.save(student);
		session.save(classes);
		transaction.commit();
		session.close();
	}
	

	/**
	 * 在保存班级的时候,级联保存学生
	 * 保存效果跟上面一个一样的
	 */
	@Test
	public void testSaveClasses_Cascade_Student_Save(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Classes classes = new Classes();
		classes.setCname("传智上海云三期:");
		classes.setDescription("很牛XX");
		
		Student student = new Student();
		student.setSname("班长");
		student.setDescription("老牛:很牛XX");
		
		Set<Student> students = new HashSet<Student>();
		students.add(student);
		
		//建立classes与student之间的关联
		classes.setStudent(students);
		session.save(classes);//级联操作就只需要save一次
		transaction.commit();
		session.close();
	}
	
	@Test
	public void testSaveClasses_Cascade_Student_Update(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Classes classes = new Classes();
		classes.setCname("传智上海云四期:");
		classes.setDescription("很牛XX");
		
		Student student=(Student)session.get(Student.class, 1L);
		student.setSname("班长叔叔!");//进行快照对比
		
		Set<Student> students = new HashSet<Student>();
		students.add(student);
		
		//建立classes与student之间的关联
		classes.setStudent(students);
		session.save(classes);//级联操作就只需要save一次
		transaction.commit();
		session.close();
	}
	/**
	 * 已经存在一个班级,新建一个学生,建立学生与班级之间的关系
	 *    通过更新班级级联保存学生  cascade
	 *    建立班级和学生之间的关系  inverse
	 */
	@Test
	public void testSaveStudent_R_1(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Student student = new Student();
		student.setSname("技术班长");
		student.setDescription("大神");
		Classes classes = (Classes)session.get(Classes.class, 1L);
		classes.getStudent().add(student);//invers就是在这里起作用
		transaction.commit();//发现没,都是处于持久化状态
		session.close();
	}
	
	@Test
	public void testSaveStudent_R_2(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Student student = new Student();
		student.setSname("技术班长");
		student.setDescription("大神11112");
		Classes classes = (Classes)session.get(Classes.class, 1L);
		
		//session.save(student);//单执行这一步就没有级联操作了
		
		classes.getStudent().add(student);
		
		transaction.commit();
		session.close();
	}
	
	@Test
	public void testUpdateClasses_Cascade_Student_Save(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes = (Classes)session.get(Classes.class, 4L);
		Student student = new Student();
		student.setSname("班花");
		student.setDescription("稀有人物");
		classes.getStudent().add(student);//invers就是在这里起作用
		transaction.commit();//发现没,都是处于持久化状态
		session.close();
	}
	
	//5、已经存在一个学生,新建一个班级,把学生加入到该班级
	@Test
	public void testSaveClasses_R(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Classes classes = new Classes();
		classes.setCname("老毕基础加强班");
		classes.setDescription("必看,杀手锏");
		Student student=(Student)session.get(Student.class,2L);
		Set<Student> students=new HashSet<Student>();
		students.add(student);
		
		classes.setStudent(students);
		session.save(classes);
		
		transaction.commit();
		session.close();
	}
	 //* 6、把一个学生从一个班级转移到另一个班级(重点)
	@Test
	public void testTransformClass(){
//		Session session = sessionfactory.openSession();
//		Transaction transaction = session.beginTransaction();
//		Classes classes1 = (Classes)session.get(Classes.class, 1L);
//		Classes classes3 = (Classes)session.get(Classes.class, 3L);
//		Student student = (Student)session.get(Student.class, 6L);
//		classes1.getStudent().remove(student);
//		classes3.getStudent().add(student);
//		transaction.commit();
//		session.close();
		
		//在这个例子,中我么可以看见,太高繁琐,虽然逻辑正确。它是先解除关系,再添加关系
		
		//另外一个更加简单的例子
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes3 = (Classes)session.get(Classes.class, 5L);
		Student student = (Student)session.get(Student.class, 2L);
		classes3.getStudent().remove(student);
		transaction.commit();
		session.close();
	}
	
	 //* 7、解析一个班级和一个学生之间的关系
	@Test
	public void testTransformClass_remove_Student(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes6 = (Classes)session.get(Classes.class, 5L);
		Student student = (Student)session.get(Student.class, 2L);
		classes6.getStudent().remove(student);
		transaction.commit();
		session.close();
	}
	 //* 8、解除一个班级和一些学生之间的关系

	@Test
	public void testR_Some(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes = (Classes)session.get(Classes.class, 3L);
		Set<Student> students = classes.getStudent();
//		for(Student student:students){
//			if(student.getSid().longValue()==6||student.getSid().longValue()==7){
//				students.remove(student);
//			}
//		}
		//set-->list这个种方式是不行的,请了解set的缺陷
		
		List<Student> sList = new ArrayList<Student>(students);
		for(int i=0;i<sList.size();i++){
			if(sList.get(i).getSid().longValue()==6||sList.get(i).getSid().longValue()==7){
				sList.remove(sList.get(i));
				i--;
			}
		}
		
		students = new HashSet<Student>(sList);
		classes.setStudent(students);
		/**
		 * 增强for循环只能修改一次
		 *   1、用普通的for循环
		 *   2、新建一个set集合,把原来的set集合要保留的数据存放到新的set集合中
		 */
		transaction.commit();
		session.close();
	}
	 //* 9、解除一个班级和所有的学生之间的关系
	@Test
	public void testRealseAll(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes = (Classes)session.get(Classes.class, 1L);
//		Set<Student> students = classes.getStudents();
//		students.clear();
		classes.setStudent(null);//这个效率更高
		transaction.commit();
		session.close();
	}
	 //* 10、已经存在一个班级,已经存在一个学生,建立该班级与该学生之间的关系
	 //* 11、已经存在一个班级,已经存在多个学生,建立多个学生与班级之间的关系
	 //* 12、删除学生
	@Test
	public void testDeleteStudent(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Student student = (Student)session.get(Student.class,4L);
		session.delete(student);
		transaction.commit();
		session.close();
	}
	 //* 13、删除班级
	 //*     删除班级的时候同时删除学生
	@Test
	public void testDeleteClasses(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes = (Classes)session.get(Classes.class, 5L);
		session.delete(classes);
		//因为有invars这个属性,再删除班级的同时,也将学生表中的也删除掉了
		transaction.commit();
		session.close();
	}
	 //*     在删除班级之前,解除班级和学生之间的关系
	@Test
	public void testDeleteClasses_Cascade(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Classes classes = (Classes)session.get(Classes.class,4L);
		//classes.setStudents(null);
		session.delete(classes);
		transaction.commit();
		session.close();
	}	
}


三、一对多的双向操作:

想对上面案例的student持久化类和映射文件稍微改一下。

如:

package cn.itcast.hibernate.domain;

import java.io.Serializable;

public class Student implements Serializable {
	private Long sid;
	private String sname;
	private String description;
	private Classes classes;//多了一个类对象
	
	public Classes getClasses() {
		return classes;
	}
	public void setClasses(Classes classes) {
		this.classes = classes;
	}
	public Long getSid() {
		return sid;
	}
	public void setSid(Long sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	
}


<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
	<class name="cn.itcast.hibernate.domain.Student">
		<id name="sid">
			<generator class="increment"></generator>
		</id>
		<property name="sname" length="20"></property>
		<property name="description" length="100"></property>
		<!-- 
			多对一
			  column 外键
		 -->
		 <!--加的这个外键只是相对以前的一对多单项操作上,能够从多的放心来操作一,从而实现了双向操作。 通过外键来访问一 -->
		<many-to-one name="classes" class="cn.itcast.hibernate.domain.Classes" column="cid" cascade="save-update"></many-to-one>
	</class>
</hibernate-mapping>

测试类:

package cn.itcast.hibernate.test;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.hibernate.domain.Classes;
import cn.itcast.hibernate.domain.Student;
import cn.itcast.hibernate.util.HibernateUtil;

/**
 * 3、新建一个班级的时候同时新建一个学生
 * 4、已经存在一个班级,新建一个学生,建立学生与班级之间的关系
 * 5、已经存在一个学生,新建一个班级,把学生加入到该班级
 * 6、把一个学生从一个班级转移到另一个班级
 * 7、解析一个班级和一个学生之间的关系
 * 8、解除一个班级和一些学生之间的关系
 * 9、解除该班级和所有的学生之间的关系
 * 10、已经存在一个班级,已经存在一个学生,建立该班级与该学生之间的关系
 * 11、已经存在一个班级,已经存在多个学生,建立多个学生与班级之间的关系
 * 12、删除学生
 * 13、删除班级
 *     删除班级的时候同时删除学生
 *     在删除班级之前,解除班级和学生之间的关系
 * @author Think
 *
 */
public class ManyToOneTest extends HibernateUtil {
	@Test
	public void testSaveStudent_Cascade_Classes_Save(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Student student = new Student();
		student.setSname("班秘");
		student.setDescription("很神秘的一个工作");
		
		Classes classes = new Classes();
		classes.setCname("老毕亲子班");
		classes.setDescription("都是老毕的亲戚");
		
		student.setClasses(classes);
//		Set<Student> students = new HashSet<Student>();
//		students.add(student);
//		
//		classes.setStudents(students);
		session.save(student);
		
		transaction.commit();
		session.close();
	}
	
	
	/**
	 * 一对多,从多的一端维护关系效率比较高
	 */
	@Test
	public void testSaveStudent_R(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Student student = new Student();
		student.setSname("潘金莲");
		student.setDescription("很好");
		
		Classes classes = (Classes)session.get(Classes.class, 2L);
		student.setClasses(classes);
		
//		Set<Student> students = new HashSet<Student>();
//		students.add(student);
//		
//		classes.getStudent().add(student);//在hibernate内部查看的是classes.hbm.xml
//		
		session.save(student);//在hibernate内部查看的是Student.hbm.xml
		transaction.commit();
		session.close();
	}
	
	
	//解除student端与class的关系
	//从这里我们就可以看出一对多的双向优势了。又多的一方,维护效率高,不用经过update了。
	@Test
	public void testRelese_R(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
//		Classes classes = (Classes)session.get(Classes.class,5L);
		Student student11 = (Student)session.get(Student.class, 11L);
		student11.setClasses(null);
		transaction.commit();
		session.close();
	}	
}

一对多的双向操作总结:

1、如果让一的一方维护关系,取决于的因素有
    1、在一的一方的映射文件中,set元素的inverse属性为default/false(这个我们一般为了更好的维护一对多的操作,选择默认。)
    2、在客户端的代码中,通过一的一方建立关系
    3、session.save/update方法是用来操作表的,和操作关系没有关系


2、怎么样采用级联的方法通过保存一个对象从而保存关联对象
    1、如果session.save操作的对象是A,这个时候应该看A.hbm.xml,看set元素中cascade是否设置有级联保存
    2、在客户端通过A建立关联
    3、在客户端执行session.save(A)


3、一对多的情况,多的一方维护关系效率比较高
    1、在多的一方many-to-one中没有inverse属性
    2、在客户端通过多的一方建立关联


其实:在操作的过程中hibernate做的不是很好,比如在sql语句方面,虽然我们利用的简便的方法在进行操作。但是在一些方面不是很好。比如更新一列值?


注:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值