Hibernate学习笔记4

时间:2023-03-09 19:11:17
Hibernate学习笔记4

一、关于联合主键的映射测试实例

实体类:

package com.***.comBineKey;
public class Person {
private Person_pk pk;
private long age;
public Person_pk getPk() {
return pk;
}
public void setPk(Person_pk pk) {
this.pk = pk;
}
public long getAge() {
return age;
}
public void setAge(long age) {
this.age = age;
}
}

联合主键类:

package com.***.comBineKey;
import java.io.Serializable;
/**
* 联合主键映射测试实例
* @author Victor
*
*/
public class Person_pk implements Serializable{
/**
* 实现序列化接口
* 判断两个对象是否相等【解决方法:重写equals方法,最好再重写hasCode方法加快解析速度(hasCode只比较ID)】
*/
private static final long serialVersionUID = 1L;
private long id;
private String name;
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 int hasCode(){
return (int)id;//hasCode只会和id比较
}
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(this==obj){
return true;
}
Person_pk person_pk=(Person_pk) obj;
if(!(obj instanceof Person_pk)){
return false;
}
if(this.id==person_pk.id && this.name.equals(person_pk.name)){
return true;
}
return false;
}
}

测试类:

package com.***.hibernateTest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class PersonTest {
private SessionFactory sf;
private Session session;
private Transaction tran;
@Before
public void before(){
Configuration con=new Configuration().configure();
sf=con.buildSessionFactory();
session=sf.openSession();
tran=session.beginTransaction();
}
@After
public void after(){
//把SQL语句刷到数据库,执行的是单纯的SQL语句
//把对象刷到数据库中,调用对象的get方法
//给?占位符赋值
tran.commit();
//关闭session【因为session不安全】
//也会提交事务
session.close();
}
@Test
public void AutoCreateTable() {
try {
Configuration con=new Configuration().configure("hibernate.cfg.xml");
SchemaExport create=new SchemaExport(con);
create.create(false, true);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}

配置文件:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.***.comBineKey.Person" table="pk_person">
<composite-id name="pk" class="com.***.comBineKey.Person_pk">
<key-property name="id"/>
<key-property name="name"/>
</composite-id>
<property name="age"/>
</class>
</hibernate-mapping>

二、类与类之间的关系:

  <一>、一对一单向关联

  实体类一: 

package com.briup.orm.oneToone.unidirectional;
public class Husband {
private int id;
private String name;
private Wife wife;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
@Override
public String toString() {
return "Husband [id=" + id + ", name=" + name + ", wife=" + wife + "]";
}
}

  实体类二:

package com.briup.orm.oneToone.unidirectional;
public class Wife{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Wife [id=" + id + ", name=" + name + "]";
}
}

  配置文件一:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.briup.orm.oneToone.unidirectional.Husband" table="s_husband">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<!--
name="wife" 表示当前Husband类中的一个名字为wife的属性做关系映射
class="..Wife" 名字为wife的属性类型是..Wife
column=wife_id 将来在Husband类所对应的表中生成一个外键列为wife_id
unique="true" 本来<many-to-one>标签指的是多对一的关系,但是设置unique="true".就是给外键列上面加上一个唯一约束,这个时候多对一的关系就变成一对一的关系
cascade="all"设置级联操作save-update delete all all-delete-orphan
lazy="proxy" 设置延迟加载false:不延迟 proxy延迟
fetch="join" 设置延迟时抓取级联操作对象的策略
join:使用连接查询的方式
这种情况下不能设置延迟加载(因为就一条sql语句)
-->
<many-to-one name="wife" class="com.briup.orm.oneToone.unidirectional.Wife" column="wife_id" unique="true" cascade="save-update" lazy="false" fetch="join"/>
</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="com.briup.orm.oneToone.unidirectional.Wife" table="s_wife">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

  测试类:

package com.briup.orm.oneToone.oneTooneTest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.briup.orm.oneToone.unidirectional.Husband;
import com.briup.orm.oneToone.unidirectional.Wife;
/**
* 类与类之间的关系:一对一单向关联实例
* @author Victor
*
*/
public class OneToOne_Unidirectional_Test {
private SessionFactory sf;
private Session session;
private Transaction tran;
@Before
public void before(){
Configuration con=new Configuration().configure();
sf=con.buildSessionFactory();
session=sf.openSession();
tran=session.beginTransaction();
}
@After
public void after(){
System.out.println("00000000000000000000000000000");
//把SQL语句刷到数据库,执行的是单纯的SQL语句
//把对象刷到数据库中,调用对象的get方法
//给?占位符赋值
tran.commit();
//关闭session【因为session不安全】
//也会提交事务
session.close();
}
@Test
public void AutoCreateTable() {
Configuration con=new Configuration().configure("/hibernate.cfg.xml");
SchemaExport create=new SchemaExport(con);
create.create(true, true);
}
@Test
public void saveHus(){
//两个对象都是瞬时状态的
Husband husband=new Husband();
husband.setName("周志伟");
Wife wife=new Wife();
//在内存中间一定要建立起来对象与对象之间的关系
wife.setName("老鸨");
husband.setWife(wife);
session.save(husband);
//注意保存是的顺序问题【分别保存将执行三条语句】
//session.save(husband);
//insert into s_hus values(1,'周志伟',null);
//session.save(wife);
//insert into s_wife values(1,'lisi')
//update s_hus set wife_id=1 where id=1
//session.save(wife);
}
@Test
public void saveHusCas(){
//级联保存
Husband husband=new Husband();
husband.setName("隔壁老王");
Wife wife=new Wife();
wife.setName("艾希女王");
//在内存中间一定要建立起来对象与对象之间的关系
husband.setWife(wife);
//wife没有关联husband,这里是对象里面的管理,
//跟表没有关系
//session.save(wife);
//注意保存是的顺序问题
//保存丈夫的时候妻子也级联的保存
//在many-to-one中写入cascade
//一对一可选all delete save-update
//前提也是内存之间的关系
session.save(husband);
}
@Test//级联保存,保证id的唯一性
public void saveHusCasUnique(){
//如果考虑删除unique,要重新建表
try {
Husband hus=new Husband();
hus.setName("lisi1");
Wife wife=(Wife) session.get(Wife.class, 1);
hus.setWife(wife);
session.save(hus);

} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
@Test//级联查询
public void queryCas(){
//查看是否设置了延迟加载 lazy="false"不延迟加载
//注意这里采用延迟加载不能写成true,因为这个事由dtd文件
//规定的,延迟采用代理proxy

//load延迟加载和映射文件中设置的延迟加载的区别
/**
* session.load(Husband.class, 1)方法查询一级缓存,二级缓存
* ,还是找不到,创建一个代理对象,不去数据库中取值,
* 只有在使用Husband的时候才会去数据库查询对象,换言
* 之就是不会立刻发送sql语句去数据库中查询相应的内容
*
* 设置的延迟加载则是,查询Husband的时候并不会吧关联的
* wife直接查询出来,而是在使用的时候在把相应的
* wife内容查询出来,
* 延迟加载至少发出两条或者两条以上的sql语句,
* 延迟加载会提高代码的效率
*
*
* 影响延迟加载的还有一个属性
* fetch
*/
System.out.println("hello");
Husband hus=(Husband) session.get(Husband.class, 1);
System.out.println("world");
System.out.println(hus.getWife().getName());
}
@Test//设置级联查询的时候呢采用select还是join连接查询的方式
public void fetch_select_join(){
//select的方式就是先发一条sql查husband,在发一条查wife
//join外链接,在查Husband的时候使用外连接吧妻子查询出来
//也就是说在采用级联的时候采用什么方式进行查询
//注意:默认的情况是select
/**
* 区别
* select 执行两条sql语句;
* join执行一条sql语句,设置了延迟加载,不起作用了
* 常识,通畅sql语句的条数会影响到你的执行效率
*
*/
System.out.println("hello");
Husband hus=(Husband) session.get(Husband.class, 1);
System.out.println("world");
System.out.println(hus.getWife().getName());
}
@Test//级联的删除
public void delete(){
Husband hus=(Husband) session.get(Husband.class, 1);
session.delete(hus);
}
@Test
public void deletenoCas(){
//类似于删除托管状态的数据,缓存中没有但是数据库中有
Husband hus=new Husband();
hus.setId(1);
session.delete(hus);
}
@Test
public void deleteDetached(){
Husband hus=new Husband();
hus.setId(1);
Wife wife=new Wife();
wife.setId(1);
hus.setWife(wife);
//遮掩也是可以删除对象的
session.delete(hus);
}
@Test//级联更新操作
public void update(){
try {
Husband hus=(Husband) session.get(Husband.class, 1);
hus.getWife().setName("ls ooo");
session.update(hus);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
@Test
public void wife_query(){
//通过妻子对象获取不到husband
Wife wife=(Wife) session.get(Wife.class, 1);
System.out.println(wife.getName());
}
}

  <二>、一对一双向关联

  实体类一:

package com.briup.orm.oneToone.bidirectional;
public class Husband {
private int id;
private String name;
private Wife wife;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
@Override
public String toString() {
return "Husband [id=" + id + ", name=" + name + ", wife=" + wife + "]";
}
}

  实体类二:

package com.briup.orm.oneToone.bidirectional;
public class Wife {
private int id;
private String name;
private Husband husband;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
@Override
public String toString() {
return "Wife [id=" + id + ", name=" + name + ", husband=" + husband
+ "]";
}
}

  配置文件一:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.briup.orm.oneToone.bidirectional.Husband" table="s_husband">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<many-to-one name="wife" class="com.briup.orm.oneToone.bidirectional.Wife" column="wife_id" unique="true" cascade="all"/>
</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="com.briup.orm.oneToone.bidirectional.Wife" table="s_wife">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<one-to-one name="husband" class="com.briup.orm.oneToone.bidirectional.Husband" cascade="all"/>
</class>
</hibernate-mapping>

  测试类:

package com.briup.orm.oneToone.oneTooneTest;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.briup.orm.oneToone.bidirectional.Husband;
import com.briup.orm.oneToone.bidirectional.Wife;

/**
* 类与类之间的关系:一对一双向关联实例
* @author Victor
*
*/
public class OneToOne_Bidirectional_Test {
private SessionFactory sf;
private Session session;
private Transaction tran;
private Configuration con =new Configuration();
@Before
public void before(){
con.configure();
sf=con.buildSessionFactory();
session=sf.openSession();
tran=session.beginTransaction();
}
@After
public void after(){
//把SQL语句刷到数据库,执行的是单纯的SQL语句
//把对象刷到数据库中,调用对象的get方法
//给?占位符赋值
tran.commit();
//关闭session【因为session不安全】
//也会提交事务
session.close();
}
@Test
public void AutoCreateTable() {
try {
SchemaExport scheme=new SchemaExport(con);
scheme.create(false, true);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
@Test
public void save(){
Husband hus=new Husband();
hus.setName("briup");
Wife wife=new Wife();
wife.setName("wangzulan");
//注意如果保存的时候是被引用的对象(wife)
//你必须也要在另一方(hus)也要维护关系
//否则的话会出现外键丢失
//维护含有外键的一方,只要自己维护了关系就可以保存(hus)
//hus.setWife(wife);
wife.setHusband(hus);
session.save(wife);
}
@Test
public void saveFail(){
Husband hus=new Husband();
hus.setName("tom");
Wife wife=new Wife();
wife.setName("li");
hus.setWife(wife);
//这时需要
wife.setHusband(hus);
session.save(wife);
}
@Test
public void query(){
//默认的方式是join
Wife wife=(Wife) session.get(Wife.class, 1);
System.out.println(wife.getHusband()+"-------");
}
@Test//延迟加载
public void query_wife(){
//双向关联延迟加载失效
System.out.println("hello");
Wife wife=(Wife) session.get(Wife.class, 1);
System.out.println("world");
System.out.println(wife.getHusband().getName());
}
@Test//级联删除妻子或husband
public void delete(){
Wife wife=(Wife) session.get(Wife.class, 1L);
session.delete(wife);
}
}

  <三>、一对多单向关联

  实体类一:

package com.briup.orm.oneTomany.unidirectional;
import java.util.HashSet;
import java.util.Set;
public class Group {
private int id;
private String name;
private Set<User> users=new HashSet<User>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@Override
public String toString() {
return "Group [id=" + id + ", name=" + name + ", users=" + users + "]";
}
}

  实体类二:

package com.briup.orm.oneTomany.unidirectional;
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + "]";
}
}

  配置文件一:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.briup.orm.oneTomany.unidirectional.Group" table="s_group">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<!--
name="users"表示当前类有一个set集合叫做users
group_id在这个一对多的关系下
的外键列名字叫做griup_id
注意:一对的关系外键都会健在多的一方
cascade=""
all-delete-orphan和all的区别
-->
<set name="users" cascade="all-delete-orphan">
<key column="group_id"/>
<one-to-many class="com.briup.orm.oneTomany.unidirectional.User"/>
</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="com.briup.orm.oneTomany.unidirectional.User" table="s_user">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

  测试类:

package com.briup.orm.oneTomany.oneTomanyTest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
* 类与类之间的关系:一对多单向关联实例
* @author Victor
*
*/
public class OneToMany_Unidirectional_Test {
private SessionFactory sf;
private Session session;
private Transaction tran;
private Configuration con=new Configuration();
@Before
public void before(){
con.configure();
sf=con.buildSessionFactory();
session=sf.openSession();
tran=session.beginTransaction();
}
@After
public void after(){
tran.commit();
session.close();
}
@Test
public void AutoCreatTable(){
SchemaExport schema=new SchemaExport(con);
schema.create(false, true);
}
}

  <四>、一对多双向关联

  实体类一:

package com.briup.orm.oneTomany.bidirectional;

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

public class Group {
private int id;
private String name;
private Set<User> users=new HashSet<User>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@Override
public String toString() {
return "Group [id=" + id + ", name=" + name + ", users=" + users + "]";
}
}

  实体类二:

package com.briup.orm.oneTomany.bidirectional;

public class User {
private int id;
private String name;
private Group group;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", group=" + group + "]";
}
}

  配置文件一:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.briup.orm.oneTomany.bidirectional.Group" table="s_group">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<!--
name="users"表示当前类有一个set集合叫做users
group_id在这个一对多的关系下
的外键列名字叫做griup_id
注意:一对的关系外键都会健在多的一方
cascade=""
all-delete-orphan和all的区别
inverse 表示是否吧外键维护的相关只能反转给另外一方;
-->
<set name="users" cascade="all-delete-orphan" inverse="true">
<key column="group_id"/>
<one-to-many class="com.briup.orm.oneTomany.bidirectional.User"/>
</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="com.briup.orm.oneTomany.bidirectional.User" table="s_user">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<!-- 注意column=group_id必须保持一致,否则会建立两个外键列 -->
<many-to-one name="group" class="com.briup.orm.oneTomany.bidirectional.Group" column="group_id" cascade="all"/>
</class>
</hibernate-mapping>

  测试类:

package com.briup.orm.oneTomany.oneTomanyTest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* 类与类之间的关系:一对多双向关联实例
* @author Victor
*
*/
public class OneToMany_Bidirectional_Test {
private SessionFactory sf;
private Session session;
private Transaction tran;
private Configuration con=new Configuration();
@Before
public void before(){
con.configure();
sf=con.buildSessionFactory();
session=sf.openSession();
tran=session.beginTransaction();
}
@After
public void after(){
tran.commit();
session.close();
}
@Test
public void AutoCreatTable(){
SchemaExport schema=new SchemaExport(con);
schema.create(false, true);
}
} 

  <五>、多对多单向关联

  实体类一:

package com.briup.orm.manyTomany.unidirectional;
import java.util.HashSet;
import java.util.Set;
public class Teacher {
private long id;
private String name;
private Set<Student> students=new HashSet<Student>();
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 Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Teacher [id=" + id + ", name=" + name + ", students="
+ students + "]";
}
}

  实体类二:

package com.briup.orm.manyTomany.unidirectional;
public class Student {
private long id;
private String name;
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;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}

  配置文件一:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.briup.orm.manyTomany.unidirectional.Teacher" table="s_teacher">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!--
table="t_s"产生第三表的名字t_s
<key column="t_id" >在桥表中当前teacher的外键是t_id
-->
<set name="students" table="t_s">
<key column="t_id"/>
<many-to-many column="s_id" class="com.briup.orm.manyTomany.unidirectional.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="com.briup.orm.manyTomany.unidirectional.Student" table="s_student">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

  测试类:

package com.briup.orm.manyTomany.manyTomanyTest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* 类与类之间的关系:多对多单向关联实例
* @author Victor
*
*/
public class ManyToMany_Unidirectional_Test {
private SessionFactory sfFactory;
private Session session;
private Transaction transaction;
private Configuration configuration=new Configuration();
@Before
public void before(){
configuration.configure();
sfFactory=configuration.buildSessionFactory();
session=sfFactory.openSession();
transaction=session.beginTransaction();
}
@After
public void after(){
transaction.commit();
session.close();
}
@Test
public void AutoCreateTable(){
SchemaExport schemaExport=new SchemaExport(configuration);
schemaExport.create(true, true);
}
}

  <六>、多对多双向关联

  实体类一:

package com.briup.orm.manyTomany.bidirectional;
import java.util.HashSet;
import java.util.Set;
public class Teacher {
private long id;
private String name;
private Set<Student> students=new HashSet<Student>();
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
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;
}
}

  实体类二:

package com.briup.orm.manyTomany.bidirectional;
import java.util.HashSet;
import java.util.Set;
public class Student {
private long id;
private String name;
private Set<Teacher> teachers=new HashSet<Teacher>();
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
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;
}
}

  配置文件一:

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.briup.orm.manyTomany.bidirectional.Teacher" table="s_teacher">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<!--
table="t_s"产生第三表的名字t_s
<key column="t_id" >在桥表中当前teacher的外键是t_id
-->
<set name="students" table="t_s" cascade="all">
<key column="t_id"/>
<many-to-many column="s_id" class="com.briup.orm.manyTomany.bidirectional.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="com.briup.orm.manyTomany.bidirectional.Student" table="s_student">
<id name="id">
<generator class="increment"/>
</id>
<property name="name"/>
<!-- inverse="true"将权限交给对象维护 -->
<set name="teachers" table="t_s" inverse="true">
<key column="s_id"/>
<many-to-many column="t_id" class="com.briup.orm.manyTomany.bidirectional.Teacher"/>
</set>
</class>
</hibernate-mapping>

  测试类:

package com.briup.orm.manyTomany.manyTomanyTest;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.briup.orm.manyTomany.bidirectional.Student;
import com.briup.orm.manyTomany.bidirectional.Teacher;

public class ManyToMany_Bidirectional_Test {
private SessionFactory sessionFactory;
private Session session;
private Transaction taranTransaction;
private Configuration configuration=new Configuration();
@Before
public void before(){
configuration.configure();
sessionFactory=configuration.buildSessionFactory();
session=sessionFactory.openSession();
taranTransaction = session.beginTransaction();
}
@After
public void after(){
taranTransaction.commit();
session.close();
}
@Test
public void AutoCreateTable(){
SchemaExport schemaExport=new SchemaExport(configuration);
schemaExport.create(true, true);
}
@Test
public void save(){
Teacher t=new Teacher();
t.setName("Oracle1");

Student s1=new Student();
s1.setName("coreJava1");

Student s2=new Student();
s2.setName("coreJava2");

Student s3=new Student();
s3.setName("coreJava3");

Student s4=new Student();
s4.setName("coreJava4");
//注意,内存中一定要建立起来关联关系
t.getStudents().add(s1);
t.getStudents().add(s2);
t.getStudents().add(s3);
t.getStudents().add(s4);
session.save(t);
}
@Test
public void query_list(){
Teacher tea=(Teacher) session.get(Teacher.class, 1L);
for(Student s:tea.getStudents()){
System.out.println(tea.getName()+";"+s.getId()+";"+s.getName());
}
}
@Test
public void delete(){
Teacher tea=(Teacher) session.get(Teacher.class, 1L);
session.delete(tea);
}
@Test
public void delete1(){
//和前面类似,all解除的只是关联关系,all-delete-orphan删除关联数据
Teacher tea=(Teacher) session.get(Teacher.class, 2L);
tea.getStudents().clear();
}
}

总结

1--------1
many-to-one(unique) one-to-one

外键是在many-to-one

fetch join(外链接)
cascade 级联操作 all save-update delete
lazy false全部一起执行,
用的时候加载的是proxy/noproxy

1-----n
外键在多的一方建立
在类里面我是通过set集合表示这种关系的,多的这一
方直接引用少的这一方对象

在hbm.xml文件中
少的这一边有
set inverse(把多的这一方外键由谁维护,fasle的
由少的维护,true由多的这一方维护,尽量由多的这方
维护,可以提高效率)
fetch(join,select,subselect)
cascade 级联all save-update all-delete-orphan delete
all和all-delete-orphan的区别
all解除关系在set集合中清空,在user中group_id全部设为null
all-delete-orphan,解除关系,只是会吧集合中的数据对应user
全部删除
<key>---这里指明的是将来外键生成的列的属性值
one-to-many 指向的是多的一方对象

多的这一方
many-to-one 注意:column的属性这时候添值一定要和
少的一方中的key里面的属性值相同,如不同会生成两个
外键,不符合设计要求;

many ----many