系统管理模块_部门管理_设计(映射)本模块中的所有实体并总结设计实体的技巧_懒加载异常问题_树状结构...
系统管理模块_部门管理_设计本模块中的所有实体并总结设计实体的技巧
设计实体流程
1,有几个实体?
一般是一组增删改查对应一个实体。
2,实体之间有什么关系?
一般是页面引用了其他的实体时,就表示与这个实体有关联关系。
3,每个实体中都有什么属性?
1,主键。推荐使用代理主键
2,关联关系属性。在类图中,关联关系是一条线,有两端,每一端对应一个表达此关联关系的属性。有几个端指向本类,本类中就有几个关联关系属性。
3,一般属性。分析所有有关的页面,找出表单中要填写的或是在显示页面中要显示的信息等。
4,特殊属性:为解决某问题而设计的属性。比如要显示年龄,但不会设计一个int age字段,而是一个Date birthday字段,年龄是在显示时实时计算出来的。
完成
Department.Java
public class Department {private Long id;private String name;private String description;private Set<User> users = new HashSet<User>();private Department parent;private Set<Department> children = new HashSet<Department>();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 getDescription() {return description;}public void setDescription(String description) {this.description = description;}public Set<User> getUsers() {return users;}public void setUsers(Set<User> users) {this.users = users;}public Department getParent() {return parent;}public void setParent(Department parent) {this.parent = parent;}public Set<Department> getChildren() {return children;}public void setChildren(Set<Department> children) {this.children = children;} }
Role.java
public class Role {private Long id;private String name;private String description;private Set<User> users = new HashSet<User>();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 getDescription() {return description;}public void setDescription(String description) {this.description = description;}public Set<User> getUsers() {return users;}public void setUsers(Set<User> users) {this.users = users;} }
User.java
public class User {private Long id;private Department department;private Set<Role> roles = new HashSet<Role>();private String loginName; //登录名private String password; //密码 private String name; //真实姓名private String gender; //性别private String phoneNumber; //电话号码private String email; //电子邮件private String description; //说明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 Department getDepartment() {return department;}public void setDepartment(Department department) {this.department = department;}public Set<Role> getRoles() {return roles;}public void setRoles(Set<Role> roles) {this.roles = roles;}public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getPhoneNumber() {return phoneNumber;}public void setPhoneNumber(String phoneNumber) {this.phoneNumber = phoneNumber;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;} }
系统管理模块_部门管理_映射本模块中的所有实体并总结映射实体的技巧
设计实体、映射文件、建表
Hibernate实体映射流程
多对一 |
<many-to-one name=“” class=“” column=“”/> |
一对多 (Set) |
<set name=""> <key column=""></key> <one-to-many class=""/> </set> |
多对多 (Set)比一对多多一个table和column属性 |
<set name="" table=""> <key column=""></key> <many-to-many class="" column=""/> </set> |
1,写注释
格式为:?属性,表达的是本对象与?的?关系。
例:“department属性,本对象与Department的多对一”
2,拷模板:
一对多多对多模板
3,填空:
name属性:属性名(写注释中的第1问号)
class属性:关联的实体类型(写注释中的第2个问号)
column属性:
<many-to-one column="..">:一般可以写成属性名加Id后缀,如属性为department,则column值写成departmentId。
一对多中的<key column="..">:从关联的对方(对方是多对一)映射中把column值拷贝过来。
多对多中的<set name="users" table="">:table属性写两个表的连接,比如itcast_user_role
多对多中的<key column=“..”>:一般可以写成本对象的名加Id后缀,如本对象名为User,则写为userId。
多对多中的<many-to-many column=“..”>:一般可以写为关联对象的名称加Id后缀。
4,运行SpringTest.java中的testSessionFactory()测试方法无报错,成功建表即可完成
完成
Departmnet.hbm.xml
<hibernate-mapping package="cn.itcast.oa.domain"><class name="Department" table="itcast_department"><id name="id"><generator class="native" /></id><property name="name"></property><property name="description"></property><!-- users属性,本类与User的一对多 --><set name="users"><key column="departmentId"></key><one-to-many class="User"/></set><!-- parent属性,本类与Department(上级)的多对一 --><!-- name属性名 、class关联的实体类型 、column外键--><many-to-one name="parent" class="Department" column="parentId"></many-to-one><!-- children属性,本类与Department(下级)的一对多 --><set name="children"><key column="parentId"></key><one-to-many class="Department"/></set></class> </hibernate-mapping>
Role.hbm.xml
<hibernate-mapping package="cn.itcast.oa.domain"><class name="Role" table="itcast_role"><id name="id"><generator class="native" /></id><property name="name"></property><property name="description"></property><!-- users属性,本类与User的多对多 --><set name="users" table="itcast_user_role"><key column="roleId"></key><many-to-many class="User" column="userId"></many-to-many></set></class> </hibernate-mapping>
User.hbm.xml
<hibernate-mapping package="cn.itcast.oa.domain"><class name="User" table="itcast_user"><id name="id"><generator class="native" /></id><property name="loginName"/><property name="password"/><property name="name"/><property name="gender"/><property name="phoneNumber"/><property name="email"/><property name="description"/><!-- department属性,本类与Department的多对一 --><!-- name属性名 、class关联的实体类型 、column外键--><many-to-one name="department" class="Department" column="departmentId"></many-to-one><!-- roles属性,本类与Role的多对多 --><set name="roles" table="itcast_user_role"><key column="userId"></key><many-to-many class="Role" column="roleId"></many-to-many></set></class> </hibernate-mapping>
系统管理模块_部门管理_在增删改功能中增加对上级部门的处理
添加上级部门,添加和修改删除也要跟着改变,对列表没有影响
1. 转到添加页面时,把上级部门的信息显示出来
对addUI()方法修改
2. 选择某个部门的时候与上级部门关联起来
怎么知道选哪个部门了呢,这时要在DepartmentAction中添加字段,实体就不要随便修改
private Long parentId;并提供setget方法
无论在javabean中还是在Action中都可以传递过来
删除上级部门采用级联删除要在Department.hbm.xml文件中配置,子孙部门就统统删除掉了
显示顶级部门
List.jsp页面也要有修改,一点击就显示上一层
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
懒加载异常
具体步骤:
1. 对Action类进行修改
DepartmentAction.java
@Controller @Scope("prototype") public class DepartmentAction extends ActionSupport implements ModelDriven<Department>{//这里也需要转递参数id,名称和说明,实体里都有了。所以要实现ModelDriven,封装表单当中传递过来的参数//有接口有实现类,想用它就创建,采用@Resource注入 @Resourceprivate DepartmentService departmentService;private Long parentId;private Department model = new Department();public Department getModel() {return model;}/*** 列表*/public String list() throws Exception {List<Department> departmentList = departmentService.findAll();//findAll()在DepartmentService接口中创建if(parentId == null) {//等于空就查询顶级//显示顶级部门,设置查询顶级列表即可departmentList = departmentService.findTopList();}else {//查询子部门列表,告诉他我的IddepartmentList = departmentService.findChildren(parentId);}//顶级部门与子部门集合在一起 ActionContext.getContext().put("departmentList", departmentList);//放在map里面方便拿,#号获取return "list";}/*** 删除*/public String delete() throws Exception {departmentService.delete(model.getId());//delete()在DepartmentService接口中创建return "toList";}/*** 添加页面*/public String addUI() throws Exception {//准备数据,DepartmnetListList<Department> departmentList = departmentService.findAll();ActionContext.getContext().put("departmentList", departmentList);//一般放在值栈中的map,获取用#号获取方便return "saveUI";}/*** 添加*/public String add() throws Exception {//封装到对象中/*Department department = new Department();department.setName(model.getName());department.setDescription(model.getDescription());//保存到数据库中departmentService.save(department);*///关联上级部门Department parent = departmentService.getById(parentId);//根据id查询出相应的对象再关联关系 model.setParent(parent);//添加的方法可以简化成一行代码 departmentService.save(model);return "toList";}/*** 修改页面*/public String editUI() throws Exception {//准备数据,DepartmnetListList<Department> departmentList = departmentService.findAll();ActionContext.getContext().put("departmentList", departmentList);//一般放在值栈中的map,获取用#号获取方便//准备回显的数据Department department =departmentService.getById(model.getId());//把回显的数据的id告诉我ActionContext.getContext().getValueStack().push(department);//把它放到栈顶就能回显if(department.getParent() != null) {//回显上级部门parentId = department.getParent().getId();//把数据给parentId }return "saveUI";}/*** 修改*/public String edit() throws Exception {//1.从数据库中取出原对象Department department = departmentService.getById(model.getId());//2.设置要修改的属性 department.setName(model.getName());department.setDescription(model.getDescription());department.setParent(departmentService.getById(parentId));//设置所属的上级部门//3.更新到数据库中 departmentService.update(department);return "toList";}public void setParentId(Long parentId) {this.parentId = parentId;}public Long getParentId() {return parentId;} }
对Service实现类进行修改
DepartmentServiceImpl.java
//在Action中要调用Service,要写下面两个注解 @Service @Transactional //业务层要管理实务,控制开关事务 @SuppressWarnings("unchecked") public class DepartmentServiceImpl implements DepartmentService{//Service里要调用Dao,得到它通过注入 @Resourceprivate DepartmentDao departmentDao;@Resourceprivate SessionFactory sessionFactory;public List<Department> findTopList() {return sessionFactory.getCurrentSession().createQuery(// "FROM Department d WHERE d.parent IS NULL")// .list();}public List<Department> findChildren(Long parentId) {return sessionFactory.getCurrentSession().createQuery(// "FROM Department d WHERE d.parent.id=?")// .setParameter(0, parentId)//这里的索引0表示上面的问号 .list();}public List<Department> findAll() {return departmentDao.findAll();}public void delete(Long id) {departmentDao.delete(id);}public void save(Department model) {departmentDao.save(model);}public Department getById(Long id) {return departmentDao.getById(id);}public void update(Department department) {departmentDao.update(department);} }
Service接口中定义两个新的方法
DepartmentService.java
//接口中只有方法的声明,没有方法的实现 public interface DepartmentService {List<Department> findAll();void delete(Long id);void save(Department model);Department getById(Long id);void update(Department department);//查询顶级部门列表List<Department> findTopList();//查询子部门列表List<Department> findChildren(Long parentId);}
对BaseDaoImpl.java中的getById()方法修改
public T getById(Long id) {if(id == null) {return null;}else{return (T) getSession().get(clazz, id);}}
处理懒加载问题
对Department.hbm.xml修改,添加lazy属性
<!-- parent属性,本类与Department(上级)的多对一 --><!-- name属性名 、class关联的实体类型 、column外键--><many-to-one name="parent" class="Department" column="parentId" lazy="false"></many-to-one><!-- children属性,本类与Department(下级)的一对多 --><set name="children" cascade="delete" lazy="false"><key column="parentId"></key><one-to-many class="Department"/></set>
list.jsp
saveUI.jsp
系统管理模块_部门管理_处理三个细节问题
点新建时默认显示上级部门,表单回显显示Action里的parentId的值,parentId属性怎么有值,传参数封装
增加返回上一级按钮,要不然后退会回到之前添加和修改的页面
//把parent对象事先放到map中,列表通过#号拿到parent对象Department parent = departmentService.getById(parentId);ActionContext.getContext().put("departmentList", departmentList);
新建或修改后,回来不是在列表,解决:让它增删改之后回到列表页面
因为在struts.xml中没有带参数
这门在重定向到其他页面的时候,很有可能带些参数,可以使用ognl表达式
改进:使用OpenSessionInViewFilter方案解决Hibernate懒加载异常的问题
之前的解决办法是把懒加载关掉,懒加载好的特性就没用了
懒加载有点:可以适当的提高效率
把懒加载打开:去掉这个属性lazy="false"再访问会抛异常
想用懒加载,但又想不抛异常
Web程序中的懒加载异常说明及解决方案
出现:一个请求来的时候,先执行Action,再执行结果。在执行Action的时候里面调用Service,Service做真正的业务处理,开始执行Service方法的时候,开始事务,Service结束的时候事务提交或回滚session就会关闭。我们在Service中查询数据,在结果页面显示数据,在前面加载的时候没有懒加载属性,页面的时候用到了懒加载的属性,所以就出现懒加载异常,把懒加载关闭这个方法不好用。没有session我们就让他有session,不把session关掉,查询的时候可以不用事务,有session连接就行,在页面处理完之后再关,session早晚要关,我们在过滤器或拦截器里关session
使用OpenSessionInViewFilter解决解决懒加载问题,在web.xml中配置,一定要配置在struts2之前:<!-- 配置Spring的用于解决懒加载问题的过滤器 --><filter><filter-name>OpenSessionInViewFilter</filter-name><filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class></filter><filter-mapping><filter-name>OpenSessionInViewFilter</filter-name><url-pattern>*.action</url-pattern></filter-mapping>
树状结构显示之讲解递归练习题并说明写递归代码的技巧
树状结构的显示说明
/*** 结构如下:* * ┣市场部* ┣宣传部* ┣业务部* ┣业务一部* ┣业务二部* ┣开发部* ┣开发一部* ┣开发二部* * @return 所有最顶层的部门的列表*/public static List<Department> findTopLevelDepartmentList() {Department dept_1_1 = new Department();dept_1_1.setId(new Long(11));dept_1_1.setName("宣传部");Department dept_1_2 = new Department();dept_1_2.setId(new Long(12));dept_1_2.setName("业务部");Department dept_1_2_1 = new Department();dept_1_2_1.setId(new Long(121));dept_1_2_1.setName("业务一部");Department dept_1_2_2 = new Department();dept_1_2_2.setId(new Long(122));dept_1_2_2.setName("业务二部");dept_1_2_1.setParent(dept_1_2);dept_1_2_2.setParent(dept_1_2);Set<Department> children_0 = new LinkedHashSet<Department>();children_0.add(dept_1_2_1);children_0.add(dept_1_2_2);dept_1_2.setChildren(children_0);// ================================Department dept_1 = new Department();dept_1.setId(new Long(1));dept_1.setName("市场部");dept_1_1.setParent(dept_1);dept_1_2.setParent(dept_1);Set<Department> children_1 = new LinkedHashSet<Department>();children_1.add(dept_1_1);children_1.add(dept_1_2);dept_1.setChildren(children_1);// ---Department dept_2_1 = new Department();dept_2_1.setId(new Long(21));dept_2_1.setName("开发一部");Department dept_2_2 = new Department();dept_2_2.setId((new Long(22)));dept_2_2.setName("开发二部");Department dept_2 = new Department();dept_2.setId(new Long(2));dept_2.setName("开发部");dept_2_1.setParent(dept_2);dept_2_2.setParent(dept_2);Set<Department> children_2 = new LinkedHashSet<Department>();children_2.add(dept_2_1);children_2.add(dept_2_2);dept_2.setChildren(children_2);// ---List<Department> depts = new ArrayList<Department>();depts.add(dept_1);depts.add(dept_2);return depts;} 市场部 宣传部 业务部 业务一部 业务二部 开发部 开发一部 开发二部
/*** 练习一:打印所有顶层部门及其子孙部门的信息(名称) 提示:假设有一个 打印部门树 的信息 的方法* * 要求打印如下效果:* * 市场部* 宣传部* 业务部* 业务一部* 业务二部* 开发部* 开发一部* 开发二部*/@Testpublic void printAllDepts_1() {List<Department> topList = findTopLevelDepartmentList();/*// 方式一for (Department top : topList) {showTree(top);//调用自己}*/// 方式二 showTreeList(topList);}/*** 显示一颗部门树中所有节点的信息* * @param top* 树的顶点(根节点)*/private void showTree(Department top) {// 顶点 System.out.println(top.getName());// 子树for (Department child : top.getChildren()) {showTree(child);}}/*** 显示多颗树的所有节点的信息* @param topList*/private void showTreeList(Collection<Department> topList) {for (Department top : topList) {// 顶点 System.out.println(top.getName());// 子树 showTreeList(top.getChildren());}}
/*** 练习二:打印所有顶层部门及其子孙部门的信息(名称),用不同的缩进表示层次(使用全角空格)。<br>* 子部门的名称前比上级部门多一个空格,最顶层部门的名字前没有空格。 提示:假设有一个打印部门集合中所有部门信息的方法* * 要求打印如下效果:* * ┣市场部* ┣宣传部* ┣业务部* ┣业务一部* ┣业务二部* ┣开发部* ┣开发一部* ┣开发二部*/@Testpublic void printAllDepts_2() {List<Department> topList = findTopLevelDepartmentList();showTreeList_2(topList, "┣");}// 显示树private void showTreeList_2(Collection<Department> topList, String prefix) {for (Department top : topList) {// 顶点System.out.println(prefix + top.getName());// 子树showTreeList_2(top.getChildren(), " " + prefix);}}
转载于:https://www.cnblogs.com/justdoitba/p/7772324.html
系统管理模块_部门管理_设计(映射)本模块中的所有实体并总结设计实体的技巧_懒加载异常问题_树状结构...相关推荐
- java懒加载的原理_每天使用 Spring 框架,那你知道 lazy-init 懒加载原理吗?
普通的bean的初始化是在容器启动初始化阶段执行的,而被lazy-init修饰的bean 则是在从容器里第一次进行context.getBean("")时进行触发. Spring ...
- OA项目10:部门管理的三个细节问题的解决及处理懒加载问题
首注:本学习教程为传智播客汤阳光讲师所公布的免费OA项目视频我的文字版实践笔记,本人用此来加强巩固自己开发知识,如有网友转载,请注明.谢谢. 一 部门管理遗留三个细节问题,及其处理方法: 1.当选择了 ...
- oracle 树状结构一直出现不了_深入解析Oracle ASSM 段头块(PAGETABLE SEGMENT HEADER)结构...
一.概念介绍 Oracle ASSM(Automatic Segment Space Managed)使用位图来管理数据库中的空间,具有管理简单.高并发等优点,ASSM的整体结构是3层位图块+数据块, ...
- html加载富文本_富文本图片懒加载解决方案
图片懒加载,作为性能优化的一部分,想必我们并不陌生. 在React.Vue项目中,我们都可以引入对应的NPM包处理图片懒加载,如 lazyload.react-lazyload.vue-lazyloa ...
- java部门管理_系统管理模块_部门管理_实现基本的增删改查功能
系统管理模块_部门管理1_实现基本的增删改查功能 先不考虑上级部门 设计实体.表 1.设计实体 Department.java public classDepartment {privateLong ...
- mysql树状数据结构_树状结构的数据表如何设计?
使用Modified Preorder Tree简直是必须的.网上可以搜一下modified preorder tree travesal找到相关资料.参考 http://www.sitepoint. ...
- python调用按键精灵插件_【一日一技】python模块的懒加载
在编写python项目时,通常将需要使用的模块直接通过import关键字导入到项目中,如果后续逻辑变动了,这个模块不需要使用,此时这个模块就白引入了,此时可以利用 import 方法实现模块的懒加载. ...
- 服务器图片加载慢_页面提高性能利器_懒加载
哈喽,艾瑞巴蒂,现在搜狗商城产品需求已经趋于稳定,已经开始逐步的着手进行页面的性能提升工作.这不最近小编正在进行"页面懒加载需求"的功能测试.小编第一次听说这个名词,让我们一起了解 ...
- dll文件懒加载_前端性能优化
# 前端性能优化 写在最前面:下面都是我对webpack的一些性能优化,想系统的学习性能优化方面的知识 推荐大家看看这本书 很系统 感觉面试也能如鱼得水 ## 构建优化 ### webpack优化 ( ...
最新文章
- mysql触发器错误信息_MySQL 触发器错误_MySQL
- 如何查看mysql索引
- 异常处理_月隐学python第19课
- Redis 持久化——混合持久化
- Jmeter之线程组(默认)
- 为什么大多数私人企业无法做大做强?
- Java版SLG游戏《竜退治2》
- R语言各个包里面的数据集
- python3.5 3.6_centos7安装较高版本python3.5/3.6
- 通信感知一体化概述(IMT-2030 6G)
- 1602-LiquidCrystal库
- Samsung ML-1640/1641/1645/2240/2241/2245/scx4200/4300/4623/4824/4828免费清零软件2.1.2完全版
- 分享几款强大的录音软件,厉害炸了!
- SQL 求同比 环比
- Python基础入门:(一)从变量到异常处理 --阿里云天池
- [转载]关于字体的一些常识
- 陶哲轩实分析 命题7.2.9 绝对收敛判别法
- python3.7通过itchat方式登录微信给好友发送天气信息
- Day01.二分查找、移除元素
- 【unity3d】如何学习unity3d