一、数据库中的表关系:

一对一关系

一个人对应一张身份证,一张身份证对应一个人,一对一关系是最好理解的一种关系,在数据库建表的时候可以将人表的主键放置与身份证表里面,也可以将身份证表的主键放置于人表里面

一对多关系

一个班级拥有多个学生,一个学生只能够属于某个班级,班级是1端,学生是多端,结合面向对象的思想,1端是父亲,多端是儿子,所以多端具有1端的属性,也就是说多端里面应该放置1端的主键,那么学生表里面应该放置班级表里面的主键

多对多关系

一个学生可以选修多门课程,一个课程可以被多个学生选修,对于多对多关系,需要转换成1对多关系,那么就需要一张中间表来转换,这张中间表里面需要存放学生表里面的主键和课程表里面的主键,此时学生与中间表示1对多关系,课程与中间表是1对多关系,学生与课程是多对多关系

引用:https://blog.csdn.net/u013144287/article/details/79024130

二·、Hibernate中的一对多配置

1、SQL语句:

CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; CREATE TABLE `cst_linkman` (
`lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',
`lkm_name` varchar(16) DEFAULT NULL COMMENT '联系人姓名',
`lkm_cust_id` bigint(32) DEFAULT NULL COMMENT '客户id',
`lkm_gender` char(1) DEFAULT NULL COMMENT '联系人性别',
`lkm_phone` varchar(16) DEFAULT NULL COMMENT '联系人办公电话',
`lkm_mobile` varchar(16) DEFAULT NULL COMMENT '联系人手机',
`lkm_email` varchar(64) DEFAULT NULL COMMENT '联系人邮箱',
`lkm_qq` varchar(16) DEFAULT NULL COMMENT '联系人qq',
`lkm_position` varchar(16) DEFAULT NULL COMMENT '联系人职位',
`lkm_memo` varchar(512) DEFAULT NULL COMMENT '联系人备注',
PRIMARY KEY (`lkm_id`),
KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),
CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2、代码结构

3、Customer类

package com.turtle.dao;

import java.io.Serializable;
import java.util.*; public class Customer implements Serializable {
// 客户编号(主键)
private Long cust_id;
// 客户名称(公司名称)
private String cust_name;
// 客户信息来源
private String cust_source;
// 客户所属行业
private String cust_industry;
// 客户级别
private String cust_level;
// 固定电话
private String cust_phone;
// 移动电话
private String cust_mobile;
// 一对多,关联多的一方
private Set<LinkMan> linkMans = new HashSet<>(); public Set<LinkMan> getLinkMans() {
return linkMans;
} public void setLinkMans(Set<LinkMan> linkMans) {
this.linkMans = linkMans;
} public Long getCust_id() {
return cust_id;
} public void setCust_id(Long cust_id) {
this.cust_id = cust_id;
} public String getCust_name() {
return cust_name;
} public void setCust_name(String cust_name) {
this.cust_name = cust_name;
} public String getCust_source() {
return cust_source;
} public void setCust_source(String cust_source) {
this.cust_source = cust_source;
} public String getCust_industry() {
return cust_industry;
} public void setCust_industry(String cust_industry) {
this.cust_industry = cust_industry;
} public String getCust_level() {
return cust_level;
} public void setCust_level(String cust_level) {
this.cust_level = cust_level;
} public String getCust_phone() {
return cust_phone;
} public void setCust_phone(String cust_phone) {
this.cust_phone = cust_phone;
} public String getCust_mobile() {
return cust_mobile;
} public void setCust_mobile(String cust_mobile) {
this.cust_mobile = cust_mobile;
}
}

4、LinkMan类

package com.turtle.dao;

public class LinkMan {

    // 联系人编号(主键)
private Long lkm_id;
// 联系人姓名
private String lkm_name;
// 客户id
private String lkm_cust_id;
// 联系人性别
private Character lkm_gender;
// 联系人办公电话
private String lkm_phone;
// 联系人手机
private String lkm_mobile;
// 联系人邮箱
private String lkm_email;
// 联系人qq
private String lkm_qq;
// 联系人职
private String lkm_position;
// 联系人备注
private String lkm_memo;
// 多对一,保存一的一方信息
private Customer customer; public Customer getCustomer() {
return customer;
} public void setCustomer(Customer customer) {
this.customer = customer;
} public Long getLkm_id() {
return lkm_id;
} public void setLkm_id(Long lkm_id) {
this.lkm_id = lkm_id;
} public String getLkm_name() {
return lkm_name;
} public void setLkm_name(String lkm_name) {
this.lkm_name = lkm_name;
} public String getLkm_cust_id() {
return lkm_cust_id;
} public void setLkm_cust_id(String lkm_cust_id) {
this.lkm_cust_id = lkm_cust_id;
} public Character getLkm_gender() {
return lkm_gender;
} public void setLkm_gender(Character lkm_gender) {
this.lkm_gender = lkm_gender;
} public String getLkm_phone() {
return lkm_phone;
} public void setLkm_phone(String lkm_phone) {
this.lkm_phone = lkm_phone;
} public String getLkm_mobile() {
return lkm_mobile;
} public void setLkm_mobile(String lkm_mobile) {
this.lkm_mobile = lkm_mobile;
} public String getLkm_email() {
return lkm_email;
} public void setLkm_email(String lkm_email) {
this.lkm_email = lkm_email;
} public String getLkm_qq() {
return lkm_qq;
} public void setLkm_qq(String lkm_qq) {
this.lkm_qq = lkm_qq;
} public String getLkm_position() {
return lkm_position;
} public void setLkm_position(String lkm_position) {
this.lkm_position = lkm_position;
} public String getLkm_memo() {
return lkm_memo;
} public void setLkm_memo(String lkm_memo) {
this.lkm_memo = lkm_memo;
}
}

5、customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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.turtle.dao.Customer" table="cst_customer">
<!-- 建立OID与主键映射 -->
<id name="cust_id" column="cust_id">
<generator class="native"/>
</id>
<!-- 建立普通属性与数据库表字段映射 -->
<property name="cust_name" column="cust_name" />
<property name="cust_source" column="cust_source"/>
<property name="cust_industry" column="cust_industry"/>
<property name="cust_level" column="cust_level"/>
<property name="cust_phone" column="cust_phone"/>
<property name="cust_mobile" column="cust_mobile"/>
<!-- 配置一对多的映射:放置的多的一方的集合 -->
<!--
set标签 :
* name :多的一方的对象集合的属性名称。
* cascade:级联
* inverse:放弃外键维护权。
-->
<set name="linkMans" cascade="save-update" inverse="true">
<!--
key标签
* column:多的一方的外键的名称。
-->
<key column="lkm_cust_id"/>
<!--
one-to-many标签
* class :多的一方的类的全路径
-->
<one-to-many class="com.turtle.dao.LinkMan"/>
</set>
</class>
</hibernate-mapping>

6、linkMan.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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.turtle.dao.LinkMan" table="cst_linkman">
<!-- 建立OID与主键映射 -->
<id name="lkm_id" column="lkm_id">
<generator class="native"/>
</id>
<!-- 建立普通属性与表字段映射 -->
<property name="lkm_name"/>
<property name="lkm_gender"/>
<property name="lkm_phone"/>
<property name="lkm_mobile"/>
<property name="lkm_email"/>
<property name="lkm_qq"/>
<property name="lkm_position"/>
<property name="lkm_memo"/>
<!-- 配置多对一的关系:放置的是一的一方的对象 -->
<!--
many-to-one标签
* name :一的一方的对象的属性名称。
* class :一的一方的类的全路径。
* column :在多的一方的表的外键的名称。
-->
<many-to-one name="customer" class="com.turtle.dao.Customer" column="lkm_cust_id"/>
</class>
</hibernate-mapping>

7、Thibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernater_demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 配置Hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 可选配置================ -->
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- 配置C3P0连接池 -->
<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property> <!-- 设置事务隔离级别 -->
<property name="hibernate.connection.isolation">4</property>
<!-- 配置当前线程绑定的Session -->
<property name="hibernate.current_session_context_class">thread</property> <!-- 引入映射 -->
<mapping resource="com/turtle/dao/Customer.hbm.xml"/>
<mapping resource="com/turtle/dao/LinkMan.hbm.xml"/>
</session-factory>
</hibernate-configuration>

8、编写测试类

package com.turtle.test;

import com.turtle.dao.Customer;
import com.turtle.dao.LinkMan;
import com.turtle.utils.HibernateUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; public class TestHibernate_1 {
@Test
// 保存2个客户 和 3个联系人 并且建立好关系
public void demo1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 创建两个客户
Customer customer1 = new Customer();
customer1.setCust_name("王东");
Customer customer2 = new Customer();
customer2.setCust_name("赵洪"); // 创建三个联系人
LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("凤姐");
LinkMan linkMan2 = new LinkMan();
linkMan2.setLkm_name("如花");
LinkMan linkMan3 = new LinkMan();
linkMan3.setLkm_name("旺财"); // 设置关系:
linkMan1.setCustomer(customer1);
linkMan2.setCustomer(customer1);
linkMan3.setCustomer(customer2);
customer1.getLinkMans().add(linkMan1);
customer1.getLinkMans().add(linkMan2);
customer2.getLinkMans().add(linkMan3); // 保存数据:
session.save(linkMan1);
session.save(linkMan2);
session.save(linkMan3);
session.save(customer1);
session.save(customer2); tx.commit();
}
}

三、一对多的级联操作

级联指的是,操作一个对象的时候,是否会同时操作其关联的对象。

级联是有方向性

操作一的一方的时候,是否操作到多的一方

操作多的一方的时候,是否操作到一的一方

        <!-- 配置一对多的映射:放置的多的一方的集合 -->
<!--
set标签 :
* name :多的一方的对象集合的属性名称。
* cascade:级联
* inverse:放弃外键维护权。
-->
<set name="linkMans" cascade="save-update" inverse="true">
<!--
key标签
* column:多的一方的外键的名称。
-->
<key column="lkm_cust_id"/>
<!--
one-to-many标签
* class :多的一方的类的全路径
-->
<one-to-many class="com.turtle.dao.LinkMan"/>
</set>

测试代码:

package com.itheima.hibernate.demo1;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.itheima.hibernate.domain.Customer;
import com.itheima.hibernate.domain.LinkMan;
import com.itheima.hibernate.utils.HibernateUtils; /**
* 一对多的测试类
* @author jt
*
*/
public class HibernateDemo1 { @Test
// 保存2个客户 和 3个联系人 并且建立好关系
public void demo1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 创建两个客户
Customer customer1 = new Customer();
customer1.setCust_name("王东");
Customer customer2 = new Customer();
customer2.setCust_name("赵洪"); // 创建三个联系人
LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("凤姐");
LinkMan linkMan2 = new LinkMan();
linkMan2.setLkm_name("如花");
LinkMan linkMan3 = new LinkMan();
linkMan3.setLkm_name("旺财"); // 设置关系:
linkMan1.setCustomer(customer1);
linkMan2.setCustomer(customer1);
linkMan3.setCustomer(customer2);
customer1.getLinkMans().add(linkMan1);
customer1.getLinkMans().add(linkMan2);
customer2.getLinkMans().add(linkMan3); // 保存数据:
session.save(linkMan1);
session.save(linkMan2);
session.save(linkMan3);
session.save(customer1);
session.save(customer2); tx.commit();
} @Test
// 一对多关系只保存一边是否可以
public void demo2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Customer customer = new Customer();
customer.setCust_name("赵洪"); LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("如花");
customer.getLinkMans().add(linkMan);
linkMan.setCustomer(customer); // 只保存一边是否可以:不可以,报一个瞬时对象异常:持久态对象关联了一个瞬时态对象。
// session.save(customer);
session.save(linkMan); tx.commit();
} @Test
/**
* 级联保存或更新操作:
* * 保存客户级联联系人,操作的主体是客户对象,需要在Customer.hbm.xml中进行配置
* * <set name="linkMans" cascade="save-update">
*/
public void demo3(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Customer customer = new Customer();
customer.setCust_name("赵洪"); LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("如花"); customer.getLinkMans().add(linkMan);
linkMan.setCustomer(customer); session.save(customer); tx.commit();
} @Test
/**
* 级联保存或更新操作:
* * 保存联系人级联客户,操作的主体是联系人对象,需要在LinkMan.hbm.xml中进行配置
* * <many-to-one name="customer" cascade="save-update" class="com.itheima.hibernate.domain.Customer" column="lkm_cust_id"/>
*/
public void demo4(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Customer customer = new Customer();
customer.setCust_name("李兵"); LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("凤姐"); customer.getLinkMans().add(linkMan);
linkMan.setCustomer(customer); session.save(linkMan); tx.commit();
} @Test
/**
* 测试对象的导航
* * 前提:一对多的双方都设置cascade="save-update"
*/
public void demo5(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Customer customer = new Customer();
customer.setCust_name("李兵"); LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("凤姐");
LinkMan linkMan2 = new LinkMan();
linkMan2.setLkm_name("如花");
LinkMan linkMan3 = new LinkMan();
linkMan3.setLkm_name("芙蓉"); linkMan1.setCustomer(customer);
customer.getLinkMans().add(linkMan2);
customer.getLinkMans().add(linkMan3); // 双方都设置了cascade
// session.save(linkMan1); // 发送几条insert语句 4条
// session.save(customer); // 发送几条insert语句 3条
session.save(linkMan2); // 发送几条insert语句 1条 tx.commit();
} @Test
/**
* 级联删除:
* * 删除客户级联删除联系人,删除的主体是客户,需要在Customer.hbm.xml中配置
* * <set name="linkMans" cascade="delete">
*/
public void demo6(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 没有设置级联删除,默认情况:修改了联系人的外键,删除客户
/*Customer customer = session.get(Customer.class, 1l);
session.delete(customer);*/ // 删除客户,同时删除联系人
Customer customer = session.get(Customer.class, 1l);
session.delete(customer); tx.commit();
} @Test
/**
* 级联删除:
* * 删除联系人级联删除客户,删除的主体是联系人,需要在LinkMan.hbm.xml中配置
* * <many-to-one name="customer" cascade="delete">
*/
public void demo7(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 删除客户,同时删除联系人
LinkMan linkMan = session.get(LinkMan.class, 3l);
session.delete(linkMan); tx.commit();
} @Test
/**
* 将2号联系人原来归1号客户,现在改为2号客户
*/
public void demo8(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 查询2号联系人
LinkMan linkMan = session.get(LinkMan.class, 2l);
// 查询2号客户
Customer customer = session.get(Customer.class, 2l);
// 双向的关联
linkMan.setCustomer(customer);
customer.getLinkMans().add(linkMan); tx.commit();
} }

一对多设置了双向关联产生多余的SQL语句,使用inverse来解决

@Test
/**
* 区分cascade和inverse的区别
*/
public void demo9(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Customer customer = new Customer();
customer.setCust_name("李兵"); LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("凤姐"); customer.getLinkMans().add(linkMan); // 条件在Customer.hbm.xml上的set中配置了cascade="save-update" inverse="true"
session.save(customer); // 客户会插入到数据库,联系人也会插入到数据库,但是外键为null tx.commit();
}

四、Hibernate的多对多关联映射

1、SQL语句

-- 用户表
CREATE TABLE `sys_user` (
`user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`user_code` varchar(32) NOT NULL COMMENT '用户账号',
`user_name` varchar(64) NOT NULL COMMENT '用户名称',
`user_password` varchar(32) NOT NULL COMMENT '用户密码',
`user_state` char(1) NOT NULL COMMENT '1:正常,0:暂停',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 角色表
CREATE TABLE `sys_role` (
`role_id` bigint(32) NOT NULL AUTO_INCREMENT,
`role_name` varchar(32) NOT NULL COMMENT '角色名称',
`role_memo` varchar(128) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 中间表
CREATE TABLE `sys_user_role` (
`role_id` bigint(32) NOT NULL COMMENT '角色id',
`user_id` bigint(32) NOT NULL COMMENT '用户id',
PRIMARY KEY (`role_id`,`user_id`),
KEY `FK_user_role_user_id` (`user_id`),
CONSTRAINT `FK_user_role_role_id` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_user_role_user_id` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、代码结构

3、Role 类

package com.turtle.dao;

import java.util.HashSet;
import java.util.Set; /**
* 角色的实体
* @author jt
*CREATE TABLE `sys_role` (
`role_id` bigint(32) NOT NULL AUTO_INCREMENT,
`role_name` varchar(32) NOT NULL COMMENT '角色名称',
`role_memo` varchar(128) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; */
public class Role {
private Long role_id;
private String role_name;
private String role_memo;
// 一个角色被多个用户选择:
// 放置的是用户的集合
private Set<User> users = new HashSet<User>();
public Long getRole_id() {
return role_id;
}
public void setRole_id(Long role_id) {
this.role_id = role_id;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
public String getRole_memo() {
return role_memo;
}
public void setRole_memo(String role_memo) {
this.role_memo = role_memo;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
} }

4、User类

package com.turtle.dao;

import java.util.HashSet;
import java.util.Set; /**
* 用户的实体
* @author jt
*CREATE TABLE `sys_user` (
`user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`user_code` varchar(32) NOT NULL COMMENT '用户账号',
`user_name` varchar(64) NOT NULL COMMENT '用户名称',
`user_password` varchar(32) NOT NULL COMMENT '用户密码',
`user_state` char(1) NOT NULL COMMENT '1:正常,0:暂停',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; */
public class User {
private Long user_id;
private String user_code;
private String user_name;
private String user_password;
private String user_state;
// 设置多对多关系:表示一个用户选择多个角色?
// 放置的是角色的集合
private Set<Role> roles = new HashSet<Role>();
public Long getUser_id() {
return user_id;
}
public void setUser_id(Long user_id) {
this.user_id = user_id;
}
public String getUser_code() {
return user_code;
}
public void setUser_code(String user_code) {
this.user_code = user_code;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_password() {
return user_password;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
public String getUser_state() {
return user_state;
}
public void setUser_state(String user_state) {
this.user_state = user_state;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
} }

5、Role.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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.turtle.dao.Role" table="sys_role">
<!-- 建立OID与主键的映射 -->
<id name="role_id" column="role_id">
<generator class="native"/>
</id>
<!-- 建立普通属性与字段的映射 -->
<property name="role_name" column="role_name"/>
<property name="role_memo" column="role_memo"/>
<!-- 与用户的多对多的映射关系 -->
<!--
set标签
* name :对方的集合的属性名称。
* table :多对多的关系需要使用中间表,放的是中间表的名称。
-->
<set name="users" table="sys_user_role" cascade="save-update,delete" inverse="true">
<!--
key标签:
* column :当前的对象对应中间表的外键的名称。
-->
<key column="role_id"/>
<!--
many-to-many标签:
* class :对方的类的全路径
* column :对方的对象在中间表中的外键的名称。
-->
<many-to-many class="com.turtle.dao.User" column="user_id"/>
</set>
</class>
</hibernate-mapping>

6、User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!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.turtle.dao.User" table="sys_user">
<!-- 建立OID与主键的映射 -->
<id name="user_id" column="user_id">
<generator class="native"/>
</id>
<!-- 建立普通属性与字段映射 -->
<property name="user_code" column="user_code"/>
<property name="user_name" column="user_name"/>
<property name="user_password" column="user_password"/>
<property name="user_state" column="user_state"/>
<!-- 建立与角色的多对多的映射关系 -->
<!--
set标签
* name :对方的集合的属性名称。
* table :多对多的关系需要使用中间表,放的是中间表的名称。
-->
<set name="roles" table="sys_user_role" cascade="save-update,delete" >
<!--
key标签:
* column :当前的对象对应中间表的外键的名称。
-->
<key column="user_id"/>
<!--
many-to-many标签:
* class :对方的类的全路径
* column :对方的对象在中间表中的外键的名称。
-->
<many-to-many class="com.turtle.dao.Role" column="role_id"/>
</set>
</class>
</hibernate-mapping>

7、TestHibernate_2测试类

package com.turtle.test;

import com.turtle.dao.Role;
import com.turtle.dao.User;
import com.turtle.utils.HibernateUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; /**
* Hibernate的多对多的映射
* @author jt
*
*/
public class TestHibernate_2 { @Test
/**
* 保存多条记录:保存多个用户和角色
*/
public void demo1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 创建2个用户
User user1 = new User();
user1.setUser_name("赵洪");
User user2 = new User();
user2.setUser_name("李兵"); // 创建3个角色
Role role1 = new Role();
role1.setRole_name("研发部");
Role role2 = new Role();
role2.setRole_name("市场部");
Role role3 = new Role();
role3.setRole_name("公关部"); // 设置双向的关联关系:
user1.getRoles().add(role1);
user1.getRoles().add(role2);
user2.getRoles().add(role2);
user2.getRoles().add(role3);
role1.getUsers().add(user1);
role2.getUsers().add(user1);
role2.getUsers().add(user2);
role3.getUsers().add(user2); // 保存操作:多对多建立了双向的关系必须有一方放弃外键维护。
// 一般是被动方放弃外键维护权。
session.save(user1);
session.save(user2);
session.save(role1);
session.save(role2);
session.save(role3); tx.commit();
} @Test
/**
* 多对多的操作:
* * 只保存一边是否可以?不可以,瞬时对象异常
*/
public void demo2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 创建2个用户
User user1 = new User();
user1.setUser_name("赵洪"); // 创建3个角色
Role role1 = new Role();
role1.setRole_name("研发部"); // 设置双向的关联关系:
user1.getRoles().add(role1);
role1.getUsers().add(user1);
// 只保存用户:
// session.save(user1);
session.save(role1); tx.commit();
} @Test
/**
* 多对多的级联保存:
* * 保存用户级联保存角色。在用户的映射文件中配置。
* * 在User.hbm.xml中的set上配置 cascade="save-update"
*/
public void demo3(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 创建2个用户
User user1 = new User();
user1.setUser_name("赵洪"); // 创建3个角色
Role role1 = new Role();
role1.setRole_name("研发部"); // 设置双向的关联关系:
user1.getRoles().add(role1);
role1.getUsers().add(user1);
// 只保存用户:
session.save(user1); tx.commit();
} /**
* 多对多的级联保存:
* * 保存角色级联保存用户。在角色的映射文件中配置。
* * 在Role.hbm.xml中的set上配置 cascade="save-update"
*/
@Test
public void demo4(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 创建2个用户
User user1 = new User();
user1.setUser_name("李兵"); // 创建3个角色
Role role1 = new Role();
role1.setRole_name("公关部"); // 设置双向的关联关系:
user1.getRoles().add(role1);
role1.getUsers().add(user1);
// 只保存用户:
session.save(role1); tx.commit();
} /**
* 多对多的级联删除:
* * 删除用户级联删除角色
* * 在User.hbm.xml中的set上配置 cascade="delete"
*/
@Test
public void demo5(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 查询1号用户:
User user = session.get(User.class, 1l);
session.delete(user); tx.commit();
} /**
* 多对多的级联删除:
* * 删除角色级联删除用户
* * 在Role.hbm.xml中的set上配置 cascade="delete"
*/
@Test
public void demo6(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 查询2号角色:
Role role = session.get(Role.class, 2l);
session.delete(role); tx.commit();
} @Test
/**
* 给用户选择角色
*/
public void demo7(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 给1号用户多选2号角色
// 查询1号用户
User user = session.get(User.class, 1l);
// 查询2号角色
Role role = session.get(Role.class, 2l);
user.getRoles().add(role); tx.commit();
} @Test
/**
* 给用户改选角色
*/
public void demo8(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 给2号用户将原有的2号角色改为3号角色
// 查询2号用户
User user = session.get(User.class, 2l);
// 查询2号角色
Role role2 = session.get(Role.class, 2l);
Role role3 = session.get(Role.class, 3l);
user.getRoles().remove(role2);
user.getRoles().add(role3); tx.commit();
} @Test
/**
* 给用户改选角色
*/
public void demo9(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // 给2号用户删除1号角色
// 查询2号用户
User user = session.get(User.class, 2l);
// 查询2号角色
Role role = session.get(Role.class, 1l);
user.getRoles().remove(role); tx.commit();
}
}

3、Hibernate的多表关联的更多相关文章

  1. Hibernate 、多表关联映射-组件关联映射(component)

    组件关联映射可以将一些简小的数据与主题放在一个表中,例如firstName 和LastName这两个结合在一起可以组成一个名字,但是再分别将这两个再建一个表就不太合适了,这个时候可以用到组件关联映射: ...

  2. Hibernate 、多表关联映射 - 多对多关系映射(many-to-many)

    hibernate.cfg.xml: <hibernate-configuration> <session-factory name="sessionFactory&quo ...

  3. Hibernate 、多表关联映射 - 一对一关系映射(one- to-one)

    hibernate.cfg.xml: <hibernate-configuration> <session-factory name="sessionFactory&quo ...

  4. Hibernate 、多表关联映射-多对一关系(many-to-one)

    Hibernate.cfg.xml: <session-factory name="sessionFactory"> <property name="h ...

  5. hibernate进行多表联合查询

    hibernate是按照hql语句来进行查询的, 里面所使用的表名, 其实是实体类的名字, hql语句的写法并没有多大差别, 是在返回结果的时候要稍微做一些处理 //使用hibernate进行多表查询 ...

  6. Hibernate原生SQL查询多表关联,SQL语句要注意的问题

    Hibernate原生SQL查询多表关联,SQL语句要注意的问题 @for&ever 2009-9-4 系统环境: MySQL5.1 Hibernate3.3 有如下的假定: 实体类 Ques ...

  7. hibernate的基础学习--多表关联数据查询

    Hibernate共提供4种多表关联数据查询方式 OID数据查询+OGN数据查询方式 HQL数据查询方式 QBC数据查询方式 本地SQL查询方式(hibernate很少用) 1.OID数据查询+OGN ...

  8. Hibernate中表与表之间的关联多对多,级联保存,级联删除

    第一步:创建两个实体类:用户和角色实体类,多对多关系,并让两个实体类之间互相关联: 用户实体类: package com.yinfu.entity; import java.util.HashSet; ...

  9. 关于hibernate纯sql查询返回结果集的问题(hbm.xml中不写多表关联)

    相信用过hibernate的兄弟们都会因为多表复杂查询后,为返回的结果如何组装到一个VO中而烦恼不已.我也不停的为此而烦恼,但是在看了hibernate的transform后,感觉这个方法还挺管用的. ...

随机推荐

  1. [阅读笔记]EfficientDet

    EfficientDet 文章阅读 Google的网络结构不错,总是会考虑计算性能的问题,从mobilenet v1到mobile net v2.这篇文章主要对近来的FPN结构进行了改进,实现了一种效 ...

  2. iconv转换

    /////////////////////////////////////////////////////// #include <iconv.h> #include <stdlib ...

  3. Django中获取参数(路径,查询,请求头,请求体)

    一.通常HTTP协议向服务器传参有几种途径 : 提取URL的特定部分,如/weather/shanghai/2018,可以在服务器端的路由中用正则表达式截取: 查询字符串(query string), ...

  4. Python-类的几种调用方法

    一:实例 二:静态 可以调用类以外的变量,只限于此模块. 三:类方法 可以调用该类中定义的变量进行使用. 直接上代码

  5. js对文中某一处关键字自动检索和全文检索

    部分检索: 代码: <%@ page language="java" contentType="text/html; charset=utf-8" pag ...

  6. C sharp #005# 对象与对象变量

    饮水思源:金老师的自学网站 索引 自动装箱 “只读”对象 设定启动窗体 ShowDialog与Show 自动装箱 基本类型的变量值可以自动装箱到一个object对象中, 反过来,object对象也可以 ...

  7. Difference between JDK, JRE and JVM

    With Java programming language, the three terms i.e. JDK, JRE and JVM will always be there to unders ...

  8. 一起学Android之Animation

    本文以一个简单的小例子,简述在Android开发中,动画的简单应用,仅供学习分享使用. 概述 android提供了各种强大的apis,用于将动画应用到ui元素中,来丰富应用程序的功能和应用. 动画分类 ...

  9. ArcGIS api for JavaScript 3.27 在线浏览的一些小部件

    var navOption; var navToolbar;// 当前选择的操作 require( [ "esri/toolbars/navigation", "esri ...

  10. Thymeleaf常用语法:数据延迟加载

    在处理模板时,可以由模板逻辑决定是否加载数据,以提高性能.在Spring Boot控制器中设置数据时,使用LazyContextVariable可以实现这功能. 开发环境:IntelliJ IDEA ...