SSH框架之Hibernate第三篇
- 1.1 多表关系分析和创建.
- 1.1.1 表关系分析和创建
- 表数据和表数据之间可以存在的关系?
- 一对多的关系
- 客户和联系人
- 建立关系原则: 在多的一方创建一个字段,这个字段作为外键指向一的一方的主键
- 多对多的关系
- 用户和角色 用户: 角色:
- jack 员工
- rose 助教
- 班主任
- 建立关系原则:在外部创建一张中间表,这个中间表里至少需要2个字段,让这2个字段当成
- 是外键,指向各自表的主键
- 1.2 Hibernate 中的一对多关系映射
- 1.2.1 Hibernate 的一对多环境搭建
- 1.2.2 创建表和实体
- 创建表
- 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) NOT 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;
- 创建实体
- 客户端(一的一方)
- private Long cust_id;// 客户编号(主键)
- private String cust_name;//客户名称
- private String cust_source;//客户信息来源
- private String cust_industry;//客户所属行业
- private String cust_level;//客户级别
- private String cust_address;//客户联系地址
- private String cust_phone;//客户联系电话
- //有多的一方的集合
- private Set<LinkMan> linkmans = new HashSet<LinkMan>();
- 联系人端(多的一方)
- private Long lkm_id;//联系人编号(主键)
- private String lkm_name;//联系人姓名
- private String lkm_gender;//联系人性别
- private String lkm_phone;//联系人办公电话
- private String lkm_mobile;//联系人手机
- private String lkm_email;//联系人邮箱
- private String lkm_qq;//联系人QQ
- private String lkm_position;//联系人职位
- private String lkm_memo;//联系人备注
- private Customer customer ;
- 1.2.3 创建映射文件 创建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="cn.baidu.domain.Customer" table="cst_customer">
- <id name="cust_id" column="cust_id">
- <generator class="native"></generator>
- </id>
- <!-- 需要做类的其它属性和表的其它字段映射 -->
- <property name="cust_name" column="cust_name"></property>
- <property name="cust_source" column="cust_source"></property>
- <property name="cust_industry" column="cust_industry"></property>
- <property name="cust_level" column="cust_level"></property>
- <property name="cust_address" column="cust_address"></property>
- <property name="cust_phone" column="cust_phone"></property>
- <!-- 配置的一对多的关系映射 -->
- <!-- // name:set集合的名称 -->
- <!--inverse:true 放弃外键的维护权 -->
- <!-- cascade:级联 save-update:级联保存 -->
- <!-- lazy: 关联数据查询时(多表查询) 是否使用延迟加载 :true:使用 默认值 false:不使用-->
- <set name="linkmans" inverse="true" cascade="save-update,delete" lazy="false" >
- <!-- // column:外键的字段名称 -->
- <key column="lkm_cust_id"></key>
- <!-- // class: 多的一方的全限定名 -->
- <one-to-many class="cn.baidu.domain.LinkMan"/>
- </set>
- </class>
- </hibernate-mapping>
- 创建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="cn.baidu.domain.LinkMan" table="cst_linkman">
- <id name="lkm_id" column="lkm_id">
- <generator class="native"></generator>
- </id>
- <!-- 需要做类的其它属性和表的其它字段映射 -->
- <property name="lkm_name" column="lkm_name"></property>
- <property name="lkm_gender" column="lkm_gender"></property>
- <property name="lkm_phone" column="lkm_phone"></property>
- <property name="lkm_mobile" column="lkm_mobile"></property>
- <property name="lkm_email" column="lkm_email"></property>
- <property name="lkm_qq" column="lkm_qq"></property>
- <property name="lkm_position" column="lkm_position"></property>
- <property name="lkm_memo" column="lkm_memo"></property>
- <!-- 配置的一对多的关系映射 -->
- <!-- name:自己里面一的一方对象的属性名
- class: 一的一方的全限定名
- column:外键字段名称 -->
- <many-to-one cascade="save-update,delete" name="customer" class="cn.baidu.domain.Customer" column="lkm_cust_id"></many-to-one>
- </class>
- </hibernate-mapping>
- 1.2.5 双向维护产生多余SQL
- 解决这个问题:将一的一方的外键维护权放弃掉:<set name="linkMans" cascade="save-update,delete" inverse="true">
- 1.2.6 一对多的级联保存操作
- 级联 : 操作一个对象的时候,是否操作其关联对象.
- 级联操作是有方向性 :
- 保存客户级联保存联系人
- /**
- * 级联保存操作:
- * * 保存客户级联保存联系人
- * 在Customer.hbm.xml中<set>上配置cascade="save-update"
- */
- public void demo2(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- // 创建一个客户 和两个联系人
- Customer customer = new Customer();
- customer.setCust_name("郝宝强");
- LinkMan linkMan1 = new LinkMan();
- linkMan1.setLkm_name("宋喆");
- customer.getLinkMans().add(linkMan1);
- linkMan1.setCustomer(customer);
- session.save(customer);
- // session.save(linkMan1);
- transaction.commit();
- }
- 保存联系人级联保存客户
- @Test
- /**
- * 级联保存操作:
- * * 保存联系人级联保存客户在LinkMan.hbm.xml中<many-to-one>上配置cascade="save-update"
- */
- public void demo3(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- // 创建一个客户 和两个联系人
- Customer customer = new Customer();
- customer.setCust_name("郝强勇");
- LinkMan linkMan1 = new LinkMan();
- linkMan1.setLkm_name("马蓉");
- customer.getLinkMans().add(linkMan1);
- linkMan1.setCustomer(customer);
- //session.save(customer);
- session.save(linkMan1);
- transaction.commit();
- }
- 1.2.7 测试级联和对象导航(关联关系)的关系
- 测试导航和级联关系:
- 前提 : 双方都配置cascade = "save-update"
- * 联系人1关联客户 客户关联联系人2和3
- */
- public void demo6(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = 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);
- // session.save(linkMan1); // 问发送几条insert语句? 4条
- // session.save(customer); // 问发送几条insert语句? 3条
- session.save(linkMan2); // 问发送几条insert语句? 1条
- transaction.commit();
- }
- 1.2.8 1.2.8一对多的级联删除操作
- 删除客户级联删除联系人
- /**
- * 级联删除操作:
- * * 删除客户级联删除联系人
- * 在Customer.hbm.xml中<set>上配置cascade="delete"
- */
- public void demo4(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- Customer customer = session.get(Customer.class, 1l);
- session.delete(customer);
- transaction.commit();
- }
- 删除联系人级联删除客户(很少用)
- @Test
- /**
- * 级联删除操作:
- * * 删除联系人级联删除客户
- * 在LinkMan.hbm.xml中<many-to-one>上配置cascade="delete"
- */
- public void demo5(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- LinkMan linkMan = session.get(LinkMan.class, 1l);
- session.delete(linkMan);
- transaction.commit();
- }
- 1.3 Hibernate 中的多对多关系映射
- 1.3.1 搭建多对多开发环境
- 1.3.2 创建表
- 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=6 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;
- 1.3.3 创建实体
- 用户端
- public class User
- {
- private Long user_id;// '用户id',
- private String user_code;// '用户账号',
- private String user_name;// '用户名称',
- private String user_password;// '用户密码',
- private String user_state;// '1:正常,0:暂停',
- // 有角色的集合
- private Set<Role> roles=new HashSet();
- 角色端
- public class Role
- {
- private Long role_id;// 主键id
- private String role_name;// '角色名称',
- private String role_memo;// '备注',
- // 有用户的集合
- private Set<User> users=new HashSet();
- 1.3.4 创建映射
- 用户端
- <?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.baidu.hibernate.domain.User" table="sys_user">
- <!-- 建立oid与表的主键映射 -->
- <id name="user_id" column="user_id">
- <generator class="native"/>
- </id>
- <!-- 建立属性与表字段映射 -->
- <property name="user_code"/>
- <property name="user_name"/>
- <property name="user_password"/>
- <property name="user_state"/>
- <!-- 建立用户与角色的映射关系 -->
- <!--
- set标签:
- name属性:角色集合属性名称
- table属性:中间表的名称
- -->
- <set name="roles" table="sys_user_role">
- <!-- 用户端的在中间表的外键的名称 -->
- <key column="user_id"/>
- <!--
- 配置多对多映射
- many-to-many标签
- * class :另一端的实体类的全路径
- * column:另一端在中间表外键的名称
- -->
- <many-to-many class="com.baidu.hibernate.domain.Role" column="role_id"/>
- </set>
- </class>
- </hibernate-mapping>
- 角色端
- <?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.baidu.hibernate.domain.Role" table="sys_role">
- <!-- 建立oid与表的主键映射 -->
- <id name="role_id" column="role_id">
- <generator class="native"/>
- </id>
- <!-- 建立属性与表字段映射 -->
- <property name="role_name"/>
- <property name="role_memo"/>
- <!-- 建立关联关系映射 -->
- <set name="users" table="sys_user_role">
- <key column="role_id"/>
- <many-to-many class="com.baidu.hibernate.domain.User" column="user_id"/>
- </set>
- </class>
- </hibernate-mapping>
- 1.3.5 编写保存代码
- @Test
- /**
- * 保存数据
- */
- public void demo1(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- User user1 = new User();
- user1.setUser_name("小王");
- User user2 = new User();
- user2.setUser_name("小勇");
- Role role1 = new Role();
- role1.setRole_name("Java教研部");
- Role role2 = new Role();
- role2.setRole_name("前台");
- Role role3 = new Role();
- role3.setRole_name("学工部");
- user1.getRoles().add(role1);// 1 1
- user1.getRoles().add(role3);
- user2.getRoles().add(role3);
- role1.getUsers().add(user1);// 1 1
- role3.getUsers().add(user1);
- role3.getUsers().add(user2);
- session.save(user1);
- session.save(user2);
- session.save(role1);
- session.save(role2);
- session.save(role3);
- transaction.commit();
- }
- 1.3.6 级联保存操作(基本不会用)
- 保存用户级联保存角色.
- 保存角色级联保存用户.
- 1.3.7 级联删除操作(不会用-避免去使用) 用的默认删除
- 删除用户有级联时,会删除角色.
- 删除角色有级联时,会删除用户.
- 1.3.8 多对多其他相关操作(掌握)
- 给用户选择角色
- @Test
- /**
- * 给1号用户选择1号和2号角色
- */
- public void demo6(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- User user = session.get(User.class, 1l);
- Role role1 = session.get(Role.class, 1l);
- Role role2 = session.get(Role.class, 2l);
- user.getRoles().add(role1);
- user.getRoles().add(role2);
- transaction.commit();
- }
- 给用户删除角色
- @Test
- /**
- * 给1号删除2号角色
- */
- public void demo7(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- User user = session.get(User.class, 1l);
- Role role = session.get(Role.class, 2l);
- user.getRoles().remove(role);
- transaction.commit();
- }
- 给用户改选角色
- @Test
- /**
- * 给1号用户的1号角色修改为2号角色
- */
- public void demo8(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- User user = session.get(User.class, 1l);
- Role role1 = session.get(Role.class, 1l);
- Role role2 = session.get(Role.class, 2l);
- user.getRoles().remove(role1);
- user.getRoles().add(role2);
- transaction.commit();
- }
- 对象导航查询(多表关系查询)
- 有一个客户,获取他的联系人个数.
- Customer ct = session.get(Customer.class,1L);
- System.out.prinltn(ct.getLinkmas().size());
- 有一个联系人,获取他所属客户名称
- Linkman lm = session.get(Linkman.class,1L);
- System.out.println(lm.getCustomer().getCust_name());
- 延迟加载
- 提高hibernate效率,决定发送sql的时机.
- 分类:
- 类级别的延迟加载 (单表数据查询);
- Load
- 关联级别的延迟加载(多个对象的数据查询-多表数据查询)
- 通过一个对象查询其关联对象的数据.
- 在set标签上有一个属性 lazy 用来配置关联级别是否延迟加载的.
- 常用的值 :
- true : 使用延迟加载,默认值.
- false : 不使用延迟加载.
- 查询客户的同时,立马发送sql查询联系人.
- 在many-to-one 标签上也有一个属性 lazy 用来配置是否延迟加载的.
- 常用的值:
- false : 不使用延迟加载(记住)
- 查询联系人的时候,立马发送sql查询客户.
- 对象导航查询底层用的全是延迟加载机制.
- 总之(按需求) :
- 根据一的一方查多的一方的时候,使用延迟加载(默认值);
- 根据多的一方查一的一方一般使用立即加载,所以需要在多的一方的many-to-one标签配置 lazy=false;
- 级联操作和对象导航的关系? -----> 关联关系对级联操作的影响?
- 测试:
- 有一个客户和3个联系人
- 让联系人1关联客户
- 让客户关联联系人2和3
- 级联保存操作:
- save(联系人1) // 问: 会发送几条sql语句? 4
- save(客户) // 问:会发送几条sql语句? 3
- save(联系人2) // 问:会发送几条sql语句? 1
- 总结: 有影响
- 级联操作是在保存自己的时候,还会去找自己关联的对象数据来保存
- 对象导航的查询(关联关系的查询---多表数据的查询)
- 1 根据一个客户,查询这个客户下面所有联系人的数量
- 2 根据一个联系人,查询这个客户的名称
SSH框架之Hibernate第三篇的更多相关文章
- SSH框架之hibernate《三》
Hibernate03 一.多表设计 1.1多表设计的总则 问题:我们为什么要学习多表映射? 答: ...
- SSH框架之Spring第三篇
1.1 AOP概述 1.1.1 什么是AOP? AOP : 全称是Aspect Oriented Progamming既 : 面向切面编程.通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技 ...
- SSH框架之Hibernate第四篇
Hibernate中有两套实现数据库数据操作的方式 : hibernate前3天讲解的都是 : hibernate自己的操作方式(纯XML配置文件的方式) 另一种方式是基于JPA的操作方式(通过注解的 ...
- SSH框架之Struts2第三篇
1.3相关知识点 : 1.3.1 OGNL的表达式 : 1.3.1.1 什么是OGNL OGNL是Object-Graph Navigation Language的编写,它是一种功能强大的表达式语言, ...
- SSH框架中hibernate 出现 user is not mapped 问题
SSH框架中hibernate 出现 user is not mapped 问题 在做SSH框架整合时,在进行DAO操作时.这里就只调用了chekUser()方法.运行时报 user is ...
- SSH框架之-hibernate 三种状态的转换
一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...
- 【SSH三个框架】Hibernate第十篇基础:inverse属性具体解释
inverse后经常用于双向1-N在相关性.它也可以在使用N-N该协会,这里,例如用双1-N联想 或两个与各部门及工作人员,两javabean没有写. 首先,我们的员工看映射文件: <?xml ...
- SSH框架之Hibernate第二篇
1.1 持久化类的编写规则 1.1.1 什么是持久化类? 持久化类 : 与表建立了映射关系的实体类,就可以称之为持久化类. 持久化类 = Java类 + 映射文件. 1.1.2 持久化类的编写规则 ( ...
- 【SSH三大框架】Hibernate基础第二篇:编写HibernateUtil工具类优化性能
相对于上一篇中的代码编写HibernateUtil类以提高程序的执行速度 首先,仍然要写一个javabean(User.java): package cn.itcast.hibernate.domai ...
随机推荐
- CentOS7.2下部署zabbix4.0
整体部署采用centos7+php+apache+mariadb 基础环境配置优化 1. 关闭防火墙 [root@monitor_53 ~]$ systemctl stop firewalld [ro ...
- Python活力练习Day2
Day2:求1000以内的素数 #素数:除了1和它本身外,不能被其他自然数整除 #判断素数的方法:1).暴力法:从2到n-1每个数均整除进行判断 2).开根号法:从2到sqrt(n)均做整除判断( ...
- hadoop集群搭建教程
1. 相关软件准备: VMware-workstation-full-15.0.4-12990004.exe CentOS-7-x86_64-DVD-1810.iso jdk-8u231-linux- ...
- 最后的记忆——Spring BeanFactory
本文尝试分析一下Spring 的BeanFactory 体系的 接口设计,尝试理解为什么这么做,为什么接口这么设计.为什么这么去实现,为什么需要有这个方法,为什么 这样命名?接口.类.方法的 大致用途 ...
- Markdown 使用误区
新手写 Markdown 容易犯这么个错: 为了美观,使用标记. 例如 为了让一句话显示粗体,使用标题. 嫌 3 级标题字体太大,2 级标题子标题使用 4 级. 强调一个词,使用行内代码. -- 每个 ...
- rsync高级同步工具
1.什么是rsync rsync 是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据同步备份的优秀工具,rsync软件使用于 unix/linux/windows等多种操作系统平台. 2 ...
- net.sf.json将string转为map
背景 改一个以前的项目,项目里只有这个包,虽然我想用gson或者fastjson,然而并不想引入新的jar.于是使用这个,特此记录,感觉贼不好用. 实现代码 entity.getData()的值:{a ...
- WebShell代码分析溯源(八)
WebShell代码分析溯源(八) 一.一句话变形马样本 <?php $e=$_REQUEST['e'];$arr= array('test', $_REQUEST['POST']);uasor ...
- Consul-template+nginx实现自动负载均衡
前言 consul-template 是 Consul 的一个守护程序,使用 consul-template 可以方便快速的实现对 Consul Key/Value 存储系统的访问,可以从 KV 系统 ...
- day 26-1 property、绑定与非绑定方法
property property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值:就是把一个函数属性的访问方式变成像访问数据属性的方式一样. 我们首先来看一个对比效果 例一:在调用 bmi ...