hibernate对象与对象的关系,其实是对象与表的关系。
一.一对一
比如一个人对应一张身份证,一个门对应一把钥匙等…
在数据库中两张表,一张表的主键是通过引入另一张表的主键,建外键的关系
card实体类中
private User users;//user对象
user实体类中
private Card card;//card对象
card实体类的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-7-8 12:14:40 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.ywy.entity.Card" table="CARD">
<id name="cid" type="java.lang.Integer">
<column name="CID" />
<!-- 外键 通过引入user表的uid class=foreign通过外键的方式生成id-->
<generator class="foreign">
<!-- 引入哪一个表的主键 users;名字与在实体类中的名字一致-->
<param name="property">users</param>
</generator>
</id>
<property name="cumber" type="java.lang.String">
<column name="CUMBER" />
</property>
<!-- 实体类中有的对象,在映射文件中都要与之对应-->
<!-- 映射users的对象 name:与实体类的名称一致 class:对象的类型-->
<!-- one-to-one一对一-->
<one-to-one name="users" class="com.ywy.entity.User"></one-to-one>
</class>
</hibernate-mapping>
user实体类的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-7-8 12:14:40 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.ywy.entity.User" table="USER">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="uname" type="java.lang.String">
<column name="UNAME" />
</property>
<!-- 在user类中也有card对象 -->
<!-- cascade:级联操作 all:级联所有的操作-->
<one-to-one name="card" class="com.ywy.entity.Card" cascade="all"></one-to-one>
</class>
</hibernate-mapping>
删除:删除主表的时候,次表与会删除。除非断绝关系
//删除--删除主表的同时,会把次表的也删除
//Card card=session.get(Card.class, 2);
Card card=session.get(Card.class, 3);
//断绝关系,就会只删除card的数据,不会删除user
//card.getUsers().setCard(null);
session.delete(card);
新增:主表的新增,次表也会新增
//两表新增--主表的新增,次表也会新增
Card card=new Card("43060220004439348");
User user=new User("小明);
//互相设置
card.setUsers(user);
user.setCard(card);
//新增就只用新增主表。因为级联的关系,次表也会新增
session.save(user);
修改:修改的时,主表修改,次表不会修改,修改次表的时候,主表也不会影响
//修改 只修改了card表的内容
Card card=session.get(Card.class,4);
//修改的时候要注意设置为空,相当于断绝关系
card.getUsers().setCard(null);
card.setCumber("43068492778339221");
/*
//两个表的修改
User user=session.get(User.class, 4);
Card card=session.get(Card.class, user.getId());
user.setUname("小小");
card.setCumber("2222222");
*/
查询:查询出主表,次表的内容也出来,查询次表,主表内容也出来
//查询全部次表
List<Card> list = session.createQuery("from Card").list();
for (Card card : list) {
System.out.println(card.getCumber()+card.getUsers().getUname());
}
//查询全部主表
List<User> list = session.createQuery("from User").list();
for (User card : list) {
System.out.println(card.getUname()+card.getCard());
}
二.一对多
就比如省份和城市,用户和订单,等…
hibernate中实体类中:
province
//省份表
private Integer pid;
private String pname;
//一个省份里面有多个城市 是数组--城市集合
//多对一 或者 一对多
private Set<City> cities=new HashSet<City>();
对应的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-7-9 16:17:42 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.ywy.entity.Province" table="PROVINCE">
<id name="pid" type="java.lang.Integer">
<column name="PID" />
<generator class="native" />
</id>
<property name="pname" type="java.lang.String">
<column name="PNAME" />
</property>
<!-- city的集合 -->
<!-- cascade:全部级联 谁为主谁级联-->
<!-- 维护关系 inverse:关系反转 现在是多的维护关系
城市自己要记住省份 而不是省份要城市强制记住自己
少的级联,多的维护关系
-->
<set name="cities" cascade="all" inverse="true">
<!-- 城市是通过pid来找到自己是在哪一个省份里面 -->
<!-- 就是城市表里面的外键 column:城市表的名称-->
<key column="pid"></key>
<!-- 来自哪一个类中 -->
<!-- 一对多的关系 一个省份里面有多个城市-->
<one-to-many class="com.ywy.entity.City"></one-to-many>
</set>
</class>
</hibernate-mapping>
city
//城市表
private Integer cid;
private String cname;
//之前有pid,现在不需要,有了一个省份对象,里面就包含了pid
//private Integer pid;
//一个城市或者多个城市 对应一个省份----省份对象
//省份对象里面就有省份的id pid 一个多
private Province province;
对应的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-7-9 16:17:42 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.ywy.entity.City" table="CITY">
<id name="cid" type="java.lang.Integer">
<column name="CID" />
<generator class="native" />
</id>
<property name="cname" type="java.lang.String">
<column name="CNAME" />
</property>
<!-- 没有了-->
<!-- <property name="pid" type="java.lang.Integer">
<column name="PID" />
</property> -->
<!-- column:通过哪一个列关联 -->
<!-- 多多一的关系,多个城市对应一个省份-->
<many-to-one name="province" class="com.ywy.entity.Province" column="pid"></many-to-one>
</class>
</hibernate-mapping>
相应的操作
新增:主表的新增,次表也会新增
//新增所有
//创建省份对象
Province province=new Province("湖北省");
//创建城市对象
City c1=new City("武汉市");
City c2=new City("襄阳市");
City c3=new City("咸宁市");
//在省份里面添加城市
province.getCities().add(c1);
province.getCities().add(c2);
province.getCities().add(c3);
//在城市里面设置相应的省份
c1.setProvince(province);
c2.setProvince(province);
c3.setProvince(province);
//新增省份,城市也会新增
session.save(province);
删除:主表删除,次表也要影响
//删除一个省份同时删除省份对应的城市
Province province =session.get(Province.class, 2);
session.delete(province);
/*//删除一个城市 删除它的省份
City city=session.get(City.class, 10);
Province province=session.get(Province.class, city.getProvince().getPid());
province.setCities(null);;
session.delete(province);
session.delete(city);*/
查询:主表查询,要有次表的内容,次表查询,也要有主表内容
查询一个省份同时查询这个省份对应的城市
/*Province p=session.get(Province.class, 2);
//先查询出省份,然后在省份中获取到城市集合
Set<City> cs = p.getCities();
for (City city : cs) {
System.out.println(p.getPname()+" "+city.getCname()+" "+city.getCid());
}
修改:主表修改,次表不会修改
//给一个城市重新设置省份
City city=session.get(City.class, 17);
Province province=session.get(Province.class, 5);
city.setProvince(province);
province.getCities().add(city);
三.多对多
有老师和学生,用户和权限等…
老师的实体类中
//一个老师可以有多个学生
private Set<Student2> student2s=new HashSet<Student2>();
映射文件中
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-7-10 18:42:51 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.yyy.entity.Teacher" table="TEACHER">
<id name="tid" type="java.lang.Integer">
<column name="TID" />
<generator class="native" />
</id>
<property name="tname" type="java.lang.String">
<column name="TNAME" />
</property>
<!-- table:两个表的关系表的名字 因为他们的关系在关系表中,不会在自己本身的表里-->
<!-- 其他的意思和上面一对多的意思一样-->
<set name="student2s" table="tea_stu" cascade="all" inverse="true">
<!-- tid:学生通过什么来找自己的老师,通过老师的id-->
<key column="tid"></key>
<!-- 学生通过自己的id和老师的id联系-->
<many-to-many column="sid" class="com.yyy.entity.Student2"></many-to-many>
</set>
</class>
</hibernate-mapping>
学生的实体类中
private Set<Teacher> teachers=new HashSet<Teacher>();
映射文件中
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-7-10 18:42:51 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.yyy.entity.Student2" table="STUDENT2">
<id name="sid" type="java.lang.Integer">
<column name="SID" />
<generator class="native" />
</id>
<property name="sname" type="java.lang.String">
<column name="SNAME" />
</property>
<!-- table:两个表的关系表的名字 因为他们的关系在关系表中,不会在自己本身的表里-->
<set name="teachers" table="tea_stu">
<key column="sid"></key>
<many-to-many class="com.yyy.entity.Teacher" column="tid"></many-to-many>
</set>
</class>
</hibernate-mapping>
增加:
//新增全部
//创建老师和学生对象
Student2 s1=new Student2("小明");
Student2 s2=new Student2("小明2");
Teacher t1=new Teacher("黄老师");
Teacher t2=new Teacher("张老师");
//要学生认识老师,老师也认识学生
t1.getStudent2s().add(s1);
t1.getStudent2s().add(s2);
s1.getTeachers().add(t1);
s2.getTeachers().add(t1);
t2.getStudent2s().add(s2);
t2.getStudent2s().add(s1);
s1.getTeachers().add(t2);
s2.getTeachers().add(t2);
session.save(t1);
session.save(t2);
//找到一个老师添加一个学生
Teacher t = session.get(Teacher.class, 1);
Student2 stu=new Student2("向敏");
t.getStudent2s().add(stu);
stu.getTeachers().add(t);
session.save(t);
删除:
//找到一个老师删除一个学生
Teacher t = session.get(Teacher.class, 2);
Student2 s2 = session.get(Student2.class, 2);
//直接删除一个学生
session.delete(s2);*/
查询:
/*//找到所有的老师 同时找到所有老师的学生
List<Teacher> list = session.createQuery("from Teacher").list();
for (Teacher teacher : list) {
//System.out.println(teacher.getTname());
//获取老师中的学生集合
Set<Student2> student2s = teacher.getStudent2s();
for (Student2 s : student2s) {
System.out.println(s.getSname()+teacher.getTname());
}
}*/
//找到一个老师找到他所有的学生
/*Teacher t = session.get(Teacher.class, 1);
Set<Student2> s = t.getStudent2s();
for (Student2 student2 : s) {
System.out.println(student2.getSname()+t.getTname());
}*/
修改:
//找到一个老师修改一个学生的名字
Teacher t = session.get(Teacher.class, 1);
Student2 stu=session.get(Student2.class, 3);
stu.setSname("小鱼");
补: cascade中有的属性
all:关联全部操作
none:不关联 默认值
delete:关联删除
save-update:关联新增和删除
delete-orphan:删除和的当前对象解除关联关系的对象
all-delete-orphan:all和delete-orphan的行为