hibernateNote2 - juedaiyuer/researchNote GitHub Wiki

#hibernate笔记(二)#

##映射类型##

  1. 一对多(one to many)
  2. 多对一(many to one)
  3. 一对一(one to one)
  4. 多对多(many to many)

##一对多关联##

在数据库中,可以通过添加主外键的关联,表现一对多的关系

##MyEclipse下的开发##

###jar包###

1.手动添加jar包

  1. 建立一个lib,将jar包复制到lib下
  2. 选择lib目录下的所有jar包
  3. 鼠标右键-bulid path

2.IDE本身支持

鼠标右键-MyEclipse-Add Hibernate Capabilities

或者 project facets(capabilities)

###Hibernate主配置文件###

hibernate的解压缩包拷贝

cfg.xml (config的简写)

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
	<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password"></property>
	<property name="hibernate.connection.url">
		<![CDATA[
			jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8
		]]>
	</property>
	<property name="show_sql">true</property>
	<property name="hbm2ddl.auto">update</property>
    
    <!-- 指定映射文件的路径 -->

	<mapping resource="Grade.hbm.xml"/>
	<mapping resource="Student.hbm.xml"/>

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

###创建工具类###

package util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class hibernateUtil {
    private static SessionFactory sessionFactory;
    private static Session session;

    static
    {
	    //创建Configuration对象,读取主配置文件cfg.xml,完成初始化
	    Configuration config = new Configuration().configure();
	    //hibernate 4.x 使用的方法
	    StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(config.getProperties());
	    StandardServiceRegistry ssr = ssrb.build();
	    sessionFactory= config.buildSessionFactory(ssr);
	
    }
    //获取sessionFactory
    public static SessionFactory getSessionFactory()
    {
	    return sessionFactory;
    }

    //获取Session
    public static Session getSession()
    {
	    return sessionFactory.openSession();
    }

//关闭session
    public static void closeSession(Session session)
    {
	    if(session!=null)
	    {
		    session.close();
	    }
    }

}
  1. 获取会话的工具类

###mysql数据库中建立表###

建立一个students.sql文件

create table grade
(
    gid int primary key,
    gname varchar(20) not null,
    gdesc varchar(50)
);

create table student
(
    sid int primary key,
    sname varchar(20) not null,
    sex char(2),
    gid int
);

//外键约束

alter table student add constraint fk_student_gid foreign key (gid)
references grade(gid);

###创建持久化类###

一对多的关系,一个班级对应多名学生

学生类 package entity;

import java.io.Serializable;

public class Student implements Serializable {
    private int sid;
    private String sname;
    private String sex;

    public int getSid() {
	    return sid;
    }
    public void setSid(int sid) {
	    this.sid = sid;
    }
    public String getSname() {
	    return sname;
    }
    public void setSname(String sname) {
	    this.sname = sname;
    }
    public String getSex() {
	    return sex;
    }
    public void setSex(String sex) {
	    this.sex = sex;
    }


}

班级类

package entity;

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

public class Grade implements Serializable {
    private int gid;
    private String gname;
    private String gdesc;

    /**
		1.在一方定义一个多方的集合
	    2.使用Set集合,学生不可以重复
	*/
    private Set<Student> students = new HashSet<Student>();

    public int getGid() {
	    return gid;
    }

    public void setGid(int gid) {
	    this.gid = gid;
    }

    public String getGname() {
	    return gname;
    }

    public void setGname(String gname) {
	    this.gname = gname;
    }

    public String getGdesc() {
	    return gdesc;
    }

    public void setGdesc(String gdesc) {
	    this.gdesc = gdesc;
    }

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

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

    public Grade() {
	
    }

    public Grade(int gid, String gname, String gdesc, Set<Student> students) {
	    super();
	    this.gid = gid;
	    this.gname = gname;
	    this.gdesc = gdesc;
	    this.students = students;
    }
}

###映射文件的配置###

班级Grade映射文件

<hibernate-mapping>
    <class name="entity.Grade" table="grade">
	    <id name="gid" column="gid" type="java.lang.Integer">
		    <generator class="increment"></generator>
	    </id>
	    <property name="gname" type="java.lang.String">
		    <column name="gname" length="20" not-null="true"></column>
	    </property>
	    <property name="gdesc">
		    <column name="gdesc"></column>
	    </property>
	    <!-- 配置一对多关联关系 -->
	    <set name="students" table="student">
            <!--指定关联的外键列-->
		    <key column="gid"></key>
		    <one-to-many class="entity.Student"/>
	    </set>
    </class>
</hibernate-mapping>
  1. 班级映射文件
  2. class标签对应持久化类,table对应数据库中的数据表
  3. id标签为主键,generator对应生成策略
  4. property标签对应了其它属性

学生Student映射文件

<hibernate-mapping>
    <class name="entity.Student" table="student">
	    <id name="sid" column="sid" type="java.lang.Integer">
		    <generator class="increment"></generator>
	    </id>
	    <property name="sname" type="java.lang.String">
		    <column name="sname" length="20" not-null="true"></column>
	    </property>
	    <property name="sex">
		    <column name="sex"></column>
	    </property>
	    <!-- 配置多对一关联关系 -->
	    
    </class>
</hibernate-mapping>

###测试###

单向一对多关系(班级--->学生)

班级的构造方法(wihtout id and students)
学生的构造方法(without id )和无参构造方法

在学生表中添加相应的班级编号,需要在班级中添加学生,建立关联关系

package entity;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;

import util.hibernateUtil;

public class Test {
	public static void main(String[] args) {
		//add();
		//findStudentByGrade();
		//update();
		delete();
	}

