博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
系统管理模块_部门管理_设计(映射)本模块中的所有实体并总结设计实体的技巧_懒加载异常问题_树状结构...
阅读量:6305 次
发布时间:2019-06-22

本文共 16789 字,大约阅读时间需要 55 分钟。

系统管理模块_部门管理_设计本模块中的所有实体并总结设计实体的技巧

设计实体流程

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
users = new HashSet
(); private Department parent; private Set
children = new HashSet
(); 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
getUsers() { return users; } public void setUsers(Set
users) { this.users = users; } public Department getParent() { return parent; } public void setParent(Department parent) { this.parent = parent; } public Set
getChildren() { return children; } public void setChildren(Set
children) { this.children = children; }}

Role.java

public class Role {    private Long id;    private String name;    private String description;        private Set
users = new HashSet
(); 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
getUsers() { return users; } public void setUsers(Set
users) { this.users = users; }}

User.java

public class User {    private Long id;    private Department department;    private Set
roles = new HashSet
(); 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
getRoles() { return roles; } public void setRoles(Set
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

Role.hbm.xml

User.hbm.xml

系统管理模块_部门管理_在增删改功能中增加对上级部门的处理

添加上级部门,添加和修改删除也要跟着改变,对列表没有影响

 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
{
//这里也需要转递参数id,名称和说明,实体里都有了。所以要实现ModelDriven,封装表单当中传递过来的参数 //有接口有实现类,想用它就创建,采用@Resource注入 @Resource private DepartmentService departmentService; private Long parentId; private Department model = new Department(); public Department getModel() { return model; } /** * 列表 */ public String list() throws Exception { List
departmentList = departmentService.findAll();//findAll()在DepartmentService接口中创建 if(parentId == null) {
//等于空就查询顶级 //显示顶级部门,设置查询顶级列表即可 departmentList = departmentService.findTopList(); }else { //查询子部门列表,告诉他我的Id departmentList = 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 { //准备数据,DepartmnetList List
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 { //准备数据,DepartmnetList List
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,得到它通过注入    @Resource    private DepartmentDao departmentDao;        @Resource    private SessionFactory sessionFactory;        public List
findTopList() { return sessionFactory.getCurrentSession().createQuery(// "FROM Department d WHERE d.parent IS NULL")// .list(); } public List
findChildren(Long parentId) { return sessionFactory.getCurrentSession().createQuery(// "FROM Department d WHERE d.parent.id=?")// .setParameter(0, parentId)//这里的索引0表示上面的问号 .list(); } public List
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
findAll(); void delete(Long id); void save(Department model); Department getById(Long id); void update(Department department); //查询顶级部门列表 List
findTopList(); //查询子部门列表 List
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属性

     

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之前:    
OpenSessionInViewFilter
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
OpenSessionInViewFilter
*.action

树状结构显示之讲解递归练习题并说明写递归代码的技巧

树状结构的显示说明

  /**     * 结构如下:     *      * ┣市场部     *    ┣宣传部     *    ┣业务部     *       ┣业务一部     *       ┣业务二部     * ┣开发部     *    ┣开发一部     *    ┣开发二部     *      * @return 所有最顶层的部门的列表     */    public static List
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
children_0 = new LinkedHashSet
(); 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
children_1 = new LinkedHashSet
(); 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
children_2 = new LinkedHashSet
(); children_2.add(dept_2_1); children_2.add(dept_2_2); dept_2.setChildren(children_2); // --- List
depts = new ArrayList
(); depts.add(dept_1); depts.add(dept_2); return depts; }市场部宣传部业务部业务一部业务二部开发部开发一部开发二部
  /**     * 练习一:打印所有顶层部门及其子孙部门的信息(名称) 提示:假设有一个 打印部门树 的信息 的方法     *      * 要求打印如下效果:     *      * 市场部     * 宣传部     * 业务部     * 业务一部     * 业务二部     * 开发部     * 开发一部     * 开发二部     */    @Test    public void printAllDepts_1() {        List
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
topList) { for (Department top : topList) { // 顶点 System.out.println(top.getName()); // 子树 showTreeList(top.getChildren()); } }
/**     * 练习二:打印所有顶层部门及其子孙部门的信息(名称),用不同的缩进表示层次(使用全角空格)。
* 子部门的名称前比上级部门多一个空格,最顶层部门的名字前没有空格。 提示:假设有一个打印部门集合中所有部门信息的方法 * * 要求打印如下效果: * * ┣市场部 * ┣宣传部 * ┣业务部 * ┣业务一部 * ┣业务二部 * ┣开发部 * ┣开发一部 * ┣开发二部 */ @Test public void printAllDepts_2() { List
topList = findTopLevelDepartmentList(); showTreeList_2(topList, "┣"); } // 显示树 private void showTreeList_2(Collection
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

你可能感兴趣的文章
hdu 5471(状压DP or 容斥)
查看>>
oracle.jdbc.driver.OracleDriver和oracle.jdbc.OracleDriver这两个驱动的区别
查看>>
NSQ部署
查看>>
git常用命令记录
查看>>
IBM发布新一代云计算工具包MobileFirst Foundation
查看>>
唯品会HDFS性能挑战和优化实践
查看>>
大规模学习该如何权衡得失?解读NeurIPS 2018时间检验奖获奖论文
查看>>
大厂前端高频面试问题与答案精选
查看>>
我们用5分钟写了一个跨多端项目
查看>>
Visual Studio 15.4发布,新增多平台支持
查看>>
有赞透明多级缓存解决方案(TMC)设计思路
查看>>
如何设计高扩展的在线网页制作平台
查看>>
Git 2.5增加了工作树、改进了三角工作流、性能等诸多方面
查看>>
Swift 5将强制执行内存独占访问
查看>>
中台之上(二):为什么业务架构存在20多年,技术人员还觉得它有点虚?
查看>>
深度揭秘腾讯云低功耗广域物联网LPWAN 技术及应用
查看>>
与Jeff Sutherland谈敏捷领导力
查看>>
More than React(四)HTML也可以静态编译?
查看>>
React Native最佳学习模版- F8 App开源了
查看>>
云服务正在吞噬世界!
查看>>