框架 day39-42 SSH整合练习项目CRM(配置文件,增删改查,ajax,上传
1 配置文件1.1 spring配置1.1.1 介绍 ? 加载properties ? 配置数据源DataSource
? 配置SessionFactory,加载所有hbm.xml ? hibernate事务管理 ? 使用 所有的模块都使用单独配置文件
1.1.2 使用源码包 ? 使用config源码,将源码和配置文件分开寄存,方便程序的保护。
1.1.3 spring核心 1.1.3.0束缚
1.1.3.1 加载properties
1.1.3.2 配置数据源
1.1.3.3 配置hibernate sessionFactory
org.hibernate.dialect.MySQL5Dialecttruetrue
1.1.3.4 配置 hibernate 事务管理
1.2 struts配置? 在struts.xml 配置“公共模块”,使用include包括子模块,所有的子模块都继承“公共模块”
struts.xml
struts-staff.xml
1.3 web.xml配置
contextConfigLocationclasspath:spring/applicationContext.xmlorg.springframework.web.context.ContextLoaderListenerstruts2org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterstruts2/*
2 用户登录
? 编写PO类(已实现) ? dao履行用户查询(用户名和密码) 继承 HibernateDaoSupport,需要spring注入SessionFactory ? service事务管理(已实现) 注意:dao和service实现,需要配置到 applicationContext_staff.xml ? action 1取得数据 属性驱动--action属性 ( --> action 类 setUsername(String username) )
属性驱动--javabean ( 模型驱动 ModelDriven (1.实现接口 2编写javabean实例(new) 3 实现getModel方法并返回实例) 2.使用service 进行登录 3.处理信息 登录成功: session作用域记录登录状态,重定向登录成功页 不成功:当前要求记录毛病信息(request作用域),使用要求转发,在登录页面显示 注意:action 需要配置到 struts-staff.xml
? 规定:所有的jsp页面(除登录页)存在WEB-INF下,javaee规范规定,阅读器端不能直接访问WEB-INF目录下的内容(tomcat直接过滤掉了),使用要求转发(
2.1 dao ? dao实现 必须继承 HibernateDaoSupport ? 使用HibernateTemplate 提供find查询所有
public class StaffDaoImpl extends HibernateDaoSupport implements StaffDao {
@Override
public CrmStaff find(CrmStaff staff) {
Listlist = this.getHibernateTemplate()
.find("from CrmStaff where loginName = ? and loginPwd = ?",staff.getLoginName(),staff.getLoginPwd());
if(list != null && list.size() > 0){
return list.get(0);
}
return null;
}
@Override
public ListfindAll(String condition,Object[] params) {
String hql = "from CrmStaff where 1=1 " + condition;
return this.getHibernateTemplate().find(hql,params);
}
}
2.2 service(MD5加密)? 登录员工密码需要使用MD5加密
public class StaffServiceImpl implements StaffService {
private StaffDao staffDao;
public void setStaffDao(StaffDao staffDao) {
this.staffDao = staffDao;
}
@Override
public CrmStaff login(CrmStaff staff) {
//登录密码需要加密
staff.setLoginPwd(MyStringUtils.getMD5Value(staff.getLoginPwd()));
return staffDao.find(staff);
}
}
MD5加密Utils
public class MyStringUtils {
/**
* 将提供的数据进行md5加密
* * 理论上不可逆的
* * JDK提供工具进行 消息摘要算法(加密)
* @param value
* @return
*/
public static String getMD5Value(String value){
try {
//1 取得工具类
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
//2 加密,加密结果为10进制
byte[] md5ValueByteArray = messageDigest.digest(value.getBytes());
//3 将10机制转换成16进制
BigInteger bigInteger = new BigInteger(1,md5ValueByteArray);
//4 转换
return bigInteger.toString(16);
} catch (Exception e) {
//如果有异常,不加密
return value;
}
}
}
2.3 配置spring
2.4 登录页面 ? 首页:使用forward包括登录页
? 登录页,将html表单,使用struts标签进行修改 略
2.5 action编写 2.5.1 封装数据 ? 实现Model接口
//1 封装数据
private CrmStaff staff = new CrmStaff(); //1.2 提供javabean实例(1定要new)
@Override
public CrmStaff getModel() { //1.3 实现方法
return staff;
}
2.5.2 提供service setter方法 ? action提供service属性名,必须与spring配置 service名称1致的
//2 spring 自动依照名称进行注入
// 2.1 员工service
// 2.1 员工service
private StaffService staffService;
public void setStaffService(StaffService staffService) {
this.staffService = staffService;
}
// 2.2部门service
private DepartmentService departmentService;
public void setDepartmentService(DepartmentService departmentService) {
this.departmentService = departmentService;
}
// 2.3 职务
private PostService postService;
public void setPostService(PostService postService) {
this.postService = postService;
}
2.5.3 登录 ? getSession().put() 相当于添加session作用域 ? addFieldError给指定的标签设置毛病提示信息,标签的主题为simple,信息将不显示,需要使用在jsp显示所有 ? this.addActionMessage() jsp 显示 (可选)
public String login(){
// 登录
CrmStaff loginStaff = staffService.login(staff);
// 处理
if(loginStaff != null){
//登录成功 -- session作用域数据,重定向首页
ActionContext.getContext().getSession().put("loginStaff",loginStaff);
return "success";
} else {
//不成功 -- 登录页给出提示
this.addFieldError("","登录用户和密码不匹配");
return "login";
}
}
2.5.4 登录成功 ? 显示WEB-INF目录下页面
/**
* 登录成功页面
* @return
*/
public String home(){
return "home";
}
2.6 action配置
staffAction_home
/WEB-INF/pages/frame.jsp/WEB-INF/pages/login.jsp/WEB-INF/pages/staff/listStaff.jsp
2.7 UIAction? 思想:如何统1显示WEB-INF目录下的jsp页面? ? 在struts.xml 编写共有内容
/WEB-INF/pages/{1}/{2}.jsp
3 拦截器? 编写登录拦截器,除登录功能,其他的页面必须登录才能访问 ? 拦截器编写: 1.编写实现类 功能:判断session是不是保存登录用户信息,如果没有拦截,如果有放行。 2.配置拦截器 2.1将自定义拦截器注册给struts 2.2使用自定义拦截器,排除登录功能。 ? 实现类回顾
Interceptor接口规定拦截器(1初始化、2拦截、3烧毁),必须编写3个方法 AbstractInterceptor拦截器抽象实现类,只需要编写“拦截”方法便可 MethodFilterInterceptor方法过滤拦截器,使用此拦截器,在配置拦截器可以设置不需要拦截的方法。
? http://localhost:8080/crm/index.jsp 当访问首页时,不使用自定义拦截器栈。 缘由:struts 拦截器 值拦截action,不拦截jsp。
3.1 实现类 ? 继承 MethodFiledInterceptor 可以在配置文件中设置需要过滤的方法,多个方法使用逗号分隔。
//登录拦截器
public class LoginInterceptor extends MethodFilterInterceptor {
/*
private String methodName;
public void setMethodName(String methodName) {
this.methodName = methodName;
}
*/
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
/*
String method = invocation.getProxy().getMethod();
if(methodName.equals(method)){
//放行
return invocation.invoke();
}
*/
//判断用户登录状态
Object loginStaff = ActionContext.getContext().getSession().get("loginStaff");
if(loginStaff == null){
/**友好提示 start*/
Object action = invocation.getAction();
if(action instanceof ActionSupport){
ActionSupport actionSupport = (ActionSupport) action;
actionSupport.addFieldError("","请登录");
}
/**友好提示 end*/
//没有登录
return "login";
}
//放行
return invocation.invoke();
}
}
3.2 配置拦截器 ? 将自定义拦截器,与struts 默许拦截器栈 组合成1个新的栈 ? 将自定义拦截器栈,配置自定义默许拦截器栈
login
3.3 扩大 手动编写拦截器疏忽方法见实现类代码/**/注释内容
3.4 配置全局结果? 登录拦截器,将拦截所有内容,如果没有登陆,大家共用1个result,需要配置全局结果。
/WEB-INF/pages/login.jsp
4 校验器? 编程式:在action 编写 所有方法:必须实现接口Validateable ,实现方法 invalidate()方法,校验所有的方法 单个方法:必须实现接口Validateable ,编写特殊的方法 invalidateAdd() 方法,表示值校验add方法 ? 声明式:使用xml配置的 所有方法: 文件名称:action类名-validation.xml 单个方法: 1)文件名称:action类名-action配置名称-validation.xml 例如:http://localhost:8080/crm/staff/staffAction_login.action action配置名称 --> staffAction_login 实例:对login方法校验,StaffAction-staffAction_login-validation.xml 2)文件束缚: xwork-core⑵.3.15.3.jar/xwork-validator⑴.0.3.dtd
3)文件内容: 类型:xwork-core⑵.3.15.3.jar/com/opensymphony/xwork2/validator/validators/default.xml
登录用户名不能为空142登录用户名必须在${minLength}-${maxLength}字符之间
登录密码不能为空164登录密码必须在${minLength}-${maxLength}字符之间
4)文件位置,与action类同包
5 员工管理--查询所有5.1 dao层
@Override
public ListfindAll() {
return this.getHibernateTemplate().find("from CrmStaff");
}
5.2 service层
@Override
public ListfindAll() {
return staffDao.findAll();
}
5.3 action实现及配置 ? /crm/src/com/itheima/crm/staff/web/action/StaffAction.java
/**
* 查询所有
* @return
*/
public String findAll(){
// 查询
ListallStaff = staffService.findAll();
// 将查询结果寄存 值栈中 -- root --> jsp页面获得, key 或 属性名 取得内容
// * 如果1组数据(List) ,使用root set方法 ,设置key
// * 如果1个对象(javabean),使用root push方法 ,javabean属性
ActionContext.getContext().getValueStack().set("allStaff",allStaff);
return "findAll";
}
配置结果
/WEB-INF/pages/staff/listStaff.jsp
5.4 OpenSessionInViewFilter
? 在web.xml 必须spring提供过滤器,必须放置struts过滤器之前
openSessionorg.springframework.orm.hibernate3.support.OpenSessionInViewFilteropenSession/*
5.5 员工管理--条件查询 5.5.1 查询所有部门 5.5.1.1 dao层 略 5.5.1.2 service层 略 5.5.1.3 配置spring 略
5.5.2 通过部门id查询职务 5.5.2.1 dao层 略 5.5.2.2 service层 略 5.5.2.3 spring 配置 略 5.5.3 优化 ? 在web.xml中配置加载所有spring文件 applicationContext*.xml 使用*通配符
contextConfigLocationclasspath:spring/applicationContext*.xml
? 注意:applicationContext.xml 不需要配置
5.5.4 发送ajax进行查询职务? 使用ajax发送部门的id,查询对应的所有的职务 /crm/post/postAction_findAllWithDepartment?crmDepartment.depId= ? 将查询的结果转成成json数据,使用javascript遍历数据并展现。 使用Jsonlib 将 List转成字符串
5.5.4.1 发送ajax
5.5.4.2 action生成json数据 ? 使用jsonlib 需要导入jar包
/**
* ajax 通过部门id查询职务,发送json
* @return
* @throws IOException
*/
public String findAllWithDepartment() throws IOException{
//1 查询
ListallPost = postService.findAll(post.getCrmDepartment().getDepId());
//2 jsonlib 将指定数据转发json字符串
//JSONObject 处理java对象 (map、javabean)
//JSONArray 处理java容器(数组、List、Set)
// 2.1 排除不需要字段
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[] {"crmDepartment","crmStaffs"});
// 2.2 转换
String jsonStr = JSONArray.fromObject(allPost,jsonConfig).toString();
// 2.3 将json数据发送给阅读器
ServletActionContext.getResponse().setContentType("application/json;charset=UTF⑻");
ServletActionContext.getResponse().getWriter().print(jsonStr);
return NONE; //表示没有返回值
}
5.5.5 条件查询实现 ? 使用ognl表达式串连进行数据封装,通过staff1个可以取得需要的所有数据。 ? 根据staff进行条件查询 ? staff被 ModelDriven拦截器已压入到栈顶,struts标签回显时,从栈顶开始取得数据,如果有就回显。
5.5.5.1 jsp表单 奇偶样式
<%--遍历数据,奇偶行样式不同 class="tabtd1" ,class="tabtd2" --%><%--将遍历每项压入到栈顶(root),可以通过javabean 属性取得值 --%>
ajax双select联动显示
5.5.5.2 action实现类
/**
* 查询所有
* @return
*/
public String findAll(){
// 1 查询所有员工
// 查询
ListallStaff = staffService.findAll(staff);
// 将查询结果寄存 值栈中 -- root --> jsp页面获得, key 或 属性名 取得内容
// * 如果1组数据(List) ,使用root set方法 ,设置key
// * 如果1个对象(javabean),使用root push方法 ,javabean属性
ActionContext.getContext().getValueStack().set("allStaff",allStaff);
//2 查询所有的部门
ListallDepartment = this.departmentService.findAll();
// * 将数据寄存到context,jsp获得 “#key”
ActionContext.getContext().put("allDepartment",allDepartment);
//3 如果选中部门,将查询部门的所有的职务
String depId = null;
if(staff.getCrmPost() != null && staff.getCrmPost().getCrmDepartment() != null){
depId = staff.getCrmPost().getCrmDepartment().getDepId();
if(StringUtils.isNotBlank(depId)){
//选中部门
ListallPost = postService.findAll(depId);
ActionContext.getContext().getValueStack().set("allPost",allPost);
}
}
return "findAll";
}
5.5.5.3 service ? 使用 StringBuilder 拼凑 HQL语句,条件中都是“ and 属性 符号 ?” 在最后使用 “where 1=1 ” ? List拼凑实际参数,(有序,可重复)
@Override
public ListfindAll(CrmStaff staff) {
//拼凑条件
//* 条件
StringBuilder sqlBuilder = new StringBuilder();
//* 参数
ListparamsList = new ArrayList();
//有可能有条件
if(staff.getCrmPost() != null){
//2 选择职务(有职务就不添加部门)
if(StringUtils.isNotBlank(staff.getCrmPost().getPostId())){
sqlBuilder.append(" and crmPost = ?");
paramsList.add(staff.getCrmPost());
} else {
//1 选中部门
CrmDepartment department = staff.getCrmPost().getCrmDepartment();
if(department != null && StringUtils.isNotBlank(department.getDepId())){
sqlBuilder.append(" and crmPost.crmDepartment = ?");
paramsList.add(staff.getCrmPost().getCrmDepartment());
}
}
}
//3员工姓名 null ""
if(StringUtils.isNotBlank(staff.getStaffName())){
sqlBuilder.append(" and staffName like ?");
paramsList.add("%"+staff.getStaffName()+"%");
}
// 将转成需要数据
String condition = sqlBuilder.toString();
Object[] params = paramsList.toArray();
return staffDao.findAll(condition,params);
}
6 课程种别6.1 dao层 ? 所有的dao继承 HibernateDaoSupport ,通过底层创建HibernateTemplate 进行PO操作。 ? save添加、update更新、delete删除 ? find查询所有,get |load 通过id查询
public class CourseTypeDaoImpl extends HibernateDaoSupport implements CourseTypeDao {
@Override
public void save(CrmCourseType courseType) {
this.getHibernateTemplate().save(courseType);
}
@Override
public void update(CrmCourseType courseType) {
this.getHibernateTemplate().update(courseType);
}
@Override
public void delete(CrmCourseType courseType) {
this.getHibernateTemplate().delete(courseType);
}
@Override
public ListfindAll() {
return this.getHibernateTemplate().find("from CrmCourseType");
}
@Override
public CrmCourseType findById(String id) {
return this.getHibernateTemplate().get(CrmCourseType.class,id);
}
}
6.2 service层 ? 提供 service 层 主要用于事务管理和业务处理。 略
6.3 配置spring 略
6.4 查询所有 6.4.1 action实现 略
6.4.2 struts配置 ? 注意:将单独文件需要添加到 struts.xml中 略
6.4.3 jsp遍历
<%--数据展现,单行:tabtd1;双行:tabtd2 --%>
<%--如果使用var,将查询结果寄存context key=var value=遍历某1项 ,标签体中获得的方式 “#key” * 注意:如果使用var iterator迭代 在context寄存1份,也在root中也寄存1份。 --%>
6.5 添加和更新(saveOrUpdate)? hibernate提供saveOrUpdate 保存或更新。 代理主键:(hibernate自动设置) 如果没有OID,将履行save 如果有OID,将履行update 自然主键:(手动设置) 履行之前必须查询select 如果查询没有结果,将履行save 如果查询有结果,将履行update ? 添加 jsp页面没有id值,表达没有数据 ? 更新 jsp页面需要id值,提供hidden 隐藏域寄存id值。需要通过id查询标签回显(struts标签)
6.5.1 dao
@Override
public void saveOrUpdate(CrmCourseType courseType) {
this.getHibernateTemplate().saveOrUpdate(courseType);
}
6.5.2 service
@Override
public void saveOrUpdateCourseType(CrmCourseType courseType) {
this.courseTypeDao.saveOrUpdate(courseType);
}
6.5.3 action ? 需要提供UI显示页面,需要通过id查询
/**
* 添加或编辑 页面显示
* @return
*/
public String addOrUpdateUI(){
//如果有id表示更新 -- 通过id查询种别
if(StringUtils.isNotBlank(courseType.getCourseTypeId())){
// 通过id查询
CrmCourseType findCourseType = courseTypeService.findById(courseType.getCourseTypeId());
// 必须将对象压入到指定
ActionContext.getContext().getValueStack().push(findCourseType);
}
return "addOrUpdateUI";
}
/**
* 添加或更新操作
* @return
*/
public String addOrUpdate(){
courseTypeService.saveOrUpdateCourseType(courseType);
return "addOrUpdate";
}
6.5.4 struts配置
/courseTypecourseTypeAction_findAll
6.5.5 jsp表单 ? 更新时,需要提供隐藏域,此处必须使用if语句。如果没有添加 courseTypeId="" 不能添加成功
<%--提供隐藏域,更新时使用 --%>
6.6 分页 + 条件? 将使用自定义javabean封装分页的数据 PageBean
public class PageBean{
//必须
private int pageNum; //当前页(第几页)
private int pageSize; //每页显示数据
private int totalRecord; //总记录数
//计算
private int startIndex; //开始索引
private int totalPage; //总页数
//分页结果
private Listdata; //分页数据
// 动态显示导航条
private int start;
private int end;
public PageBean(int pageNum,int pageSize,int totalRecord) {
super();
this.pageNum = pageNum;
this.pageSize = pageSize;
this.totalRecord = totalRecord;
//1 算法:开始索引
this.startIndex = (this.pageNum - 1) * this.pageSize;
//2 算法:总页数
this.totalPage = (this.totalRecord + this.pageSize - 1) / this.pageSize;
//3 处理导航条 (显示10个分页)
this.start = 1;
this.end = 10;
// totalPage = 4;
if(this.totalPage <= 10){ this.start = 1; this.end = this.totalPage; } else { // totalPage = 38,要求:前4后5 this.start = this.pageNum - 4; this.end = this.pageNum + 5; // 第1页 if(this.start < 1){ this.start = 1; this.end = 10; } // 最后1页 if(this.end > this.totalPage){
this.end = this.totalPage;
this.start = this.totalPage - 9;
}
}
}
get set...............
public class PageHibernateCallBackimplements HibernateCallback{
private String hql; //hql语句
private Object[] params; //hql对应实际参数
private int firstResult; //开始索引
private int maxResults; //每页显示个数
public PageHibernateCallBack(String hql,Object[] params,int firstResult,int maxResults) {
super();
this.hql = hql;
this.params = params;
this.firstResult = firstResult;
this.maxResults = maxResults;
}
@Override
public ListdoInHibernate(Session session) throws HibernateException,SQLException {
//1 创建Query对象
Query queryObject = session.createQuery(hql);
//2 设置实际参数
if (params != null) {
for (int i = 0; i < params.length; i++) { queryObject.setParameter(i,params[i]); } } //3 分页 // 3.1 开始索引 if (firstResult >= 0) {
queryObject.setFirstResult(firstResult);
}
// 3.2 每页显示个数
if (maxResults > 0) {
queryObject.setMaxResults(maxResults);
}
return queryObject.list();
}
}
6.6.1 分页 ? service层将 web层传递(pageNum,pageSize)进行处理并封装到PageBean中,需要查询总记录
//1 总记录数
int totalRecord = this.courseTypeDao.getTotalRecord(condition,params);
//2 将查询结果封装 javabean
PageBeanpageBean = new PageBean(pageNum,pageSize,totalRecord);
//3 查询分页数
Listdata = this.courseTypeDao.findAll(condition,params,pageBean.getStartIndex(),pageSize);
pageBean.setData(data);
return pageBean;
6.6.2 条件查询(拼凑条件) ? 查询总记录时,需要传递条件 ? 查询分页数据时,也需要传递条件 ? 在service拼凑条件便可。
@Override
public PageBeanfindAll(CrmCourseType courseType,int pageNum,int pageSize) {
//拼凑条件
//#1 准备对象
StringBuilder builder = new StringBuilder();
ListparamsList = new ArrayList();
//#2 拼凑
//#2.1 种别名称
if(StringUtils.isNotBlank(courseType.getCourseName())){
builder.append(" and courseName like ? ");
paramsList.add("%"+courseType.getCourseName()+"%");
}
//#2.2 简介
if(StringUtils.isNotBlank(courseType.getRemark())){
builder.append(" and remark like ? ");
paramsList.add("%"+courseType.getRemark()+"%");
}
//#2.3 总学时--条件都是字符串,需要的整形
int totalStart = 0;
int totalEnd = 0;
if(StringUtils.isNotBlank(courseType.getTotalStart())){ //200
totalStart = Integer.parseInt(courseType.getTotalStart());
}
if(StringUtils.isNotBlank(courseType.getTotalEnd())){ //100
totalEnd = Integer.parseInt(courseType.getTotalEnd());
}
// * 处理start <= end int temp = 0; if(totalStart > totalEnd){
/*
totalStart = totalStart + totalEnd;
totalEnd = totalStart - totalEnd;
totalStart = totalStart - totalEnd;
*/
temp = totalStart;
totalStart = totalEnd;
totalEnd = temp;
//查询条件中没有交换
}
// * 拼凑sql
if(totalStart > 0){
builder.append(" and total >= ?");
paramsList.add(totalStart);
}
if(totalEnd > 0){
builder.append(" and total <= ?"); paramsList.add(totalEnd); } //#2.4 费用 if(StringUtils.isNotBlank(courseType.getLessonCostStart())){ builder.append(" and courseCost >= ?");
paramsList.add(Double.parseDouble(courseType.getLessonCostStart()));
}
if(StringUtils.isNotBlank(courseType.getLessonCostEnd())){
builder.append(" and courseCost <= ?"); paramsList.add(Double.parseDouble(courseType.getLessonCostEnd())); } //#3 转换 String condition = builder.toString(); Object[] params = paramsList.toArray(); //1 总记录数 int totalRecord = this.courseTypeDao.getTotalRecord(condition,params); //2 将查询结果封装 javabean PageBeanpageBean = new PageBean(pageNum,pageSize);
pageBean.setData(data);
return pageBean;
}
6.6.3 jsp处理 ? 使用javascript,将分页的数据,与表单中条件数据 1并发送给服务器 ? 或分页a标签1并把条件发送过去
分页jsp
7 编写BaseDao和BaseAction? 泛型 + 反射 在Dao层1般情况下,进行增删改查(CRUD) 添加:session.save(PO) 修改:session.update(PO) 删除:session.delete(PO) 添加或更新:session.saveOrUpdate(PO) OID查询:session.get(Xxx.class,id) / session.load(Xxx.class,id) HQL查询:session.createQuery(hql).list()
7.1 提供统1接口BaseDao
public interface BaseDao{
/**
* 保存
* @param t
*/
public void save(T t);
/**
* 更新
* @param t
*/
public void update(T t);
/**
* 删除
* @param t
*/
public void delete(T t);
/**
* 保存或更新
* @param t
*/
public void saveOrUpdate(T t);
/**
* 通过id查询
* @param t
*/
public T findById(String id);
/**
* 查询所有
* @param t
*/
public ListfindAll();
/**
* 查询带有条件所有
* @param t
*/
public ListfindAll(String hqlCondition,Object[] params);
/**
* 查询总记录数,带有条件
* @param hqlCondition
* @param hqlParams
* @return
*/
int findTotalRecord(String hqlCondition,Object[] hqlParams);
/**
* 查询带有条件,分页数据
* @param hqlCondition hql查询条件
* @param hqlParams 对应的实际参数
* @param startIndex 开始索引
* @param pageSize 每页显示个数
* @return
*/
ListfindAll(String hqlCondition,Object[] hqlParams,int startIndex,int pageSize);
}
7.2 提供实现BaseDaoImpl? BaseDao的实现,继承HibernateDaoSupport
public class BaseDaoImplextends HibernateDaoSupport implements BaseDao{
//具体操作PO类Class对象
private ClassbeanClass;
//具体操作PO类 全限定类名
private String className;
public BaseDaoImpl() {
//1 取得当前运行类的,具有泛型信息的父类,
ParameterizedType parameterizedType = (ParameterizedType) this.getClass().getGenericSuperclass();
//2 取得实际参数类型
beanClass = (Class)parameterizedType.getActualTypeArguments()[0];
//3 实际参数类型 全限定类名
className = beanClass.getName();
}
@Override
public void save(T t) {
this.getHibernateTemplate().save(t);
}
@Override
public void update(T t) {
this.getHibernateTemplate().update(t);
}
@Override
public void delete(T t) {
this.getHibernateTemplate().delete(t);
}
@Override
public void saveOrUpdate(T t) {
this.getHibernateTemplate().saveOrUpdate(t);
}
@Override
public T findById(String id) {
return this.getHibernateTemplate().get(beanClass,id);
}
@Override
public ListfindAll() {
return this.getHibernateTemplate().find("from " + className);
}
@Override
public ListfindAll(String hqlCondition,Object[] params) {
String hql = "from " +className + " where 1=1 " + hqlCondition;
return this.getHibernateTemplate().find(hql,params);
}
@Override
public int findTotalRecord(String hqlCondition,Object[] hqlParams) {
String hql = "select count(*) from " + className + " where 1=1 " + hqlCondition;
Listlist = this.getHibernateTemplate().find(hql,hqlParams);
return list.size() == 1 ? list.get(0).intValue() : 0 ;
}
@Override
public ListfindAll(String hqlCondition,int pageSize) {
String hql = "from "+className+" where 1=1 " + hqlCondition;
return this.getHibernateTemplate().execute(new PageHibernateCallback(hql,hqlParams,startIndex,pageSize));
}
}
7.3 使用 7.3.1 接口
public interface UserDao extends BaseDao{
/**
* 使用用户名和密码进行查询/特有方法
* @param logonName
* @param logonPwd 注意:密码需要MD5加密
* @return
*/
public CrmUser findUser(String logonName,String logonPwd);
}
7.3.2 实现类
public class UserDaoImpl extends BaseDaoImplimplements UserDao {
@Override
@SuppressWarnings("unchecked")
public CrmUser findUser(String logonName,String logonPwd) {
ListallUser = this.getHibernateTemplate()
.find("from CrmUser c where c.logonName = ? and c.logonPwd = ?",logonName,logonPwd);
return allUser.size() == 1 ? allUser.get(0) : null ;
}
}
BaseAction
public class BaseActionextends ActionSupport implements ModelDriven{
// 0 使用反射,实例化 T
public BaseAction() {
try {
//1 取得当前运行类,被参数化父类。例如:BaseActionParameterizedType parameterizedType = (ParameterizedType) this
.getClass().getGenericSuperclass();
//2 取得具体类型, CrmClass,取得第1个实际参数
// * 泛型可以有多个,所以提供的是数组取得。例如: AClass
@SuppressWarnings("unchecked")
ClasscrmClass = (Class) parameterizedType.getActualTypeArguments()[0];
//3 实例化 new CrmClass();
t = crmClass.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//1 封装数据
private T t;
@Override
public T getModel() {
return t;
}
//2 注入使用到service(如果都寄存父类,以后将愈来愈多,可以采取放置在子类中)
//2.1
private ClassesService classesService;
// ** 交予spring注入
public void setClassesService(ClassesService classesService) {
this.classesService = classesService;
}
// ** 提供给子类调用
//3 分页数据
private int pageNum;
private int pageSize = 2; //暂时固定的
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
//4 简化 值栈操作
// 4.1 root --set
public void set(String key,Object o){
ActionContext.getContext().getValueStack().set(key,o);
}
// 4.2 root -- push
public void push(Object o){
ActionContext.getContext().getValueStack().push(o);
}
// 4.3 context
public void put(String key,Object value){
ActionContext.getContext().put(key,value);
}
// 4.4 context -- session
public void putSession(String key,Object value){
ActionContext.getContext().getSession().put(key,value);
}
}
8文件上传
1.1 jsp页面 ? 提供 ? 表单
1.2 action提供属性 ? struts默许拦截器栈中 提供upload拦截器,完成文件上传功能。 提供特定的属性便可 Filexxx; 内容 StringxxxFileName; 名称 StringxxxContentType; 类型 ? action实例默许压入到栈顶的,如果使用ModelDriven javabean再压入
/**
* 上传页面
* @return
*/
public String uploadUI(){
//通过id查询班级
CrmClass findClass = this.getClassesService().findById(this.getModel().getClassId());
//压入栈顶
this.push(findClass);
return "uploadUI";
}
private File schedule; //文件内容
private String scheduleFileName; //文件名称
private String scheduleContentType; //文件类型(没有用)
public void setSchedule(File schedule) {
this.schedule = schedule;
}
public void setScheduleFileName(String scheduleFileName) {
this.scheduleFileName = scheduleFileName;
}
public void setScheduleContentType(String scheduleContentType) {
this.scheduleContentType = scheduleContentType;
}
/**
* 文件上传
* @return
*/
@InputConfig(resultName="uploadInput") //如果不使用注解,方法出错时,默许返回input
public String upload(){
try {
//将 文件保存硬盘中 -- 将课表的内容保存硬盘,文件名随机,没有扩大
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |