2.1、Hibernate多表操作--一对多、多对一、多对多。
一、什么是一对一、一对多、多对一及多对多关系(以简单的学生和老师的关系为例来说):
1、一对一:学生具有学号和姓名(假定没有同名的学生)这两个属性,那么我知道了学生的学号也就能找到对应的学生姓名,如果我找到了学生的姓名也就能够找到学生的学号,两者之间是一一对应的,即一对一。
2、一对多:以一个学生为对象,学生可以选择多门门课程,每门课程对应一个老师,即一个学生对应多个老师为他教学。那么这样就产生了一对多的关系。
3、多对一:每一个学生都可以选择不同的课程,但是课程的数量是有限的,这样一来就会有多个学生选择选择同一门课,即就是多个学生对应于同一个老师。这样就产生了多对一的关系。
4、多对多:从学生的角度来说:一个学生可以对应多个老师,从老师的角度来说:一个老师可以同时教多个学生。如果同时考虑学生和老师,那么就产生了多对多的关系。
二、简单的一对多关系(.xml):
1、创建两张表:
create table t_item(
id number primary key,
item_name varchar2(30)
);
create table t_image(
item_id number references t_item(id),
img_name varchar2(30)
);
2、创建一个web项目,将Hibernate框架所需的jar包拷贝到lib目录下。
3、粘贴上一篇日志中的HibernateTools工具类。
4、创建一个ItemBean类
package com.st.bean1; import java.util.HashSet;
import java.util.Set; public class ItemBean { private long id;
private String itemName; private Set<String> imge =new HashSet<String>(); public long getId() {
return id;
} public void setId(long id) {
this.id = id;
} public String getItemName() {
return itemName;
} public void setItemName(String itemName) {
this.itemName = itemName;
} public Set<String> getImge() {
return imge;
} public void setImge(Set<String> imge) {
this.imge = imge;
} @Override
public String toString() {
return "ItemBean [id=" + id + ", itemName=" + itemName + ", imge="
+ imge + "]";
}
}
5、.拷贝一个xxx.hbm.xml文件到com.st.bean目录下,重命名为item.hbm.xml,并修改class标签中的属性:使item表与ItemBean类之间存在映射关系:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.st.bean1.ItemBean" table="t_item">
<id name="id" column="ID">
<!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
<generator class="increment"></generator>
</id>
<!-- 普通节点配置 -->
<property name="itemName" column="ITEM_NAME" type="java.lang.String" ></property> <!-- 基本的一对多配置
name:javaBean 里面的集合名
table:映射外键对应的表
key:映射的外表的外键
elememt:元素值对应的列
-->
<set name="imge" table="t_image">
<!-- 指定外键 -->
<key column="item_id"></key>
<element column="IMG_NAME" type="java.lang.String"></element>
</set>
</class>
</hibernate-mapping>
6、拷贝一个hibernate.cfg.xml文件到src文件下,删除hibernate.xml文件中无用的映射文件后,添加映射文件-item.hbm.xml。
7、6、在新建一个BeanTest类,在里面即可编写相应的增删改查的代码:
@Test
public void bean1test1(){
// 获取一个会话
Session session = HibernateTools.openSession();
//开启一次事物
Transaction tran = session.beginTransaction();
ItemBean item = new ItemBean ();
item.setItemName("第四个项目");
item.getImge().add("a4.jpg");
item.getImge().add("b4.jpg");
session.save(item);
//确认提交事物
tran.commit();
}
@Test
public void bean1test2(){
Session session = HibernateTools.openSession();
List<ItemBean> list= session.createCriteria(ItemBean.class).list();
for(ItemBean a : list)
System.out.println(a);
}
@Test
public void bean1test3(){
Session session = HibernateTools.openSession();
ItemBean item = (ItemBean)session.get(ItemBean.class,1L); //1L代表主键
Transaction tran = session.beginTransaction();
session.delete(item);
tran.commit();
}
三、复杂的一对多关系:
1、创建两张表:
/*部门表*/
create table dept(
id number primary key,
name varchar2(30) /*部门名称*/
);
/*员工表*/
create table employee(
id number primary key,
name varchar2(30),
sex varchar2(2),
job varchar2(20),
dept_id number references dept(id) /*所在部门*/
);
2、创建一个DeptBean类
package com.st.bean2; import java.util.HashSet;
import java.util.Set; public class DeptBean {
private long id;
private String name; private Set<EmployeeBean> emp = new HashSet<EmployeeBean>(); @Override
public String toString() {
return "DeptBean [id=" + id + ", name=" + 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 Set<EmployeeBean> getEmp() {
return emp;
} public void setEmp(Set<EmployeeBean> emp) {
this.emp = emp;
} }
3、创建一个EmployeeBean类
package com.st.bean2; public class EmployeeBean {
private long id;
private String name;
private String sex;
private String job;
private long deptId;
//一个员工对应于一个部门号,所以这里不用集合
private DeptBean dept ; //注意这个地方不要new对象,否则会无法运行 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 String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public String getJob() {
return job;
} public void setJob(String job) {
this.job = job;
} public long getDeptId() {
return deptId;
} public void setDeptId(long deptId) {
this.deptId = deptId;
} public DeptBean getDept() {
return dept;
} public void setDept(DeptBean dept) {
this.dept = dept;
} @Override
public String toString() {
return "EmployeeBean [id=" + id + ", name=" + name + ", sex=" + sex
+ ", job=" + job + ", deptId=" + deptId + ", dept=" + dept
+ "]";
}
}
4、配置DeptBean这个类的xml文件
<hibernate-mapping> <class name="com.st.bean2.DeptBean" table="DEPT">
<id name="id" column="ID">
<!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
<generator class="increment"></generator>
</id>
<!-- 普通节点配置 -->
<property name="name" column="NAME" type="java.lang.String" ></property> <!-- 一对多配置一的一方
name:javaBean 里面的集合名
cascade:级联关系(增加、删除、修改)
inverse:表示是否维护关系
key:映射的外表的外键
class:对应外表的JavaBean
-->
<set name="emp" cascade="all" inverse="false">
<!-- 指定外键 -->
<key column="dept_id"></key>
<one-to-many class="com.st.bean2.EmployeeBean"/> <!-- 外表对应的JavaBean -->
</set>
</class>
</hibernate-mapping>
5、配置EmployeeBean这个类的xml文件
<hibernate-mapping> <class name="com.st.bean2.EmployeeBean" table="employee">
<id name="id" column="ID">
<!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
<generator class="increment"></generator>
</id>
<!-- 普通节点配置 -->
<property name="name" column="NAME" type="java.lang.String" ></property>
<property name="sex" column="SEX" ></property>
<property name="job" column="JOB" ></property> <!-- 多的一方的属性名 -->
<many-to-one name="dept" column="DEPT_ID"></many-to-one>
</class>
</hibernate-mapping>
6、将上面两个类的配置文件映射到hibernate.cfg.xml文件中去。
7、在BeanTest类下面编写测试代码:
@Test
public void bean2test1(){
// 获取一个会话
Session session = HibernateTools.openSession();
//开启一次事物
Transaction tran = session.beginTransaction(); //首先在dept中新增一条数据,再在关联的employee中新增一条数据
DeptBean dept = new DeptBean();
//先读去dept中的数据,再在读取的基础上关联的在employee中新增一条数据
// DeptBean dept = (DeptBean) session.get(DeptBean.class,1L); //1L代表主键
EmployeeBean emp = new EmployeeBean();
dept.setName("技术部");
emp.setName("陈泽俊");
emp.setSex("男");
emp.setJob("STM32");
emp.setDeptId(1);
dept.getEmp().add(emp);
session.save(dept);
//确认提交事物
tran.commit();
}
@Test
public void bean2test2(){
Session session = HibernateTools.openSession();
List<DeptBean> list= session.createCriteria(DeptBean.class).list();
for(DeptBean a : list)
System.out.println(a.getEmp());
System.out.println("/************************************************************************/");
List<EmployeeBean> list1= session.createCriteria(EmployeeBean.class).list();
for(EmployeeBean a : list1)
System.out.println(a);
}
@Test
//注意以下三种删除方法的不同之处,更新和删除一样
public void bean2test3(){
Session session = HibernateTools.openSession();
Transaction tran = session.beginTransaction();
//先将employee的dept_id更新为null,再讲dept删除
/* DeptBean dept = new DeptBean();
dept.setId(1L);
session.delete(dept);*/
//直接将employee中的类容删除,dept中的类容不删除
/* EmployeeBean employee = new EmployeeBean();
employee.setId(1L);
session.delete(employee);*/
//将employee中的关联外键dept_id更新为null,再删除employee中的数据再删除dept中的数据
DeptBean dept = (DeptBean) session.get(DeptBean.class, 1L);
session.delete(dept);
tran.commit();
}
四、多对多关系
1、新建三张表t_user、t_role及第三张关联表user_role
create table t_user(
id number primary key,
name varchar2(30),
sex varchar2(10)
);
create table t_role(
id number primary key,
post varchar2(30),--职位
pay number --薪资
);
create table user_role(
user_id number references t_user(id) ,
role_id number references t_role(id)
); select *from t_role;
select *from t_user;
select *from user_role; drop table user_role;
drop table t_role;
drop table t_user;
2、上述已有的目下新建一个bean3包,再在包下面新建两个类:UserBean和RoleBean
a)userBean
package com.st.bean3;
import java.util.HashSet;
import java.util.Set;
public class UserBean {
private long id;
private String name;
private String sex; private Set<RoleBean> role = new HashSet<RoleBean>(); 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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Set<RoleBean> getRole() {
return role;
}
public void setRole(Set<RoleBean> role) {
this.role = role;
}
@Override
public String toString() {
return "UserBean [id=" + id + ", name=" + name + ", sex=" + sex
+ ", role=" + role + "]";
}
}
b)RoleBean
package com.st.bean3;
import java.util.HashSet;
import java.util.Set;
public class RoleBean {
private long id;
private String post;//职位
private int pay; //薪资 private Set<UserBean> user = new HashSet<UserBean>(); public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
public int getPay() {
return pay;
}
public void setPay(int pay) {
this.pay = pay;
}
public Set<UserBean> getUser() {
return user;
}
public void setUser(Set<UserBean> user) {
this.user = user;
}
@Override
public String toString() {
return "RoleBean [id=" + id + ", post=" + post + ", pay=" + pay + "]";
}
}
3、在bean包下面添加两个Bean类的.xml配置文件
a)user.hbm.xml
<hibernate-mapping> <class name="com.st.bean3.UserBean" table="T_USER">
<id name="id" column="ID">
<!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
<generator class="increment"></generator>
</id>
<!-- 普通节点配置 -->
<property name="name" column="NAME" type="java.lang.String" ></property>
<property name="sex" column="SEX" type="java.lang.String" ></property> <!-- 多对多关系映射
name:javaBean对应的属性名
table:中间表
key中的column:与本类主键对应的中间表的外键
many-to-many中的column:class里设置的类的主键对应的中间表的外键
-->
<set name="role" table = "user_role" cascade="save-update" inverse="false">
<key column="USER_ID"></key>
<many-to-many class="com.st.bean3.RoleBean" column="ROLE_ID"></many-to-many>
</set>
</class>
</hibernate-mapping>
b)role.hbm.xml
<hibernate-mapping> <class name="com.st.bean3.RoleBean" table="T_ROLE">
<id name="id" column="ID">
<!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
<generator class="increment"></generator>
</id>
<!-- 普通节点配置 -->
<property name="post" column="POST" type="java.lang.String" ></property>
<property name="pay" column="PAY" ></property> <set name="user" table="user_role" cascade="save-update" inverse="false">
<key column="ROLE_ID"></key>
<many-to-many class="com.st.bean3.UserBean" column="USER_ID"/>
</set>
</class>
</hibernate-mapping>
4、早hibernate.cfg.xml文件中引入步骤三种的两个配置文件:
<mapping resource="com/st/bean3/role.hbm.xml"/>
<mapping resource="com/st/bean3/user.hbm.xml"/>
5、在BeanTest类中编写测试代码
@Test
public void bean3test1(){
// 获取一个会话
Session session = HibernateTools.openSession();
//开启一次事物
Transaction tran = session.beginTransaction();
UserBean user = new UserBean();
RoleBean role = (RoleBean) session.get(RoleBean.class,3L);
// RoleBean role = new RoleBean();
user.setName("陈泽俊");
user.setSex("男");
// role.setPost("单片机开发工程师");
// role.setPay(9000);
role.getUser().add(user);
session.save(role);
//确认提交事物
tran.commit();
}
@Test
public void bean3test2(){
// 获取一个会话
Session session = HibernateTools.openSession();
/* List<UserBean> list = session.createCriteria(UserBean.class).list();
for(UserBean user : list)
System.out.println(user);*/
String hql = "select new Map(u.name as name,u.sex as sex,r.post as post,r.pay as pay) from UserBean u join u.role r";
List<Map<String,Object>> list = session.createQuery(hql).list();
for(Map<String,Object> data : list)
System.out.println(data);
}
19:41:06
2.1、Hibernate多表操作--一对多、多对一、多对多。的更多相关文章
- JDBC上关于数据库中多表操作一对多关系和多对多关系的实现方法
黑马程序员 我们知道,在设计一个Javabean的时候,要把这些BEAN 的数据存放在数据库中的表结构,然而这些数据库中的表直接又有些特殊的关系,例如员工与部门直接有一对多的关系,学生与老师直接又多对 ...
- hibernate多表操作
一.表之间的关系 1.一对一 2.一对多 3.多对多 二.表之间关系建表原则 1.一对多:在多的一方创建一个外键,指向一的一方的主键 2.多对多:创建一个中间表,中间表至少有两个字段,分别作为外键指向 ...
- Hibernate单表操作
单一主键 assigned:由Java应用程序负责生成(即手工的赋值) native:由底层的数据库自动的生成标示符,如果是MySQL就是auto_increment,如果是Oracle就是seque ...
- (三)hibernate单表操作
0. 贴上节hbm文件 <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hib ...
- hibernate课程 初探单表映射3-1 hibernate单表操作简介
本章简介: 1 单一主键 2 基本类型 3 对象类型 4 组件属性 5 单表操作CRUD实例
- 六 Hibernate多表操作&级联&外键维护
Hibernate的一对多关联映射 Hibernate的多对多关联映射 数据库表与表之间的关系:一对多,多对多,一对一 一对多:一个部门对应多个员工,一个员工只能属于一个部门.一个客户对应多个联系人, ...
- Hibernate单表操作(一)——单一主键
assigned由java应用程序负责生成.(手工赋值) native由底层数据库自己主动生成标识符,假设是MySQL就是increment,假设是oracle就是sequence.等等.
- Django框架第七篇(模型层)--多表操作:一对多/多对多增删改,跨表查询(基于对象、基于双下划线跨表查询),聚合查询,分组查询,F查询与Q查询
一.多表操作 一对多字段的增删改(book表和publish表是一对多关系,publish_id字段) 增 create publish_id 传数字 (publish_id是数据库显示的字段名 ...
- Django学习手册 - ORM 数据创建/表操作 汇总
ORM 查询的数据类型: QuerySet与惰性机制(可以看作是一个列表) 所谓惰性机制:表名.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它 ...
随机推荐
- JS--轻松设置获取表单数据
接触过Angularjs的都知道,ng支持双向绑定,我们可以轻轻松松的通过ngModel将我们的值绑定到界面,当修改了值提交表单的时候不需要再重新通过ID去重新抓取输入框信息了.那对于我们开发前台网站 ...
- 常用的14种HTTP状态码速查手册
分类 1xx \> Information(信息) // 接收的请求正在处理 2xx \> Success(成功) // 请求正常处理完毕 3xx \> Redirection(重定 ...
- 【python之路2】CMD中执行python程序中文显示乱码
在IDLE中执行下面代码,中文显示正常: # -*- coding:utf-8 -*- st=raw_input("请输入内容")print st 但在CMD中执行e:\hello ...
- Spring 设值注入 构造注入 p命名空间注入
注入Bean属性---构造注入配置方案 在Spring配置文件中通过<constructor-arg>元素为构造方法传参 注意: 1.一个<constructor-arg>元素 ...
- ACM模板(持续补完)
1.KMP #include<cstring> #include<algorithm> #include<cstdio> using namespace std; ...
- C#扩展方法
扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法就相当于一个马甲,给一个现有类套上,就可以为这个类添加其他方法了. 马甲必须定义为stati ...
- Spring缓存机制的理解
在spring缓存机制中,包括了两个方面的缓存操作:1.缓存某个方法返回的结果:2.在某个方法执行前或后清空缓存. 下面写两个类来模拟Spring的缓存机制: package com.sin90lzc ...
- zabbix利用api批量添加item,并且批量配置添加graph
关于zabbix的API见,zabbixAPI 1item批量添加 我是根据我这边的具体情况来做的,本来想在模板里面添加item,但是看了看API不支持,只是支持在host里面添加,所以我先在一个ho ...
- Javascript字节转换
//文件大小转换 function bytesToSize(bytes) { if (bytes === 0) return '0 B'; var k = 1024; sizes = ['B', 'K ...
- destoon : 后台无法登录问题解决
经常有朋友在destoon搬家的时候 , 数据还原之后 , 会出现后台无法登录的情况 . 具体表现为后台帐号密码输入后点击确定 , 页面刷新 .并没有跳转到相应后台页面 . 但是如果帐号密码输入错误 ...