SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步

文章目录

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方法
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
编写Service
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
编写Dao
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
配置页面的跳转
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
页面中显示数据
 在成功页面上显示用户信息
 在失败的页面上显示错误信息

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
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
创建Service、Dao(同User)
将相关的类配置到Spring中(同User)
 这里都是类似的做法,参考第一章内容

跳转到添加页面

修改左侧菜单页面
编写Action中的saveUI的方法:跳转功能
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
配置Action的跳转
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
测试跳转
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步

引入数据字典(***)

什么是数据字典
数据字典用来规范某些地方具体值和数据
创建数据字典表

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;

客户表和字典表的关系分析
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
创建字典的实体和映射
 创建实体
 创建映射

//实体
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
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步

在添加页面上异步加载字典数据

创建字典的Action、Service、DAO(同User)
 编写DAO
 编写Service
 编写Action
将字典类交给Spring
引入jquery的js(在添加页面上)
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
编写异步加载的方法

<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
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
编写Service
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
编写Dao
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
加载其他字典项数据

<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
 修改表单项名称:
SSH企业案例_CRM客户管理系统(二):客户管理模块&字典&异步
编写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>
					&nbsp;&nbsp;
					<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>
					&nbsp;&nbsp;
					<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这里面是否有错误,然后再依次排查

上一篇:mysql创建数据库


下一篇:Android笔记: 在Eclipse环境下使用Genymotion模拟器