文章目录
1、上次课内容回顾
SVN
SVN:版本控制工具。
常见版本控制工具
SVN
CVS
GIT
安装SVN服务器
安装SVN客户端
SVN的使用
检出checkout
更新update
提交commit
解决SVN冲突问题
SVN的权限的设置
SVN创建用户
SVN创建组
SVN设置权限
SVN的Eclipse的插件
搭建CRM环境
CRM:客户关系管理
CRM准备工作:
CRM用户的注册功能
完成用户注册的功能
将CRM部署SVN服务器上
2、CRM综合练习:用户模块登录功能
用户模块:登录功能代码实现
修改登录页面:把路径改为login_action
编写Action中login方法
编写Service
编写Dao
配置页面的跳转
页面中显示数据
在成功页面上显示用户信息
在失败的页面上显示错误信息
3、CRM综合练习:客户管理保存客户
客户管理:准备工作
创建表
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
创建实体和映射
创建实体
创建映射
//实体
private Long cust_id;
private String cust_name;
private String cust_source;
private String cust_industry;
private String cust_level;
private String cust_phone;
private String cust_mobile;
//映射
<hibernate-mapping>
<!-- 建立类与表的映射 -->
<class name="domain.Customer" table="cst_customer">
<!-- 主键字段 -->
<id name="cust_id" column="cust_id">
<generator class="native"/>
</id>
<!-- 普通的属性字段 -->
<property name="cust_name"/>
<property name="cust_source"/>
<property name="cust_industry"/>
<property name="cust_level"/>
<property name="cust_phone"/>
<property name="cust_mobile"/>
<!-- set标签:name<->多的一方的在本对象的属性名 -->
<!-- <set name="linkMans" cascade="save-update,delete" batch-size="4" lazy="false">
key标签:一的一方在多的一方的外键名
<key column="lkm_cust_id"></key>
one-to-maney:多的一方全路径
<one-to-many class="domain.LinkMan"/>
</set> -->
</class>
</hibernate-mapping>
创建Action
创建Service、Dao(同User)
将相关的类配置到Spring中(同User)
这里都是类似的做法,参考第一章内容
跳转到添加页面
修改左侧菜单页面
编写Action中的saveUI的方法:跳转功能
配置Action的跳转
测试跳转
引入数据字典(***)
什么是数据字典
数据字典用来规范某些地方具体值和数据
创建数据字典表
CREATE TABLE `base_dict` (
`dict_id` varchar(32) NOT NULL COMMENT '数据字典id(主键)',
`dict_type_code` varchar(10) NOT NULL COMMENT '数据字典类别代码',
`dict_type_name` varchar(64) NOT NULL COMMENT '数据字典类别名称',
`dict_item_name` varchar(64) NOT NULL COMMENT '数据字典项目名称',
`dict_item_code` varchar(10) DEFAULT NULL COMMENT '数据字典项目(可为空)',
`dict_sort` int(10) DEFAULT NULL COMMENT '排序字段',
`dict_enable` char(1) NOT NULL COMMENT '1:使用 0:停用',
`dict_memo` varchar(64) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`dict_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
客户表和字典表的关系分析
创建字典的实体和映射
创建实体
创建映射
//实体
private String dict_id;
private String dict_type_code;
private String dict_type_name;
private String dict_item_name;
private String dict_item_code;
private Integer dict_sort;
private String dict_enable;
private String dict_memo;
//映射
<hibernate-mapping>
<!-- 建立类与表的映射 -->
<class name="domain.BaseDict" table="base_dict">
<!-- 主键字段 -->
<id name="dict_id" column="dict_id">
<generator class="uuid"/>
</id>
<!-- 普通的属性字段 -->
<property name="dict_type_code"/>
<property name="dict_type_name"/>
<property name="dict_item_name"/>
<property name="dict_item_code"/>
<property name="dict_sort"/>
<property name="dict_enable"/>
<property name="dict_memo"/>
<!-- 如果查询时没用到关联对象就不用设置 -->
</class>
</hibernate-mapping>
修改字典和客户的关系映射
修改了客户的实体
修改客户的映射
//实体
private Long cust_id;
private String cust_name;
private String cust_phone;
private String cust_mobile;
//虽然都是同一个对象,但是当作不同属性对待
private BaseDict cust_source;
private BaseDict cust_industry;
private BaseDict cust_level;
//映射
<hibernate-mapping>
<!-- 建立类与表的映射 -->
<class name="domain.Customer" table="cst_customer">
<!-- 主键字段 -->
<id name="cust_id" column="cust_id">
<generator class="native"/>
</id>
<!-- 普通的属性字段 -->
<property name="cust_name"/>
<property name="cust_phone"/>
<property name="cust_mobile"/>
<!-- 关联对象字段 -->
<many-to-one name="cust_source" class="domain.BaseDict" column="cust_source"/>
<many-to-one name="cust_industry" class="domain.BaseDict" column="cust_industry"/>
<many-to-one name="cust_level" class="domain.BaseDict" column="cust_level"/>
</class>
</hibernate-mapping>
将映射文件交给Spring
在添加页面上异步加载字典数据
创建字典的Action、Service、DAO(同User)
编写DAO
编写Service
编写Action
将字典类交给Spring
引入jquery的js(在添加页面上)
编写异步加载的方法
<script type="text/javascript">
$(function(){
/*
页面加载函数就会执行
页面加载,异步查询字典数据
加载客户来源
*/
$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"002"},function(data){
//遍历json的数据
$(data).each(function(i,n){
$("#cust_source").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
});
},"json");
});
</script>
编写Action
编写Service
编写Dao
加载其他字典项数据
<script type="text/javascript">
$(function(){
/*
页面加载函数就会执行
页面加载,异步查询字典数据
加载客户来源
*/
$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"002"},function(data){
//遍历json的数据
$(data).each(function(i,n){
$("#cust_source").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
});
},"json");
$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"001"},function(data){
//遍历json的数据
$(data).each(function(i,n){
$("#cust_industry").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
});
},"json");
$.post("${pageContext.request.contextPath }/baseDict_findByTypeCode",{"dict_type_code":"006"},function(data){
//遍历json的数据
$(data).each(function(i,n){
$("#cust_level").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
});
},"json");
});
</script>
小结: 写代码的时候也不报错,数据也不出来,搞了1个多小时,原因有以下几点:
1、使用modelDriver封装数据一定一定一定要手动实例化
2、使用hibernate进行查询的时候,from后面跟的一定是java对象的名称而不是数据库的!
3、怪自己没有好好的掌握好基本功,导致错误浪费了很多时间
保存数据到数据库中
修改添加页面
修改表提交action->customer_save
修改表单项名称:
编写Action、Service、Dao
添加事务:@Transactional
4、CRM综合练习:客户管理分页查询客户
查询客户(分页)
编写pageBean对象
public class PageBean<T> {
private Integer curPage; //当前页
private Integer pageSize; //页的记录数
private Integer pageCount; //每页的对象个数
private Integer totalPage; //总页数
private Integer totalCount; //总个数
private List<T> list; //封装每页对象
public void setPageSize(Integer pageSize) {
if(pageSize == null)this.pageSize=3;
else this.pageSize = pageSize;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public void setTotalCount(Integer totalCount) {
this.totalCount = totalCount;
totalPage = (int) Math.ceil(totalCount*1.0/pageSize*1.0);
}
public void setList(List<T> list) {
this.list = list;
}
public Integer getPageSize() {
return pageSize;
}
public Integer getTotalPage() {
return totalPage;
}
public Integer getTotalCount() {
return totalCount;
}
public List<T> getList() {
return list;
}
public Integer getPageCount() {
return pageCount;
}
public void setPageCount(Integer pageCount) {
this.pageCount = pageCount;
}
public Integer getCurPage() {
return curPage;
}
public void setCurPage(Integer curPage) {
this.curPage = curPage;
}
}
修改menu.jsp
修改表提交action->customer_findAll
编写Action中findAll的方法
//页面传递过来的属性
private Integer curPage = 1;
private Integer pageSize;
public void setCurPage(Integer curPage) {
if(curPage==null)curPage=1;
else this.curPage = curPage;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
//分页查询客户的方法
public String findAll(){
System.out.println("执行了```");
//最好使用DetachedCriteria对象(条件查询--带分页)
DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
//调用业务层进行查询
PageBean<Customer> pageBean = customerService.findAll(criteria, curPage, pageSize);
//ServletActionContext.getRequest().setAttribute("pageBean", pageBean); 重定向后就失效了
ActionContext.getContext().getValueStack().push(pageBean);
System.out.println(pageBean.getPageSize());
return "customer_list";
}
修改Service
@Override
//业务层分页查询客户的方法:
public PageBean<Customer> findAll(DetachedCriteria criteria, Integer curPage, Integer pageSize) {
PageBean<Customer> pageBean = new PageBean<Customer>();
// 封装当前页数:
pageBean.setCurPage(curPage);
System.out.println("到了这里:"+pageSize);
// 封装每页显示记录数:
pageBean.setPageSize(pageSize);
// 调用DAO、封装总记录数
Integer totalCount = dao.getTotalCount(criteria);
pageBean.setTotalCount(totalCount);
// 调用DAO查询所有对象
List<Customer> list = dao.findAll(criteria, pageBean.getCurPage(), pageBean.getPageSize());
// 测试输出
for (Customer customer : list) {
System.out.println(customer);
}
// 封装页的个数
pageBean.setPageCount(list.size());
// 封装pageBean中的list属性
pageBean.setList(list);
return pageBean;
}
编写Dao
@Override
public Integer getTotalCount(DetachedCriteria criteria) {
// select count(*) from xxx where 条件;
criteria.setProjection(Projections.rowCount());
List<Long> findByCriteria = (List<Long>) this.getHibernateTemplate().findByCriteria(criteria);
if(findByCriteria.size()>0)return findByCriteria.get(0).intValue();
return 0;
}
@Override
public List<Customer> findAll(DetachedCriteria criteria, Integer curPage, Integer pageSize) {
criteria.setProjection(null);
return (List<Customer>) this.getHibernateTemplate().findByCriteria(criteria, (curPage-1)*pageSize, pageSize);
}
struts配置页面跳转
<package name="customer" extends="struts-default" namespace="/">
<action name="customer_*" class="customerAction" method="{1}">
<result name="saveUI">/jsp/customer/add.jsp</result>
<result name="customer_list">/jsp/customer/list.jsp</result>
</action>
</package>
在list.jsp中显示数据(版本一:对应action中pageBean存入request的情况,存入值栈显示不了)
<TR>
<TD>
<TABLE id=grid
style="BORDER-TOP-WIDTH: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-LEFT-COLOR: #cccccc; BORDER-BOTTOM-WIDTH: 0px; BORDER-BOTTOM-COLOR: #cccccc; WIDTH: 100%; BORDER-TOP-COLOR: #cccccc; FONT-STYLE: normal; BACKGROUND-COLOR: #cccccc; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: none; BORDER-RIGHT-COLOR: #cccccc"
cellSpacing=1 cellPadding=2 rules=all border=0>
<TBODY>
<TR
style="FONT-WEIGHT: bold; FONT-STYLE: normal; BACKGROUND-COLOR: #eeeeee; TEXT-DECORATION: none">
<TD>客户名称</TD>
<TD>客户级别</TD>
<TD>客户来源</TD>
<TD>联系人</TD>
<TD>电话</TD>
<TD>手机</TD>
<TD>操作</TD>
</TR>
<s:iterator value="#request.pageBean.list">
<TR
style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none">
<TD><s:property value="cust_name"/></TD>
<TD><s:property value="cust_level.dict_item_name"/></TD>
<TD><s:property value="cust_source.dict_item_name"/></TD>
<TD><s:property value="cust_industry.dict_item_name"/></TD>
<TD><s:property value="cust_phone"/></TD>
<TD><s:property value="cust_mobile"/></TD>
<TD>
<a href="${pageContext.request.contextPath }/customerServlet?method=edit&custId=<s:property value="cust_id"/>">修改</a>
<a href="${pageContext.request.contextPath }/customerServlet?method=delete&custId=<s:property value="cust_id"/>">删除</a>
</TD>
</TR>
</s:iterator>
</TBODY>
</TABLE>
</TD>
</TR>
<TR>
<TD><SPAN id=pagelink>
<DIV style="LINE-HEIGHT: 20px; HEIGHT: 20px; TEXT-ALIGN: right">
共[<B><s:property value="#request.pageBean.totalCount"/></B>]条记录,[<B><s:property value="#request.pageBean.totalPage"/></B>]页
,每页显示
<select name="pageSize">
<option value="3" <s:if test="%{#request.pageBean.pageSize==3}">selected="selected"</s:if>>3</option>
<option value="5" <s:if test="%{#request.pageBean.pageSize==5}">selected="selected"</s:if>>5</option>
<option value="10" <s:if test="%{#request.pageBean.pageSize==10}">selected="selected"</s:if>>10</option>
</select>
条
[<A name="curPage" href="javascript:to_page(<s:property value="#request.pageBean.curPage"/>-1)">前一页</A>]
<B><s:property value="#request.pageBean.curPage"/></B>
[<A name="curPage" href="javascript:to_page(<s:property value="#request.pageBean.curPage"/>+1)">后一页</A>]
到
<input type="text" size="3" id="page" name="curPage" />
页
<input type="button" value="Go" onclick="to_page()"/>
</DIV>
</SPAN></TD>
</TR>
在list.jsp中显示数据(版本二:对应action中pageBean存入值栈的情况)
<TR>
<TD>
<TABLE id=grid
style="BORDER-TOP-WIDTH: 0px; FONT-WEIGHT: normal; BORDER-LEFT-WIDTH: 0px; BORDER-LEFT-COLOR: #cccccc; BORDER-BOTTOM-WIDTH: 0px; BORDER-BOTTOM-COLOR: #cccccc; WIDTH: 100%; BORDER-TOP-COLOR: #cccccc; FONT-STYLE: normal; BACKGROUND-COLOR: #cccccc; BORDER-RIGHT-WIDTH: 0px; TEXT-DECORATION: none; BORDER-RIGHT-COLOR: #cccccc"
cellSpacing=1 cellPadding=2 rules=all border=0>
<TBODY>
<TR
style="FONT-WEIGHT: bold; FONT-STYLE: normal; BACKGROUND-COLOR: #eeeeee; TEXT-DECORATION: none">
<TD>客户名称</TD>
<TD>客户级别</TD>
<TD>客户来源</TD>
<TD>联系人</TD>
<TD>电话</TD>
<TD>手机</TD>
<TD>操作</TD>
</TR>
<s:iterator value="list">
<TR
style="FONT-WEIGHT: normal; FONT-STYLE: normal; BACKGROUND-COLOR: white; TEXT-DECORATION: none">
<TD><s:property value="cust_name"/></TD>
<TD><s:property value="cust_level.dict_item_name"/></TD>
<TD><s:property value="cust_source.dict_item_name"/></TD>
<TD><s:property value="cust_industry.dict_item_name"/></TD>
<TD><s:property value="cust_phone"/></TD>
<TD><s:property value="cust_mobile"/></TD>
<TD>
<a href="${pageContext.request.contextPath }/customer_edit?cust_id=<s:property value="cust_id"/>">修改</a>
<a href="${pageContext.request.contextPath }/customer_delete?cust_id=<s:property value="cust_id"/>">删除</a>
</TD>
</TR>
</s:iterator>
</TBODY>
</TABLE>
</TD>
</TR>
<TR>
<TD><SPAN id=pagelink>
<DIV style="LINE-HEIGHT: 20px; HEIGHT: 20px; TEXT-ALIGN: right">
共[<B><s:property value="totalCount"/></B>]条记录,[<B><s:property value="totalPage"/></B>]页
,每页显示
<select name="pageSize" onchange="to_page()">
<option value="3" <s:if test="pageSize==3">selected="selected"</s:if>>3</option>
<option value="5" <s:if test="pageSize==5">selected="selected"</s:if>>5</option>
<option value="10" <s:if test="pageSize==10">selected="selected"</s:if>>10</option>
</select>
条
<s:if test="curPage!=1">
[<A name="curPage" href="javascript:to_page(<s:property value="curPage"/>-1)">前一页</A>]
</s:if>
<B><s:property value="curPage"/></B>
<s:if test="curPage!=totalPage">
[<A name="curPage" href="javascript:to_page(<s:property value="curPage"/>+1)">后一页</A>]
</s:if>
到
<input type="text" size="3" id="page" name="curPage" />
页
<input type="button" value="Go" onclick="to_page()"/>
</DIV>
</SPAN></TD>
</TR>
注意:
1、这里由于Struts2的遗忘,对s:if的强制解析的写法不是很熟悉,强制解析时,应把判断这些东西都卸载{}
里面
2、写的时候一直遇到一个问题就是当我跳转到页面的时候,下拉框一直显示每页10条,是因为selected写在了s:if外面,因为selected只有一个值那就是selected,所以不能写在外面,应该写在里面才行
3、pageBean的各种属性要搞好它的意义,比如pageCount和pageSize,如果搞混了就很难了
4、要配置InView的过滤器,如果不配置的话,就不能够异步显示信息了
5、离线查询的对象是一路贯穿到底的,所以统计查询之后必须要把统计查询条件清空了再去查其他的东西
6、只要是网页都进不去的错误,就先看applicationContext.xml这里面是否有错误,然后再依次排查