	//将学生添加到班级
	public static void add()
	{
		Grade g = new Grade("电气一班","信息学院");
		Student stu1 = new Student("依然", "女");
		Student stu2 = new Student("牧月", "女");

		//在学生表中添加相应的班级编号,需要在班级中添加学生,建立关联关系
		g.getStudents().add(stu1);
		g.getStudents().add(stu2);

		Session session = hibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		session.save(g);
		session.save(stu1);
		session.save(stu2);
		tx.commit();
		hibernateUtil.closeSession(session);

	}

	//学生信息的查询,班级中学生信息
	//建立关联关系后,可以方便的从一个对象导航到另一个对象
	//注意关联的方向 班级--->学生

	public static void findStudentByGrade()
	{
		Session session = hibernateUtil.getSession();
		Grade grade = (Grade) session.get(Grade.class,1);
		System.out.println(grade.getGname()+","+grade.getGdesc());

		Set<Student>  students = grade.getStudents();
		for(Student stu:students)
		{
			System.out.println(stu.getSname()+","+stu.getSex());
		}

	}

	//修改学生信息
	public static void update()
	{
		Grade g = new Grade("健行一班", "健行学院");

		Session  session = hibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		Student stu = (Student)session.get(Student.class, 1);
		g.getStudents().add(stu);
		session.save(g);
		tx.commit();
		hibernateUtil.closeSession(session);
	}

	//删除学生信息
	public static void delete()
	{
		Session session = hibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		Student stu = (Student)session.get(Student.class, 1);
		session.delete(stu);
		tx.commit();
		hibernateUtil.closeSession(session);
	}
}

set属性


##单向多对一关联##

通过在多方持有一方的引用实现,需要在多的一端使用

  1. 在多方的持久化类中定义一个多方的引用,并且生成getter/setter

  2. 映射文件的配置(多方);一方配置不用更改

    package test;

    import org.hibernate.Session; import org.hibernate.Transaction;

    import util.hibernateUtil; import entity.Grade; import entity.Student;

    //测试单向多对一(学生--->班级)

    public class Test2 { public static void main(String[] args) { save(); }

     //保存
     public static void save()
     {
     	Grade g = new Grade("电气一班", "信息学院");
     	Student stu1 = new Student("王九九","女");
     	Student stu2 = new Student("林浣溪", "女");
     
     	//设置关联关系
     	stu1.setGrade(g);
     	stu2.setGrade(g);
     
     	Session session = new hibernateUtil().getSession();
     	Transaction tx = session.beginTransaction();
     	session.save(g);
     	session.save(stu1);
     	session.save(stu2);
     	tx.commit();
     	hibernateUtil.closeSession(session);
     
     }
    

    }


##双向多对一##

package test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import util.hibernateUtil;
import entity.Grade;
import entity.Student;


//测试单向多对一(学生--->班级)

public class Test2 {
	public static void main(String[] args) {
		save();
	}

	//保存
	public static void save()
	{
		Grade g = new Grade("电气一班", "信息学院");
		Student stu1 = new Student("王九九","女");
		Student stu2 = new Student("林浣溪", "女");
	
		//设置关联关系
		g.getStudents().add(stu1);
		g.getStudents().add(stu2);
		stu1.setGrade(g);
		stu2.setGrade(g);
	
		Session session = new hibernateUtil().getSession();
		Transaction tx = session.beginTransaction();
		session.save(g);
		session.save(stu1);
		session.save(stu2);
		tx.commit();
		hibernateUtil.closeSession(session);
	
	}
}

##inverse属性##

set标签 指定关联关系的控制方向,默认由one方来维护
在关联关系中,inverse="false",则为主动方,由主动方负责维护关联关系
在一对多关联中,只能设置one方的inverse为true,这将有助于性能的改善

##cascade属性##

session.save(g);
session.save(stu1);
session.save(stu2);
  1. 操作麻烦,保存班级,仍然需要进行保存学生的操作
  2. 级联操作简化

当设置了cascade属性不为none时,hibernate会自动持久化所关联的对象

cascade属性的设置会带来性能上的变动,需谨慎设置

cascade属性

##查询操作##

查询学生所在班级的信息

//查询学生所在班级信息
public static void findGradeByStudent()
{
	Session session = hibernateUtil.getSession();
	Student stu =(Student) session.get(Student.class, 2);
	System.out.println(stu.getSid()+","+stu.getSname()+","+stu.getSex());
	
	Grade g = stu.getGrade();
	System.out.println(g.getGid()+","+g.getGname()+","+g.getGdesc());
	hibernateUtil.closeSession(session);
}

##总结##

实现单向一对多

  1. 在one方的实体中添加保存many方的集合
  2. 在one方的配置文件中添加one-to-many标签

实现单向多对一

  1. 在many方的实体中添加one方的引用
  2. 在many方的配置文件中添加many-to-one标签

常用属性

  1. cascade:设置级联关系
  2. inverse:设置哪一方维护关联关系

##MyEclipse使用技巧##

使用IDE提供的支持来简化操作

###添加数据库连接视图###

MyEclipse的右上角-open perspective-MyEclipse Database Explorer

或者是

菜单栏-Window-Show View-Other 展开MyEclipse Database 选择DB Browser

myeclipse连接数据库视图方法

myeclipse添加hibernate支持方法

myeclipse配置文档和获取会话

myeclipse添加数据库连接

##反向工程##

根据数据库中的表,自动生成持久化类和映射关系文件

创建实体包entity


##资源##

  1. imooc Hibernate初探之一对多映射
  2. 代码
⚠️ **GitHub.com Fallback** ⚠️