day38_Spring学习笔记_06_CRM_02
七、使用SVN
-
步骤一:创建空文件夹crm,并创建crm仓库,同时创建目录规范,并浏览目录规范,操作步骤如下图所示:
1、
2、
3、
4、
-
步骤二:配置SVN权限,配置顺序如下图所示:
svnserve.conf
passwd
authz(多仓库)
-
步骤三:在myeclipse 中新建 svn 资源库路径并查看,步骤如下:
1、
2、
3、
-
步骤四:将项目分享到svn服务器,右键要分享的项目 –> Team –> Share Project…
1、
2、
3、
4、
5、
6、同步资源库后,由于只有我一个人进行操作,所以选中项目进行提交即可
7、
8、项目提交完成截图
9、
-
步骤五:查看项目日志记录
1、项目右键/team/显示资源历史记录
2、会出现一个错误
3、 解决办法:在配置文件中添加一些信息
svnserve.conf
uthz
再次单击 显示资源历史记录,效果如下图所示:
八、员工的编辑
思路:
1、先查询
2、用户在浏览器端修改
3、提交表单,进行更新
8.1、标签的回显
- 标签回显的原则:
- 如果是文本框数据,我们通过name属性从值栈的栈顶开始获得数据,如果获得到数据,则将数据回显到jsp页面。
- 如果是checkbox、radio、select,它们本身需要有数据才能回显,我们通过name属性从值栈获得数据,如果获得到的数据与提供的数据一致,将回显数据到jsp页面。
8.1.1、编辑前:通过员工id查询员工信息
StaffDao.java
/**
* 通过员工id查询员工
*
* @param staffId
* @return
*/
public CrmStaff findById(String staffId);
StaffDaoImpl.java
@Override
public CrmStaff findById(String staffId) {
return this.getHibernateTemplate().get(CrmStaff.class, staffId);
}
StaffService.java
/**
* 通过员工id查询员工
*
* @param staffId
* @return
*/
public CrmStaff findById(String staffId);
StaffServiceImpl.java
@Override
public CrmStaff findById(String staffId) {
return this.staffDao.findById(staffId);
}
StaffAction.java
/**
* 编辑员工信息前的显示操作
*
* @return
*/
public String editUI() {
// 1、通过员工id查询员工信息
CrmStaff findStaff = this.staffService.findById(staff.getStaffId());
// ActionContext.getContext().put("abc", findStaff); // jsp中取值方式为:#abc.getXxx 这种方式叫做手动回显
ActionContext.getContext().getValueStack().push(findStaff); // 自动回显
// 2、查询所有部门
List<CrmDepartment> allDepartment = departmentService.findAllDepartment();
// jsp页面通过“key”来获得
ActionContext.getContext().getValueStack().set("allDepartment", allDepartment); // 建议使用set(),如果使用push()的话,会比较慢
return "editUI";
}
jsp页面回显普通数据:editStaff.jsp
<s:form>
<table width="88%" border="0" class="emp_table" style="width:80%;">
<tr>
<td>登录名:</td>
<td><s:textfield name="loginName"></s:textfield></td><!-- 普通数据自动回显 -->
<td>密码:</td>
<td><s:password name="loginPwd" showPassword="true"></s:password></td>
</tr>
<tr>
<td>姓名:</td>
<td><s:textfield name="staffName"></s:textfield></td>
<td>性别:</td>
<td>
<s:radio list="{'男', '女'}" name="gender"></s:radio>
</td>
</tr>
......
<tr>
<td width="10%">入职时间:</td>
<td width="20%">
<s:date name="onDutyDate" format="yyyy-MM-dd" var="myDate"/><!-- 日期需要手动回显,因为需要格式化 -->
<s:textfield name="onDutyDate" readonly="true" value="%{#myDate}" onfocus="c.showMoreDay=true; c.show(this)"></s:textfield>
</td>
<td width="8%"></td>
<td width="62%"></td>
</tr>
</table>
</s:form>
8.1.2、部门和职务数据回显
DepartmentDao.java
/**
* 查询所有的部门
*
* @return
*/
public List<CrmDepartment> findAll();
DepartmentDaoImpl.java
@Override
public List<CrmDepartment> findAll() {
return this.getHibernateTemplate().find("from CrmDepartment");
}
DepartmentService.java
public List<CrmDepartment> findAllDepartment();
StaffDao.java
private DepartmentDao departmentDao;
public void setDepartmentDao(DepartmentDao departmentDao) {
this.departmentDao = departmentDao;
}
@Override
public List<CrmDepartment> findAllDepartment() {
return departmentDao.findAll();
}
spring 的配置
- 每一个模块单独使用xml,必须要在 applicationContext.xml 中进行import
applicationContext.xml
<!-- 4.2、部门 -->
<import resource="applicationContext-department.xml"/>
applicationContext-department.xml
<!-- 部门配置项 dao、service-->
<bean id="departmentDao" class="com.itheima.crm.department.dao.impl.DepartmentDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="departmentService" class="com.itheima.crm.department.service.impl.DepartmentServiceImpl">
<property name="departmentDao" ref="departmentDao"></property>
</bean>
StaffAction.java
/**
* 编辑员工信息前的显示操作
*
* @return
*/
public String editUI() {
// 1、通过员工id查询员工信息
CrmStaff findStaff = this.staffService.findById(staff.getStaffId());
// ActionContext.getContext().put("abc", findStaff); // jsp中取值方式为:#abc.getXxx 这种方式叫做手动回显
ActionContext.getContext().getValueStack().push(findStaff); // 自动回显
// 2、查询所有部门
List<CrmDepartment> allDepartment = departmentService.findAllDepartment();
// jsp页面通过“key”来获得
ActionContext.getContext().getValueStack().set("allDepartment", allDepartment); // 建议使用set(),如果使用push()的话,会比较慢
return "editUI";
}
jsp页面回显部门和职务数据:editStaff.jsp
- listKey 和 listValue ,获得当前列表项所使用javabean的某一个属性的值
- name ,通过name从值栈获得数据,如果获得数据和listKey确定的数据一致,会将数据进行回显
注意:当前员工的职务所属的部门,此部门下的所有职务。代码表示:post.department.postSet
editStaff.jsp
<tr>
<td width="10%">所属部门:</td>
<td width="20%">
<%--
<select name="crmPost.crmDepartment.depId" onchange="changePost(this)">
<option value="">----请--选--择----</option>
<option value="2c9091c14c78e58b014c78e67de10001" selected="selected">java学院</option>
<option value="2c9091c14c78e58b014c78e68ded0002">咨询部</option>
</select>
--%>
<s:select list="allDepartment" name="post.department.depId"
headerKey="" headerValue="----请--选--择----"
listKey="depId" listValue="depName"
>
</s:select>
</td>
<td width="8%">职务:</td>
<td width="62%">
<%--
<select name="crmPost.postId" id="postSelectId">
<option value="">----请--选--择----</option>
<option value="2c9091c14c78e58b014c78e6b34a0003">总监</option>
<option value="2c9091c14c78e58b014c78e6d4510004" selected="selected">讲师</option>
</select>
--%>
<s:select list="post != null ? post.department.postSet : {}" name="post.postId"
headerKey="" headerValue="----请--选--择----"
listKey="postId" listValue="postName"
>
</s:select>
</td>
</tr>
8.2、ajax二级联动
8.2.1、思路分析
8.2.2、查询职务
PostDao.java
/**
* 查询指定部门下的所有职务
*
* @return
*/
public List<CrmPost> findAll(CrmDepartment department);
PostDaoImpl.java
@Override
public List<CrmPost> findAll(CrmDepartment department) {
return this.getHibernateTemplate().find("from CrmPost where department=?", department); // 面向对象的角度来写
}
PostService.java
public List<CrmPost> findAllWithDepartment(CrmDepartment department);
PostServiceImpl.java
private PostDao postDao;
public void setPostDao(PostDao postDao) {
this.postDao = postDao;
}
@Override
public List<CrmPost> findAllWithDepartment(CrmDepartment department) {
return postDao.findAll(department);
}
spring 的配置
applicationContext.xml
<!-- 4.3、职务 -->
<import resource="applicationContext-post.xml"/>
applicationContext-post.xml
<!-- 职务配置项 dao、service-->
<bean id="postDao" class="com.itheima.crm.post.dao.impl.PostDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="postService" class="com.itheima.crm.post.service.impl.PostServiceImpl">
<property name="postDao" ref="postDao"></property>
</bean>
PostAction.java
package com.itheima.crm.post.web.action;
import java.io.IOException;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import com.itheima.crm.post.domain.CrmPost;
import com.itheima.crm.post.service.PostService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;
public class PostAction extends ActionSupport implements ModelDriven<CrmPost> {
// ****************************************************************
// 公共代码
// 封装数据
private CrmPost post = new CrmPost();
@Override
public CrmPost getModel() {
return post;
}
// 默认按照名称进行注入
// 职务的service
private PostService postService;
public void setPostService(PostService postService) {
this.postService = postService;
}
// ****************************************************************
// 业务代码(功能代码)
/**
* ajax 通过部门,查询指定部门下的所有职务
*
* @return
* @throws IOException
*/
public String findAllWithDepartment() throws IOException {
// 1、通过部门,查询指定部门下的所有职务
List<CrmPost> allPost = postService.findAllWithDepartment(post.getDepartment());
// 2、将查询到的结果 javabean 对象转换成 json 数据
// 2.1、排除不需要的数据(即需要排除关联对象)
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[]{"department", "staffSet"});
// 2.2、转换
String jsonData = JSONArray.fromObject(allPost, jsonConfig).toString();
// 3、 将json 数据 发送给浏览器(就相当于发送给ajax引擎了)
// 3.1、解决响应的中文乱码问题
ServletActionContext.getResponse().setContentType("text/html;charset=UTF-8"); // 这样写不标准,因为你发送的是json数据,但是你告诉浏览器是html,学习JQuery的时候再说
// 3.2、发送
ServletActionContext.getResponse().getWriter().print(jsonData);
return "none";
}
}
struts 的配置
struts.xml
<!-- 3.2、职务-->
<include file="struts/struts-post.xml"></include>
struts-post.xml
<!-- 职务的配置 -->
<package name="pos" namespace="/" extends="common">
<action name="postAction_*" class="com.itheima.crm.post.web.action.PostAction" method="{1}">
</action>
</package>
8.2.3、json数据的生成
-
将采用json-lib 工具生成
-
需要导入jar包:(注意:重复的jar包就不要导入了,留下最新版本的jar包)
-
json api的使用:
如果处理 JavaBean 或 Map 数据,使用:JSONObject.fromObject(…).toString();
如果处理 List 或 Array 数据,使用:JSONArray.fromObject(…).toString();
8.2.4、发送 ajax 请求
- /day36_06_Spring_crm/WebRoot/WEB-INF/pages/staff/editStaff.jsp
- 步骤:
- 获得当前选中部门
- 发送ajax查询职务(获得引擎、设置回调、创建连接、发送请求)
- 获得数据后,将数据添加到职务的select标签中
editStaff.jsp
......
<script type="text/javascript">
function showPost(obj) {
// 1、先获得所选的部门
var depId = obj.value;
// 2、发送ajax,通过部门查询职务
// 2.1、获得ajax引擎,不用记,找着位置就行:W3CSchool全套离线手册_最新版.chm/XML/XML DOM/DOM XMLHttpRequest/浏览器支持/XMLHttpRequest 对象/实例
var xmlhttp = null;
if (window.XMLHttpRequest) { // code for all new browsers
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) { // code for IE5 and IE6
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
// 2.2、设置回调函数
xmlhttp.onreadystatechange = function() {
// 判断请求完成和服务器正常响应
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// 3、获得数据并显示,因为是手动ajax,所以获得的是json数据的字符串
var textData = xmlhttp.responseText;
// 3.1、将字符串手动的转换成json对象,是数组
var jsonData = eval("(" + textData + ")");
// 获得select标签对象
var postSelectElement = document.getElementById("postSelectId");
postSelectElement.innerHTML = "<option value=''>----请--选--择----</option>";
// 3.2、遍历数组
for (var i = 0 ; i < jsonData.length; i++) {
var postObj = jsonData[i];
// 获得职务的id
var postId = postObj.postId;
// 获得职务的名称
var postName = postObj.postName;
// 3.3、显示数据在select标签中,先给select标签起一个id
postSelectElement.innerHTML += "<option value='" + postId + "' >" + postName + "</option>";
}
}
}
// 2.3、创建连接
var url = "${pageContext.request.contextPath}/postAction_findAllWithDepartment?department.depId=" + depId;
xmlhttp.open("GET", url);
// 2.4、发送请求
xmlhttp.send(null);
// 调试用
// alert("depId");
// alert("O(∩_∩)O哈哈~");
}
</script>
......
8.3、更新(保存)功能
8.3.1、完善表单
填写表单提交位置,添加隐藏字段
<s:form namespace="/" action="staffAction_edit">
<%-- 隐藏域,用来存放员工的id --%>
<s:hidden name="staffId" value="%{staffId}"></s:hidden>
添加javascript onclick事件,提交表单
<!-- 提交表单/保存按钮 -->
<a href="javascript:void(0)" onclick="document.forms[0].submit()">
<img src="${pageContext.request.contextPath}/images/button/save.gif"/>
</a>
8.3.2、修改action
StaffAction.java
/**
* 更新(保存)编辑后的员工信息
*
* @return
*/
public String edit() {
this.staffService.updateStaff(staff);
return "edit";
}
8.3.3、编写service
- 采用 hibernate的 快照 和 一级缓存,特别注意:一级缓存如果被修改了,与快照不一致,在默认情况下,当提交时,会自动执行update语句,所以
dao层就没有相应的update代码
了。
StaffServiceImpl.java
@Override
public void updateStaff(CrmStaff staff) {
// 密码怎么办?
/* 方案一:判断密码是否是32位长度,(我们只考虑简单情况)
* 如果是,说明密码没有修改,是之前的密码,是加密后的密码
* 如果不是,说明密码已经修改,是之后的密码,需要进行加密
*/
/*
* 方案二:我们不更新密码,
* dao层执行的是 update(staff) 即默认把一个对象的所有数据更新
* CrmStaff.hbm.xml 文件中我们需要配置密码不参加更新,即 <property name="loginPwd" update="false"></property>
*/
/*
* 方案三:先通过员工id查询,比较密码是否一致,
* 如果密码不一致,则需要对密码进行MD5加密,然后将除OID之外的数据,全部进行手动设置
* 原因:一级缓存被修改了,与快照不一致,默认情况下,当提交时,会自动执行update语句,所以dao层就没有相应的update代码了
*/
CrmStaff findStaff = staffDao.findById(staff.getStaffId());
if (! findStaff.getLoginPwd().equals(staff.getLoginPwd())) { // 不一致
findStaff.setLoginPwd(MyStringUtils.getMD5Value(staff.getLoginPwd()));
}
findStaff.setLoginName(staff.getLoginName()); // 登录名
findStaff.setStaffName(staff.getStaffName()); // 员工姓名
findStaff.setGender(staff.getGender()); // 性别
findStaff.setOnDutyDate(staff.getOnDutyDate()); // 入职时间
findStaff.setPost(staff.getPost()); // 职务
/*
* 方案四:自己编写update语句
*/
}
8.3.4、struts 的配置
struts-staff.xml
<!-- 6、编辑员工信息成功,动作重定向至查询所有,方式一:简便写法
<result name="edit" type="redirectAction">staffAction_findAll</result> -->
<!-- 6、编辑员工信息成功,动作重定向至查询所有,方式二:完整写法,可以注入详细配置 -->
<result name="edit" type="redirectAction">
<param name="namespace">/</param>
<param name="actionName">staffAction_findAll</param>
</result>
九、课程类别
9.1、查询所有课程类别
1、dao + dao.impl
CourseTypeDao.java
package com.itheima.crm.coursetype.dao;
import java.util.List;
import com.itheima.crm.coursetype.domain.CrmCourseType;
public interface CourseTypeDao {
/**
* 查询所有的课程类别
*
* @return
*/
public List<CrmCourseType> findAll();
}
CourseTypeDaoImpl.java
package com.itheima.crm.coursetype.dao.impl;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.itheima.crm.coursetype.dao.CourseTypeDao;
import com.itheima.crm.coursetype.domain.CrmCourseType;
@SuppressWarnings("unchecked")
public class CourseTypeDaoImpl extends HibernateDaoSupport implements CourseTypeDao {
@Override
public List<CrmCourseType> findAll() {
return this.getHibernateTemplate().find("from CrmCourseType");
}
}
2、service + service.impl
CourseTypeService.java
package com.itheima.crm.coursetype.service;
import java.util.List;
import com.itheima.crm.coursetype.domain.CrmCourseType;
public interface CourseTypeService {
/**
* 查询所有的课程类别
*
* @return
*/
public List<CrmCourseType> findAllCourseType();
}
CourseTypeServiceImpl.java
package com.itheima.crm.coursetype.service.impl;
import java.util.List;
import com.itheima.crm.coursetype.dao.CourseTypeDao;
import com.itheima.crm.coursetype.domain.CrmCourseType;
import com.itheima.crm.coursetype.service.CourseTypeService;
public class CourseTypeServiceImpl implements CourseTypeService {
private CourseTypeDao courseTypeDao;
public void setCourseTypeDao(CourseTypeDao courseTypeDao) {
this.courseTypeDao = courseTypeDao;
}
@Override
public List<CrmCourseType> findAllCourseType() {
return this.courseTypeDao.findAll();
}
}
3、spring
applicationContext.xml
<!-- 4.4、课程类别 -->
<import resource="applicationContext-courseType.xml"/>
applicationContext-courseType.xml
<!-- 课程类别配置项 dao、service-->
<bean id="courseTypeDao" class="com.itheima.crm.coursetype.dao.impl.CourseTypeDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="courseTypeService" class="com.itheima.crm.coursetype.service.impl.CourseTypeServiceImpl">
<property name="courseTypeDao" ref="courseTypeDao"></property>
</bean>
4、action class
CourseTypeAction.java
package com.itheima.crm.coursetype.web.action;
import java.util.List;
import com.itheima.crm.coursetype.domain.CrmCourseType;
import com.itheima.crm.coursetype.service.CourseTypeService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class CourseTypeAction extends ActionSupport implements ModelDriven<CrmCourseType> {
// ****************************************************************
// 公共代码
// 封装数据
private CrmCourseType courseType = new CrmCourseType();
@Override
public CrmCourseType getModel() {
return courseType;
}
// 默认按照名称进行注入
// 课程的service
private CourseTypeService courseTypeService;
public void setCourseTypeService(CourseTypeService courseTypeService) {
this.courseTypeService = courseTypeService;
}
// ****************************************************************
// 业务代码(功能代码)
/**
* 查询所有课程类别
*
* @return
*/
public String findAll() {
// 1、简单查询:查询所有课程类别
List<CrmCourseType> allCourseType = this.courseTypeService.findAllCourseType();
// 2、将查询的结果放入值栈中,本次放入context(大map中),使用put(key, value) 方法,jsp页面使用 “#key” 方式获得
ActionContext.getContext().put("allCourseType", allCourseType);
return "findAll";
}
}
5、struts
struts.xml
<!-- 3.3、课程类别-->
<include file="struts/struts-courseType.xml"></include>
struts-courseType.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 课程类别的配置 -->
<package name="cour" namespace="/" extends="common">
<action name="courseTypeAction_*" class="com.itheima.crm.coursetype.web.action.CourseTypeAction" method="{1}">
<!-- 1、查询所有课程类别 -->
<result name="findAll">/WEB-INF/pages/coursetype/listCourse.jsp</result>
</action>
</package>
</struts>
6、jsp
/day36_06_Spring_crm/WebRoot/WEB-INF/pages/coursetype/listCourse.jsp
......
<table width="97%" border="1">
<tr class="henglan" style="font-weight:bold;">
<td width="14%" align="center">名称</td>
<td width="33%" align="center">简介</td>
<td width="13%" align="center">总学时</td>
<td width="18%" align="center">收费标准</td>
<td width="11%" align="center">编辑</td>
</tr>
<%--数据展示,单行:tabtd1;双行:tabtd2 --%>
<s:iterator value="#allCourseType" status="vs" var="courseType">
<tr class="<s:property value="#vs.even ? 'tabtd2' : 'tabtd1'"/>"><%--设置奇偶行不同的样式 --%>
<td align="center"><s:property value="#courseType.courseName"/></td>
<td align="center"><s:property value="#courseType.remark"/></td>
<td align="center"><s:property value="#courseType.total"/></td>
<td align="center"><s:property value="#courseType.courseCost"/></td>
<td width="11%" align="center">
<a href="${pageContext.request.contextPath}/pages/coursetype/addOrEditCourse.jsp">
<img src="${pageContext.request.contextPath}/images/button/modify.gif" class="img"/>
</a>
</td>
</tr>
</s:iterator>
</table>
......
9.2、课程类别的条件查询
9.2.1、分析
9.2.2、jsp表单
listCourse.jsp
......
<%--条件查询 start --%>
<s:form namespace="/" action="courseTypeAction_findAll">
<table width="88%" border="0" class="emp_table" style="width:80%;">
<tr>
<td width="10%">课程类别:</td>
<td>
<!-- <input type="text" name="courseName" size="30" value="" /> -->
<s:textfield name="courseName" size="30"></s:textfield>
</td>
</tr>
<tr>
<td >课程简介:</td>
<td ><s:textfield name="remark" size="30"></s:textfield></td>
</tr>
<tr>
<td >总学时:</td>
<td >
<s:textfield name="totalStart" size="12"></s:textfield>
至
<s:textfield name="totalEnd" size="12"></s:textfield>
</td>
</tr>
<tr>
<td>课程费用:</td>
<td >
<s:textfield name="courseCostStart" size="12"></s:textfield>
至
<s:textfield name="courseCostEnd" size="12"></s:textfield>
</td>
</tr>
</table>
</s:form>
<%--条件查询 end --%>
......
9.2.3、修改PO类:CrmCourseType.java
CrmCourseType.java
// 修改javabean
// 查询条件的字段,注意:一般查询条件都是字符串
// 1、总学时
private String totalStart;
private String totalEnd;
// 2、课程费用
private String courseCostStart;
private String courseCostEnd;
9.2.4、action类传入参数
CourseTypeAction.java
/**
* 查询所有课程类别
*
* @return
*/
public String findAll() {
/*
// 1、简单查询:查询所有课程类别,没有参数
List<CrmCourseType> allCourseType = this.courseTypeService.findAllCourseType();
// 2、将查询的结果放入值栈中,本次放入context(大map中),使用put(key, value) 方法,jsp页面使用 “#key” 方式获得
ActionContext.getContext().put("allCourseType", allCourseType);
*/
// 2、条件查询:(包括简单查询没有条件的查询),有参数
List<CrmCourseType> allCourseType = this.courseTypeService.findAllCourseType(courseType);
ActionContext.getContext().put("allCourseType", allCourseType);
return "findAll";
}
9.2.5、service层拼凑查询条件
- 使用StringBuilder 拼凑字符串,所有的查询条件格式为:“ and 属性 运算符 ? ”
把查询条件使用 toString 转成字符串 - 使用List 拼凑实际参数,使用的是List 的特性:重复、有序
把实际参数使用 toArray 转成数组 - commons-lang3 提供了一个 StringUtils 工具类
@Override
public List<CrmCourseType> findAllCourseType() {
return courseTypeDao.findAll();
}
@Override
public List<CrmCourseType> findAllCourseType(CrmCourseType courseType) {
// 1.1、使用StringBuilder 接收:拼凑查询条件
StringBuilder builder = new StringBuilder();
// 1.2、使用List 接收:拼凑实际参数,需要可以重复,有顺序 => 选择 List集合
List<Object> paramsList = new ArrayList<Object>();
// 2、过滤条件
// 2.1、过滤课程类别,不需要 null 或者 "" 或者 " ",使用工具类
if (StringUtils.isNotBlank(courseType.getCourseName())) {
builder.append(" and courseName like ?");
paramsList.add("%" + courseType.getCourseName() + "%");
}
// 2.2、过滤课程简介,不需要 null 或者 "" 或者 " ",使用工具类
if (StringUtils.isNotBlank(courseType.getRemark())) {
builder.append(" and remark like ?");
paramsList.add("%" + courseType.getRemark() + "%");
}
// 2.3、过滤总学时
if (StringUtils.isNotBlank(courseType.getTotalStart())) {
builder.append(" and total >= ?");
paramsList.add(Integer.parseInt(courseType.getTotalStart()));
}
if (StringUtils.isNotBlank(courseType.getTotalEnd())) {
builder.append(" and total <= ?");
paramsList.add(Integer.parseInt(courseType.getTotalEnd()));
}
// 2.3、过滤总费用
if (StringUtils.isNotBlank(courseType.getCourseCostStart())) {
builder.append(" and courseCost >= ?");
paramsList.add(Double.parseDouble(courseType.getCourseCostStart()));
}
if (StringUtils.isNotBlank(courseType.getCourseCostEnd())) {
builder.append(" and courseCost <= ?");
paramsList.add(Double.parseDouble(courseType.getCourseCostEnd()));
}
// 3、使用数据
// 1、条件,格式:“and ...? and ...?”
String condition = builder.toString();
// 2、实际参数
Object[] params = paramsList.toArray();
return this.courseTypeDao.findAll(condition, params);
}
9.2.6、dao层查询
- service层拼凑查询条件,在dao层直接使用,通过 where 1=1 产生一个恒定条件
CourseTypeDaoImpl.java
@Override
public List<CrmCourseType> findAll(String condition, Object[] params) {
String hql = "from CrmCourseType where 1=1 " + condition;
return this.getHibernateTemplate().find(hql, params);
}
9.3、课程类别的添加或编辑
思路:
1.dao 层,hibernate 提供 saveOrUpdate() 方法 和 get() 方法
1.1 通过课程类别id查询详情,hibernate 提供 get(Class, String) 方法
1.2 代理主键 uuid
如果没有OID,即uuid值为null,则hibernate底层执行save(),即insert语句
如果有OID,即uuid有值,则hibernate底层执行update(),即update语句
2.service 层,需要事务管理器(add、update、delete、find)
findById(String courseTypeId);
addOrEditCourseType(CrmCourseType courseType);
3.action 类
addOrEditUI()方法,数据回显在jsp上
如果是添加,在jsp页面上显示为空
如果是更新,需要通过课程类别id查询详情,findById(XxxId) 将数据回显在jsp页面上
addOrEdit()方法,
直接保存或更新,注意:如果是更新,需要传递课程类别id值
4.jsp 页面
添加,没有课程类别id,直接显示jsp页面,没有数据
编辑,有课程类别id,传递课程类别id值,通过id查询到数据,将数据显示在jsp页面
9.3.1、dao 层
- 编辑课程类别时,需要通过课程类别id查询课程类别详情
- 保存(添加)或更新(编辑)课程类别,则直接执行 saveOrUpdate()
CourseTypeDao.java
/**
* 通过课程类别id查询课程类别详情
*
* @param courseType
* @return
*/
public CrmCourseType findById(String courseTypeId);
/**
* 保存(添加)或更新(编辑)课程类别
*
* @param courseType
*/
public void saveOrUpdate(CrmCourseType courseType);
CourseTypeDaoImpl.java
@Override
public CrmCourseType findById(String courseTypeId) {
return this.getHibernateTemplate().get(CrmCourseType.class, courseTypeId);
}
@Override
public void saveOrUpdate(CrmCourseType courseType) {
this.getHibernateTemplate().saveOrUpdate(courseType);
}
9.3.2、service 层
CourseTypeService.java
/**
* 通过课程类别id查询课程类别详情
*
* @param courseTypeId
* @return
*/
public CrmCourseType findById(String courseTypeId);
/**
* 添加或编辑课程类别
*
* @param courseType
*/
public void addOrEditCourseType(CrmCourseType courseType);
CourseTypeServiceImpl.java
@Override
public CrmCourseType findById(String courseTypeId) {
return this.courseTypeDao.findById(courseTypeId);
}
@Override
public void addOrEditCourseType(CrmCourseType courseType) {
this.courseTypeDao.saveOrUpdate(courseType);
}
9.3.3、action
- 添加课程类别时,需要显示jsp,不需要通过课程类别id查询课程类别详情
- 更新课程类别时,需要显示jsp,需要通过课程类别id查询课程类别详情,我们使用id进行区分。
CourseTypeAction.java
/**
* 添加或编辑课程类别,显示jsp页面
*
* @return
*/
public String addOrEditUI() {
// 如果课程类别id有值,说明是编辑课程类别,那么编辑需要查询课程类别详情
if (StringUtils.isNotBlank(this.courseType.getCourseTypeId())) {
// 根据课程类别id,查询课程类别详情
CrmCourseType findCourseType = this.courseTypeService.findById(this.courseType.getCourseTypeId());
// 将查询到的课程类别详情压入栈顶,方便jsp标签自动回显数据
ActionContext.getContext().getValueStack().push(findCourseType);
}
// 否则就是添加课程类别,回显空的jsp页面
return "addOrEditUI";
}
/**
* 添加或编辑课程类别功能
*
* @return
*/
public String addOrEdit() {
this.courseTypeService.addOrEditCourseType(courseType);
return "addOrEdit";
}
9.3.4、jsp页面
- 使用struts标签进行数据的自动回显
- 提供隐藏字段进行更新,添加时不需要,加入判断条件
......
<td width="52%"align="right">
<%-- 保存按钮 --%>
<a href="javascript:void(0)" onclick="javascript:document.forms[0].submit();">
<img src="${pageContext.request.contextPath}/images/button/save.gif" />
</a>
<%-- 退回按钮
<a href="#">
<img src="${pageContext.request.contextPath}/images/button/tuihui.gif"/>
</a>
--%>
<s:a namespace="/" action="courseTypeAction_findAll">
<img src="${pageContext.request.contextPath}/images/button/tuihui.gif"/>
</s:a>
</td>
......
<%-- 表单 --%>
<s:form namespace="/" action="courseTypeAction_addOrEdit">
<%-- 添加隐藏域,如果课程类别id有值,说明是更新操作,则提交表单的时候,我们就把课程类别id 隐藏着传过去 --%>
<s:if test="courseTypeId != null">
<s:hidden name="courseTypeId" value="%{courseTypeId}"></s:hidden>
</s:if>
<%-- 如果课程类别id值为空字符串,说明保存操作 --%>
<table width="88%" border="0" class="emp_table" style="width:80%;">
<tr>
<td width="10%">课程类别:</td>
<td width="20%"><s:textfield name="courseName"></s:textfield></td>
<td width="8%">总学时:</td>
<td width="62%"><s:textfield name="total"></s:textfield></td>
</tr>
<tr>
<td>课程费用:</td>
<td><s:textfield name="courseCost"></s:textfield></td>
<td></td>
<td></td>
</tr>
<tr>
<td>课程简介:</td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td colspan="4">
<s:textarea name="remark" cols="60" rows="10"></s:textarea>
</td>
</tr>
</table>
</s:form>
......