一.回顾
1.项目首页面执行过程分析
2.顶部菜单点击后,为什么左侧,中间区域会改变
3.为什么左侧菜单点击后,显示结果在中间区域
4.DAO分析
5.Page分页组件
6.编写及酉己置Service, Action
7完成DeptAction类的CRUD操作
8.BaseAction 的类
二.DeptAction 更新&删除
Dept .java 父部门 、用户
public class Dept implements Serializable {
private String id;
private Set<User> users = new HashSet<User>(0);//部门与用户 一对多
private String deptName;//部门名称
private Dept parent; //父部门 自关联 子部门与父部门 多对一
private Integer state;//状态 1代表启用 0代表停用
public String getId() {
Dept.hbm.xml 子部门与父部门/多对一 部门与用户 一对多
<hibernate-mapping package="cn.itcast.jk.domain">
<class name="Dept" table="DEPT_P">
<id name="id" column="DEPT_ID">
<generator class="uuid"></generator>
</id>
<property name="deptName" column="DEPT_NAME"></property>
<property name="state" column="STATE"></property>
<!-- 自关联 子部门与父部门 多对一 -->
<many-to-one name="parent" class="Dept" column="PARENT_ID"></many-to-one>
<!-- private Set<User> users = new HashSet<User>(0);//部门与用户 一对多 -->
<set name="users">
<key column="DEPT_ID"></key>
<one-to-many class="User"/>
</set>
</class>
</hibernate-mapping>
界面-列表
jDeptUpdate.jsp 分页,列表
<table id="ec_table" class="tableRegion" width="98%" >
<thead>
<tr>
<td class="tableHeader"><input type="checkbox" name="selid" onclick="checkAll('id',this)"></td>
<td class="tableHeader">序号</td>
<td class="tableHeader">编号</td>
<td class="tableHeader">上级</td>
<td class="tableHeader">名称</td>
</tr>
</thead>
<tbody class="tableBody" >
${links }
<c:forEach items="${results }" var="dept" varStatus="st">
<tr class="odd" onmouseover="this.className='highlight'" onmouseout="this.className='odd'" >
<td><input type="checkbox" name="id" value="${dept.id }"/></td>
<td>${st.count }</td>
<td>${dept.id }</td>
<td>${dept.parent.deptName }</td>
<td><a href="deptAction_toview?id=${dept.id }">${dept.deptName }</a></td>
</tr>
</c:forEach>
</tbody>
</table>
分页 Page.java results
/**
* 分页辅助类:对分页的基本数据进行一个简单的封装
* 用来传递分页参数和查询参数params
*/
public class Page<T> {
private int pageNo = 1; //页码,默认是第一页
private int pageSize = SysConstant.PAGE_SIZE; //每页显示的记录数,默认是10
private int totalRecord; //总记录数
private int totalPage; //总页数
private List<T> results; //对应的当前页记录
private Map<String, Object> params = new HashMap<String, Object>(); //其他的参数我们把它分装成一个Map对象
/* 页面链接 */
public String url; //分页按钮中的转向链接
public void setUrl(String url) {
this.url = url;
}
public String links;
public String getLinks() {
return sBuf.toString();
}
DeptAction.java list() 模型驱动 ModelDriven
/**
* 部门管理的Action
* @author Administrator
*
*/
public class DeptAction extends BaseAction implements ModelDriven<Dept> {
private Dept model = new Dept();
public Dept getModel() {
return model;
}
//分页查询
private Page page = new Page();
public Page getPage() {
return page;
}
public void setPage(Page page) {
this.page = page;
}
//注入DeptService
private DeptService deptService;
public void setDeptService(DeptService deptService) {
this.deptService = deptService;
}
/**
* 分页查询
*/
public String list() throws Exception {
deptService.findPage("from Dept", page, Dept.class, null);
//设置分页的url地址
page.setUrl("deptAction_list");
//将page对象压入栈顶
super.push(page);
return "list";
}
BaseAction .java push(Object obj)、put(String key ,Object value)
/**
* @Description:
* @Author: 传智播客 java学院 传智.宋江
* @Company: http://java.itcast.cn
* @CreateDate: 2014年10月31日
*/
//通过RequestAware, SessionAware, ApplicationAware实行接口获得request,session,application对象,action中就可直接调用
public class BaseAction extends ActionSupport implements RequestAware, SessionAware, ApplicationAware{
private static Logger log = Logger.getLogger(BaseAction.class);
private static final long serialVersionUID = 1L;
protected Map<String, Object> request;
protected Map<String, Object> session;
protected Map<String, Object> application;
public Map<String, Object> getRequest() {
return request;
}
public Map<String, Object> getSession() {
return session;
}
public Map<String, Object> getApplication() {
return application;
}
@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
@Override
public void setApplication(Map<String, Object> application) {
this.application = application;
}
/**
*
* 将对象放入值栈的栈顶
*/
public void push(Object obj){
ActionContext.getContext().getValueStack().push(obj);
}
/**
* 将key-value对放入值栈的 context中
*
*/
public void put(String key ,Object value){
ActionContext.getContext().put(key, value);
}
/**
* 获取当前登录的用户对象
* @return
*/
public User getCurUser(){
User user = (User)session.get(SysConstant.CURRENT_USER_INFO);
return user;
}
}
struts-sysadmin.xml /sysadmin/deptAction_*
<constant name="struts.ui.theme" value="simple"/>
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.encoding" value="UTF-8" />
<package name="sysadmin" namespace="/sysadmin" extends="default">
<action name="deptAction_*" class="deptAction" method="{1}">
<result name="list">/WEB-INF/pages/sysadmin/dept/jDeptList.jsp</result>
<result name="toview">/WEB-INF/pages/sysadmin/dept/jDeptView.jsp</result>
<result name="tocreate">/WEB-INF/pages/sysadmin/dept/jDeptCreate.jsp</result>
<result name="toupdate">/WEB-INF/pages/sysadmin/dept/jDeptUpdate.jsp</result>
<result name="alist" type="redirectAction">deptAction_list</result>
</action>
界面-查看
DeptAction.java toView 进入查看页面 jDeptView.jsp
public String toview() throws Exception {
//1.调用业务方法,根据id,得到对象
Dept dept = deptService.get(Dept.class, model.getId());
//放入栈顶
super.push(dept);
//3.跳页面
return "toview";
}
界面-修改
DeptAction.java toupdate() 进入修改页面 jDeptUpdate.jsp
/**
* 进入修改页面
*/
public String toupdate() throws Exception {
//1.根据id,得到一个对象
Dept obj = deptService.get(Dept.class, model.getId());
//2.将对象放入值栈中
super.push(obj);
//3.查询父部门
List<Dept> deptList = deptService.find("from Dept where state=1", Dept.class, null);
//4.将查询的结果放入值栈中 ,它放在context区域中
super.put("deptList", deptList);
//5.跳页面
return "toupdate";
}
DeptAction.java update() 更新 先查询原始信息,只保存更新的书写
public String update() throws Exception {
//调用业务
Dept obj = deptService.get(Dept.class, model.getId());//根据id,得到一个数据库中保存的对象
//2.设置修改的属性
obj.setParent(model.getParent());
obj.setDeptName(model.getDeptName());
deptService.saveOrUpdate(obj);
return "alist";
}
界面-新增
DeptAction.java tocreate() 进入新增页面 jDeptCreate.jsp
public String tocreate() throws Exception {
//调用业务方法
List<Dept> deptList = deptService.find("from Dept where state=1", Dept.class, null);
//将查询的结果放入值栈中 ,它放在context区域中
super.put("deptList", deptList);
//跳页面
return "tocreate";
}
jDeptCreate.jsp 上级部门下拉框
<!--
name属性代表下拉框的名称
list: 绑定的集合名 List<Dept>
headerKey:代表首选项的value属性
headerValue:代表首选项的文本
listKey: <option value="${id }"
listValue:代表中间的文本
-->
<s:select name="parent.id" list="#deptList" headerKey="" headerValue="--请选择--" listKey="id" listValue="deptName"></s:select>
DeptAction.java insert() 保存
/**
* 保存
* <s:select name="parent.id"
* <input type="text" name="deptName" value=""/>
* model对象能接收
* parent
* id
* deptName
*/
public String insert() throws Exception {
//1.调用业务方法,实现保存
deptService.saveOrUpdate(model);
//跳页面
return "alist";
}
新增时,指定用户状态为1 DeptServiceImpl saveOrUpdate
public void saveOrUpdate(Dept entity) {
if(UtilFuns.isEmpty(entity.getId())){
//新增
entity.setState(1);//1启用 0停用 默认为启用
}
baseDao.saveOrUpdate(entity);
}
删除
DeptAction.java delete() 多选删除
/**
* 删除
* <input type="checkbox" name="id" value="100"/>
* <input type="checkbox" name="id" value="3d00290a-1af0-4c28-853e-29fbf96a2722"/>
* .....
* model
* id:String类型
* 具有同名框的一组值如何封装数据?
* 如何服务端是String类型:
* 100, 3d00290a-1af0-4c28-853e-29fbf96a2722, 3d00290a-1af0-4c28-853e-29fbf96a2722
*
* id:Integer,Float,Double.Date类型 id=100 id=200 id=300
* id=300
* Integer []id; {100,200,300}
*
*
*/
public String delete() throws Exception {
String ids[] = model.getId().split(", ");
//调用业务方法,实现批量删除
deptService.delete(Dept.class, ids);
return "alist";
}
删除时注意级联删除下级部门
DeptServiceImpl.deleteById()
public void deleteById(Class<Dept> entityClass, Serializable id) {
//有哪些子部门,它的父部门编号为第二个参数:id
String hql = "from Dept where parent.id=?";
List<Dept> list = baseDao.find(hql, Dept.class, new Object[]{id});//查询出当前父部门下的子部门列表
if(list!=null && list.size()>0){
for(Dept dept :list){
deleteById(Dept.class,dept.getId());//递归调用
}
}
baseDao.deleteById(entityClass, id);//删除父部门
}
public void delete(Class<Dept> entityClass, Serializable[] ids) {
for(Serializable id :ids){
this.deleteById(Dept.class,id);
}
}
三.认证的传统与BRAC认证方式
BRAC认证方式:
Base Role Access Controller :基于角色的访问控制
四.BRAC认证方式下的数据库设计
五.实现用户与用户扩展信息的CRUD
用户 User/BaseEntity
抽取与用户扩展信息中的相同属性,放入父类中
BaseEntity .java
public class BaseEntity implements Serializable {
protected String createBy; //创建者的 id
protected String createDept;//创建者所在部门的id
protected Date createTime;//创建时间
protected String updateBy;//更新者的id
protected Date updateTime;//更新时间
User.java
public class User extends BaseEntity{
private String id;
private Dept dept;//用户与部门 多对一
private Userinfo userinfo ; //用户与用户扩展信息 一对一
private Set<Role> roles = new HashSet<Role>(0);//用户与角色 多对多
private String userName;//用户名
private String password;//密码 要加密
private Integer state;//状态
UserInfo.java
public class Userinfo extends BaseEntity {
private String id;
private String name;//姓名
private User manager;//用户与直属领导 多对一
private Date joinDate;//入职时间
private Double salary;//薪水
private Date birthday; //出生年月
private String gender; //性别
private String station;//岗位
private String email;//邮箱
private String telephone;//电话
private Integer degree;//等级
private String remark;// 备注
private Integer orderNo;//排序号
User.hbm.xml 用户-部门-用户扩展信息-角色
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.jk.domain">
<class name="User" table="USER_P" dynamic-insert="true" dynamic-update="true">
<id name="id" column="USER_ID">
<generator class="assigned"></generator>
</id>
<property name="userName" column="USER_NAME"></property>
<property name="password" column="PASSWORD"></property>
<property name="state" column="STATE"></property>
<property name="createBy" column="CREATE_BY"></property>
<property name="createDept" column="CREATE_DEPT"></property>
<property name="createTime" column="CREATE_TIME"></property>
<property name="updateBy" column="UPDATE_BY"></property>
<property name="updateTime" column="UPDATE_TIME"></property>
<!-- private Dept dept;//用户与部门 多对一 -->
<many-to-one name="dept" class="Dept" column="DEPT_ID"></many-to-one>
<!-- private Userinfo userinfo ; //用户与用户扩展信息 一对一 -->
<one-to-one name="userinfo" class="Userinfo" cascade="all"></one-to-one>
<!-- private Set<Role> roles = new HashSet<Role>(0);//用户与角色 多对多 -->
<set name="roles" table="ROLE_USER_P">
<key column="USER_ID"></key>
<many-to-many class="Role" column="ROLE_ID"></many-to-many>
</set>
</class>
</hibernate-mapping>
Userinfo.hbm.xml
<hibernate-mapping package="cn.itcast.jk.domain">
<class name="Userinfo" table="USER_INFO_P" dynamic-insert="true" dynamic-update="true">
<id name="id" column="USER_INFO_ID">
<generator class="assigned"></generator>
</id>
<property name="name" column="NAME"></property>
<property name="joinDate" column="JOIN_DATE"></property>
<!-- private User manager;//用户与直属领导 多对一 -->
<many-to-one name="manager" class="User" column="MANAGER_ID"></many-to-one>
</class>
</hibernate-mapping>
界面-用户列表
界面-查看
界面-修改
界面-新增
用户id generator方式为 assigned
UserServiceImpl.saveOrUpdate()
if(UtilFuns.isEmpty(entity.getId())){
//新增
String id = UUID.randomUUID().toString();
entity.setId(id);
entity.getUserinfo().setId(id);
新增用户 选择所在部门,领导 jUserCreate.jsp
<tr>
<td class="columnTitle">所在部门:</td>
<td class="tableContent">
<s:select name="dept.id" list="deptList"
listKey="id" listValue="deptName"
headerKey="" headerValue="--请选择--"
></s:select>
</td>
</tr>
<td class="columnTitle">直属领导:</td>
<td class="tableContent">
<s:select name="userinfo.manager.id" list="userList"
listKey="id" listValue="userinfo.name"
headerKey="" headerValue="--请选择--"
></s:select>
</td>
更新是,用户状态回显 jUserUpdate.jsp
<td class="columnTitle">状态:</td>
<td class="tableContentAuto">
<input type="radio" name="state" class="input" ${state==0?'checked':'' } value="0">停用
<input type="radio" name="state" class="input" ${state==1?'checked':'' } value="1">启用
</td>
六.实现角色的CRUD
Role.hbm.xml 角色与用户 /多对多 角色与模块/多对多
<hibernate-mapping package="cn.itcast.jk.domain">
<class name="Role" table="ROLE_P" dynamic-insert="true" dynamic-update="true">
<id name="id" column="ROLE_ID">
<generator class="uuid"></generator>
</id>
<property name="name" column="NAME"></property>
<!-- private Set<User> users = new HashSet<User>(0);//角色与用户 多对多 -->
<set name="users" table="ROLE_USER_P">
<key column="ROLE_ID"></key>
<many-to-many class="User" column="USER_ID"></many-to-many>
</set>
<!-- private Set<Module> modules = new HashSet<Module>(0);//角色与模块 多对多 -->
<set name="modules" table="ROLE_MODULE_P">
<key column="ROLE_ID"></key>
<many-to-many class="Module" column="MODULE_ID" order-by="ORDER_NO"></many-to-many>
</set>
</class>
</hibernate-mapping>
Role.java
public class Role extends BaseEntity{
private String id;
private Set<User> users = new HashSet<User>(0);//角色与用户 多对多
private Set<Module> modules = new HashSet<Module>(0);//角色与模块 多对多
private String name;//角色名
private String remark;//备注
private String orderNo;//排序号
界面-列表
界面-新增
七.实现模块的CRUD
Module.hbm.xml 模块与角色 多对多
<hibernate-mapping package="cn.itcast.jk.domain">
<class name="Module" table="MODULE_P" dynamic-update="true" dynamic-insert="true">
<id name="id" column="MODULE_ID">
<generator class="uuid"></generator>
</id>
<property name="parentId" column="PARENT_ID"></property>
<property name="parentName" column="PARENT_NAME"></property>
<property name="name" column="NAME"></property>
<!-- private Set<Role> roles = new HashSet<Role>(0);//模块与角色 多对多 -->
<set name="roles" table="ROLE_MODULE_P">
<key column="MODULE_ID"></key>
<many-to-many class="Role" column="ROLE_ID" order-by="ORDER_NO"></many-to-many>
</set>
</class>
</hibernate-mapping>
Module.java
public class Module extends BaseEntity {
private String id;
private Set<Role> roles = new HashSet<Role>(0);//模块与角色 多对多
private String parentId; //父模块的编号
private String parentName;//父模块的名称 冗余 用空间换时间
private String name; //模块名
private Integer layerNum;//层数
private Integer isLeaf;//叶子
private String ico; //图片
private String cpermission;//权限
private String curl;//路径
private Integer ctype;//菜单的类型:主菜单,左侧菜单 ,按钮
private Integer state;//状态
private String belong;//从属于
private String cwhich;//
private Integer quoteNum;//引用次数
private String remark;//备注
private Integer orderNo;//排序号