【SSH框架-CRM整合练习】 字典表 分页PageBean 静态包含 FastJson ajax异步 structs Upload文件上传 BaseDao BaseAction 关系映射 统计

crm练习


课程内容


课程目标

1. 通过SSH框架完成基本功能的开发

在这里插入图片描述

在这里插入图片描述

系统截图

登录

http://localhost:8080/ssh2/
在这里插入图片描述

全局异常

http://localhost:8080/ssh2/user_login.action
在这里插入图片描述

首页

http://localhost:8080/ssh2/index.jsp
在这里插入图片描述

客户列表

/ssh2/customer_findByPage.action
在这里插入图片描述

客户新增

/ssh2/customer_initAddUI.action
在这里插入图片描述

联系人列表

http://localhost:8080/ssh2/linkman_findByPage.action
在这里插入图片描述

客户拜访记录

http://localhost:8080/ssh2/visit_findByPage.action
在这里插入图片描述

客户拜访-新增

http://localhost:8080/ssh2/jsp/visit/add.jsp
在这里插入图片描述

客户来源统计

http://localhost:8080/ssh2/customer_findBySource.action
在这里插入图片描述

安全退出

/ssh2/user_exit.action

用户模块


功能一:用户注册功能

1. 可以先判断登录名是否已经存在
2. 要给密码使用MD5进行加密操作

功能二:用户登录功能

1. 登录功能要注意需要先给密码加密后,再进行查询
	* 密码加密后再查询
	* 用户的状态必须是1,字符串类型的

功能三:用户退出功能

1. 把用户信息从HttpSession中清除

客户模块


功能一:查询所有客户功能**

1. 数据字典表的引入

	* 数据字典表的作用:规范开发中数据的写法
	* 字段表与客户表是一对多的关系
	* 修改客户表,添加外键(使用SQLyog进行修改)

在这里插入图片描述

2. 创建字典表的实体和映射的配置文件

	* 编写字典表的JavaBean和映射的配置文件
	* 修改Customer的JavaBean,因为是多方,需要把外键字段换成字典对象
	* 修改Customer.hbm.xml的配置文件,配置多对一

3. 分页查询所有的客户功能实现

Customer.java

Customer.java

// 描述的是 一客户的来源,多是客户
	private Dict source;
	// 一客户的行业 多是客户
	private Dict industry;
	// 一客户级别 多是客户
	private Dict level;
Customer.hbm2.xml
<!-- 配置的多方 name是JavaBean属性名称  class="一方类的全路径" cloumn="外键的名称"  -->
		<many-to-one name="source" class="com.itheima.domain.Dict" column="cust_source"/>
		<many-to-one name="industry" class="com.itheima.domain.Dict" column="cust_industry"/>
		<many-to-one name="level" class="com.itheima.domain.Dict" column="cust_level"/>
CustomerAction.java
/**
	 * 分页的查询方法
	 * @return
	 */
	public String findByPage(){
		// 调用service业务层
		DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
		// 拼接查询的条件
		String cust_name = customer.getCust_name();
		if(cust_name != null && !cust_name.trim().isEmpty()){
			// 说明,客户的名称输入值了
			criteria.add(Restrictions.like("cust_name", "%"+cust_name+"%"));
		}
		
		// 拼接客户的级别
		Dict level = customer.getLevel();
		if(level != null && !level.getDict_id().trim().isEmpty()){
			// 说明,客户的级别肯定选择了一个级别
			criteria.add(Restrictions.eq("level.dict_id", level.getDict_id()));
		}
		
		// 客户的来源
		Dict source = customer.getSource();
		if(source != null && !source.getDict_id().trim().isEmpty()){
			// 说明,客户的级别肯定选择了一个级别
			criteria.add(Restrictions.eq("source.dict_id", source.getDict_id()));
		}
		
		// 查询
		PageBean<Customer> page = customerService.findByPage(pageCode,pageSize,criteria);
		// 压栈
		ValueStack vs = ActionContext.getContext().getValueStack();
		// 栈顶是map<"page",page对象>
		vs.set("page", page);
		return "page";
	}

3. 分页查询所有的客户功能实现

PageBean.java
package com.itheima.domain;

import java.util.List;

/**
 * 分页的JavaBean
 * @author Administrator
 */
public class PageBean<T> {
	
	// 当前页
	private int pageCode;
	
	// 总页数
	// private int totalPage;
	
	// 总记录数
	private int totalCount;
	// 每页显示的记录条数
	private int pageSize;
	// 每页显示的数据
	private List<T> beanList;
	
	public int getPageCode() {
		return pageCode;
	}
	public void setPageCode(int pageCode) {
		this.pageCode = pageCode;
	}
	
	/**
	 * 调用getTotalPage() 获取到总页数
	 * JavaBean的属性规定:totalPage是JavaBean是属性 ${pageBean.totalPage}
	 * @return
	 */
	public int getTotalPage() {
		// 计算
		int totalPage = totalCount / pageSize;
		// 说明整除
		if(totalCount % pageSize == 0){
			return totalPage;
		}else{
			return totalPage + 1;
		}
	}
	
	/*public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}*/
	
	public int getTotalCount() {
		return totalCount;
	}
	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public List<T> getBeanList() {
		return beanList;
	}
	public void setBeanList(List<T> beanList) {
		this.beanList = beanList;
	}
}

page.jsp 静态引入 <%@ include file="/jsp/page.jsp" %>

									<%@ include file="/jsp/page.jsp" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<SPAN id=pagelink>
	<DIV style="LINE-HEIGHT: 20px; HEIGHT: 20px; TEXT-ALIGN: right">
		共[<B>${page.totalCount}</B>]条记录,共[<B>${page.totalPage}</B>]页 ,每页显示 <select
			name="pageSize">
			<option value="2" <c:if test="${page.pageSize==2 }">selected</c:if>>2</option>
			<option value="3" <c:if test="${page.pageSize==3 }">selected</c:if>>3</option>
		</select><c:if test="${ page.pageCode > 1 }">
													[<A href="javascript:to_page(${page.pageCode-1})">前一页</A>]
												</c:if>

		<B>${page.pageCode}</B>

		<c:if test="${ page.pageCode < page.totalPage }">
													[<A href="javascript:to_page(${page.pageCode+1})">后一页</A>] 
												</c:if><input type="text" size="3" id="page" name="pageCode" /><input
			type="button" value="Go" onclick="to_page()" />
	</DIV>
</SPAN>
BaseAction.java
package com.itheima.web.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * Action的父类
 * @author Administrator
 */
public class BaseAction extends ActionSupport{

	private static final long serialVersionUID = 2736308223315548464L;

	// 属性驱动的方式
	// 当前页,默认值就是1  
	private Integer pageCode = 1;
	public void setPageCode(Integer pageCode) {
		if(pageCode == null){
			pageCode = 1;
		}
		this.pageCode = pageCode;
	}
	public Integer getPageCode() {
		return pageCode;
	}

	// 每页显示的数据的条数
	private Integer pageSize = 2;
	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}
	public Integer getPageSize() {
		return pageSize;
	}
	
	/**
	 * 调用值栈对象的set方法
	 */
	public void setVs(String key,Object obj){
		ActionContext.getContext().getValueStack().set(key, obj);
	}
	
	/**
	 * 调用值栈的push方法
	 * @param obj
	 */
	public void pushVs(Object obj){
		ActionContext.getContext().getValueStack().push(obj);
	}
}


LinkManAction.java findByPage()
/**
	 * 分页查询
	 * @return
	 */
	public String findByPage(){
		DetachedCriteria criteria = DetachedCriteria.forClass(Linkman.class);
		// 获取到联系人的名称
		String lkm_name = linkman.getLkm_name();
		if(lkm_name != null && !lkm_name.trim().isEmpty()){
			criteria.add(Restrictions.like("lkm_name", "%"+lkm_name+"%"));
		}
		
		// 获取客户
		Customer c = linkman.getCustomer();
		if(c != null && c.getCust_id() != null){
			// 拼接查询的条件
			criteria.add(Restrictions.eq("customer.cust_id", c.getCust_id()));
		}
		
		// 调用业务层
		PageBean<Linkman> page = linkmanService.findByPage(this.getPageCode(),this.getPageSize(),criteria);
		// 压栈
		this.setVs("page", page);
		return "page";
	}

list.jsp分页时保留上次查询条件
<TABLE cellSpacing=0 cellPadding=2 border=0>
<TBODY>
	<TR>
		<TD>客户名称:</TD>
		<TD>
			<INPUT class=textbox id=sChannel2 style="WIDTH: 80px" maxLength=50 name="cust_name" value="${ model.cust_name }">
		</TD>
		
		<td>客户级别</td>
		<td>
			<select name="level.dict_id" id="levelId">
				<option value="">--请选择--</option>
			</select>
		</td>
		
		<td>客户来源</td>
		<td>
			<select name="source.dict_id" id="sourceId">
				<option value="">--请选择--</option>
			</select>
		</td>
		
		<TD>
			<INPUT class=button id=sButton2 type=submit value="筛选 " name=sButton2>
		</TD>
	</TR>
</TBODY>
</TABLE>
list.jsp延迟加载客服来源下拉框
// 页面的加载
$(function(){
	// 发送ajax的请求
	var url = "${ pageContext.request.contextPath }/dict_findByCode.action";
	var param = {"dict_type_code":"006"};
	$.post(url,param,function(data){
		// 遍历
		$(data).each(function(i,n){
			// alert(i+" : "+n.dict_item_name);
			// alert(this.dict_item_name);
			
			// 先获取值栈中的值,使用EL表达式
			var vsId = "${model.level.dict_id}";
			// 值栈中的id值和遍历的id值相同,让被选中
			if(vsId == n.dict_id){
				// JQ的DOM操作
				$("#levelId").append("<option value='"+n.dict_id+"' selected>"+n.dict_item_name+"</option>");
			}else{
				$("#levelId").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
			}
		});
	},"json");
	
});

功能二:按条件查询所有的客户

1. 使用异步的方式加载客户级别和客户的来源

	* 前端使用JQuery的ajax技术
	* 后端使用fastjson的jar包
		* 导入fastjson的开发jar包fastjson-1.2.8.jar
		* String s = JSON.toJSONString(集合)
		* String s = JSON.toJSONString(对象)
	
	* 如果List集合中存入相同引用的对象
		* fastjson默认的情况下是进行循环检测的,去除掉死循环调用的方式
		* 可以使用JSON.toJSONString(p,SerializerFeature.DisableCircularReferenceDetect) 去除循环检测,但是就会出现死循环的效果
		* 最后可以使用注解:@JSONField(serialize=false)对指定的属性不转换成json

2. 异步获取客户级别

* ajax的代码
var url = "${pageContext.request.contextPath }/dict_findByCode.action";
var param = {"dict_type_code":"006"};
	$.post(url,param,function(data){
	$(data).each(function(){
		var id = "${model.level.dict_id}";
		if(id == this.dict_id){
			$("#levelId").append("<option value='"+this.dict_id+"' selected>"+this.dict_item_name+"</option>");
		}else{
			$("#levelId").append("<option value='"+this.dict_id+"'>"+this.dict_item_name+"</option>");
		}
	});
},"json");
Action的代码
public String findByCode(){
List<Dict> list = dictService.findByCode(dict.getDict_type_code());
	String jsonString = FastJsonUtil.toJSONString(list);
	HttpServletResponse response = ServletActionContext.getResponse();
	FastJsonUtil.write_json(response, jsonString);
	return NONE;
}
CustomerAction的分页查询的代码
public String findByPage(){
	// 调用service业务层
	DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
	// 拼接查询的条件
	String name = customer.getCust_name();
	if(name != null && !name.trim().isEmpty()){
		criteria.add(Restrictions.like("cust_name", "%"+name+"%"));
	}
	
	// System.out.println(customer.getLevel().getDict_type_code());
	Dict level = customer.getLevel();
	if(level != null && !level.getDict_id().trim().isEmpty()){
		criteria.add(Restrictions.eq("level.dict_id", level.getDict_id()));
	}
	
	Dict source = customer.getSource();
	if(source != null && !source.getDict_id().trim().isEmpty()){
		criteria.add(Restrictions.eq("source.dict_id", source.getDict_id()));
	}
	
	// 查询
	PageBean<Customer> page = customerService.findByPage(pageCode,pageSize,criteria);
	// 压栈
	ValueStack vs = ActionContext.getContext().getValueStack();
	// 栈顶是map<"page",page对象>
	vs.set("page", page);
	vs.set("cust_name", name);
	return "page";
}

FastJsonUtil.java

package com.itheima.utils;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class FastJsonUtil {
	
	/**
	 * 将对象转成json串
	 * @param object
	 * @return
	 */
	public static String toJSONString(Object object){
		//DisableCircularReferenceDetect来禁止循环引用检测
		return JSON.toJSONString(object,SerializerFeature.DisableCircularReferenceDetect);
	}
	
	//输出json
	public static void write_json(HttpServletResponse response,String jsonString){
		response.setContentType("application/json;utf-8");
		response.setCharacterEncoding("UTF-8");
		try {
			response.getWriter().print(jsonString);
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	/**
	 * ajax提交后回调的json字符串
	 * @return
	 */
	public static String ajaxResult(boolean success,String message)
	{
		Map map=new HashMap();
		map.put("success", success);//是否成功
		map.put("message", message);//文本消息
		String json= JSON.toJSONString(map);		
		return json;
	}
	

	/**
	 * JSON串自动加前缀
	 * @param json 原json字符串
	 * @param prefix 前缀
	 * @return 加前缀后的字符串
	 */

	public static String JsonFormatterAddPrefix(String json,String prefix,Map<String,Object> newmap)
	{
		if(newmap == null){
			newmap = new HashMap();
		}
		Map<String,Object> map = (Map) JSON.parse(json);

		for(String key:map.keySet())
		{
			Object object=map.get(key);
			if(isEntity(object)){
				String jsonString = JSON.toJSONString(object);
				JsonFormatterAddPrefix(jsonString,prefix+key+".",newmap);
				
			}else{
				newmap.put(prefix+key, object);
			}
			
		}
		return JSON.toJSONString(newmap);		
	}
	/**
	 * 判断某对象是不是实体
	 * @param object
	 * @return
	 */
	private static boolean isEntity(Object object)
	{
		if(object instanceof String  )
		{
			return false;
		}
		if(object instanceof Integer  )
		{
			return false;
		}
		if(object instanceof Long  )
		{
			return false;
		}
		if(object instanceof java.math.BigDecimal  )
		{
			return false;
		}
		if(object instanceof Date  )
		{
			return false;
		}
		if(object instanceof java.util.Collection )
		{
			return false;
		}
		return true;
		
	}
}


功能三:添加客户功能(含有文件上传功能)

在这里插入图片描述

流程

1. 跳转到客户的添加页面,需要通过ajax来显示客户的级别,客户的来源和客户的行业。
2. 添加文件上传的选择项
3. 客户端三个注意事项
	* method="post"
	* enctype="multipart/form-data"
	* <input type="file" name="upload">
4. Struts2框架的使用拦截器完成了文件上传,并且底层使用也是FileUpload开源的组件。
	* 提供 FileUpload 拦截器,用于解析 multipart/form-data 编码格式请求,解析上传文件的内容 
	* fileUpload拦截器 默认在 defaultStack 栈中, 默认会执行的 
	
	* 在Action中编写文件上传,需要定义三个属性
		> 文件类型File ,属性名与表单中file的name属性名一致.
		> 字符串类型String , 属性名:前段是name属性名一致 + ContentType;
		> 字符串类型String , 属性名:前段是name属性名一致+FileName;
		
		> 最后需要为上述的三个属性提供set方法。
		> 可以通过FileUtils提供 copyFile 进行文件复制,将上传文件 保存到服务器端 

文件上传中存在的问题

	1  先配置input逻辑视图
	2  在页面中显示错误信息

在这里插入图片描述

	3 文件上传的总大小默认值是2M,如果超过了2M,程序会报出异常。可以使用<s:actionError>来查看具体信息!
		> 解决总大小的设置,找到常量:
			* struts.multipart.parser=jakarta		-- 默认文件上传解析器,就是FileUpload组件
			* struts.multipart.saveDir=				-- 文件上传的临时文件存储目录
			* struts.multipart.maxSize=2097152		-- 文件上传的最大值(总大小),默认是2M
		
		> 可以在struts.xml中设置常量,修改文件上传的默认总大小!!!
			* <constant name="struts.multipart.maxSize" value="5000000"></constant>

	4  还可以通过配置拦截器来设置文件上传的一些属性
	* 先在<action>标签中引入文件上传的拦截器
		<interceptor-ref name="defaultStack">
			<!-- 设置单个上传文件的大小 -->
			<param name="fileUpload.maximumSize">2097152</param>
			<!-- 设置扩展名 -->
			<param name="fileUpload.allowedExtensions">.jpg,.txt</param>
		</interceptor-ref>

功能三:修改客户的功能**

1. 先通过客户的主键查询出客户的详细信息,显示到修改的页面上

	* 要把客户的主键和上传文件的路径使用隐藏域保存起来
	* 在edit.jsp中,把客户的网络地址等信息删除掉,没有用这些字段。

2. 修改客户的信息

	* 修改表单的enctype属性(enctype="multipart/form-data")
	* 给edit.jsp页面添加文件上传项()
	* 如果用户新上传了文件,删除旧的文件,上传新的文件。
	* 如果用户没有上传新文件,正常更新。

3. 如果要客户和联系人配置了一对多

	* 再修改客户的时候,由于Customer对象中linkmans的set中没有值,所以在默认修改Customer的时候,会把set集合中的Linkman的外键设置成null
	* 创建linkman的SQL语句中,要求外键是不能为null的
		* <set name="linkmans" inverse="true">
add.jsp
<FORM id=form1 name=form1 action="${pageContext.request.contextPath }/customer_save.action" method="post" enctype="multipart/form-data">

<TR>
	<td>客户传真 :</td>
	<td>
	<INPUT class=textbox id=sChannel2
							style="WIDTH: 180px" maxLength=50 name="custFax">
	</td>
	
	<td>上传资质:</td>
	<td>
		<input type="file" name="upload" />
	</td>
</TR>
structs.xml
<!-- 配置客户的Action,如果ActionSpring框架来管理,class标签上只需要编写ID值就OK -->
		<action name="customer_*" class="customerAction" method="{1}">
			<result name="page">/jsp/customer/list.jsp</result>
			<result name="initAddUI">/jsp/customer/add.jsp</result>
			<result name="save" type="redirectAction">customer_findByPage.action</result>
			<result name="input">/jsp/error.jsp</result>
			<result name="delete" type="redirectAction">customer_findByPage.action</result>
			<result name="initUpdate">/jsp/customer/edit.jsp</result>
			<result name="update" type="redirectAction">customer_findByPage.action</result>
			<result name="findBySource">/jsp/totals/sources.jsp</result>
			
			<!-- 引入默认的拦截器 -->
			<interceptor-ref name="userInterceptor"/>
			<interceptor-ref name="defaultStack">
				<!-- 决定上传文件的类型 -->
				<param name="fileUpload.allowedExtensions">.jpg,.txt</param>
			</interceptor-ref>
		</action>
CustomerAction.java save() delete()
/**
	 * 文件的上传,需要在CustomerAction类中定义成员的属性,命名是有规则的!!
	 * private File upload;		// 表示要上传的文件
	 * private String uploadFileName;	表示是上传文件的名称(没有中文乱码)
	 * private String uploadContentType;	表示上传文件的MIME类型
	 * 提供set方法,拦截器就注入值了
	 */
	
	// 要上传的文件
	private File upload;
	// 文件的名称
	private String uploadFileName;
	// 文件的MIME的类型
	private String uploadContentType;
	
	public void setUpload(File upload) {
		this.upload = upload;
	}
	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}
	
	/**
	 * 保存客户的方法
	 * @return
	 * @throws IOException 
	 */
	public String save() throws IOException{
		// 做文件的上传,说明用户选择了上传的文件了
		if(uploadFileName != null){
			// 打印
			System.out.println("文件类型:"+uploadContentType);
			// 把文件的名称处理一下
			String uuidname = UploadUtils.getUUIDName(uploadFileName);
			// 把文件上传到D:\\apache-tomcat-7.0.52\\webapps\\upload
			String path = "D:\\apache-tomcat-7.0.52\\webapps\\upload\\";
			// 创建file对象
			File file = new File(path+uuidname);
			// 简单方式
			FileUtils.copyFile(upload, file);
			
			// 把上传的文件的路径,保存到客户表中
			customer.setFilepath(path+uuidname);
		}
		
		// 保存客户成功了
		customerService.save(customer);
		return "save";
	}

/**
	 * 删除客户
	 * @return
	 */
	public String delete(){
		// 删除客户,获取客户的信息获取到,上传文件的路径
		customer = customerService.findById(customer.getCust_id());
		// 获取上传文件的路径
		String filepath = customer.getFilepath();
		// 删除客户
		customerService.delete(customer);
		
		// 再删除文件
		File file = new File(filepath);
		if(file.exists()){
			file.delete();
		}
		
		return "delete";
	}

功能四:删除客户的功能

1. 删除上传的文件后,再删除客户信息。

抽取通用的BaseDao功能

在这里插入图片描述

在这里插入图片描述

1. 通过上面编写的一些功能,DAO层的代码相对比较固定,所以可以想办法来抽取出通用的方法!!

2. 代码如下
	private Class clazz;
	public BaseDaoImpl(){
		Class c = this.getClass();
		Type type = c.getGenericSuperclass();
		// 判断
		if(type instanceof ParameterizedType){
			ParameterizedType ptype = (ParameterizedType) type;
			// 获取实际类型参数
			Type[] types = ptype.getActualTypeArguments();
			// 获取0位置的值
			clazz = (Class) types[0];
		}
	}

BaseDao.java

package com.itheima.dao;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;

import com.itheima.domain.PageBean;

/**
 * 以后所有的DAO的接口都需要继承BaseDao接口
 * 自定义泛型接口
 * @author Administrator
 */
public interface BaseDao<T> {
	
	public void save(T t);
	
	public void delete(T t);
	
	public void update(T t);
	
	public T findById(Long id);
	
	public List<T> findAll();
	
	public PageBean<T> findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria);
	
}

BaseDaoImpl.java

package com.itheima.dao;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.itheima.domain.Customer;
import com.itheima.domain.PageBean;

/**
 * 以后所有的Dao成的实现类,都可以继承BaseDaoImpl,增删改查分页方法不用再编写了
 * @author Administrator
 * @param <T>
 */
@SuppressWarnings("all")
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{
	
	// 定义成员的属性
	private Class clazz;
	
	public BaseDaoImpl(){
		// this表示的子类,c表示就是CustomerDaoImpl的Class对象
		Class c = this.getClass();
		// CustomerDaoImpl extends BaseDaoImpl<Customer>  map<k,v>
		// 第2步:获取到是BaseDaoImpl<Customer>
		Type type = c.getGenericSuperclass();
		
		// 目的:把type接口转换成子接口
		if(type instanceof ParameterizedType){
			ParameterizedType ptype = (ParameterizedType) type;
			
			// 获取到 Customer
			Type[] types = ptype.getActualTypeArguments();
			this.clazz = (Class) types[0];
		}
	}
	
	/**
	 * 添加
	 */
	public void save(T t) {
		this.getHibernateTemplate().save(t);
	}
	
	/**
	 * 删除
	 */
	public void delete(T t) {
		this.getHibernateTemplate().delete(t);
	}

	/**
	 * 修改
	 */
	public void update(T t) {
		this.getHibernateTemplate().update(t);
	}
	
	/**
	 * 通过主键查询
	 */
	public T findById(Long id) {
		return (T) this.getHibernateTemplate().get(clazz, id);
	}
	
	/**
	 * 查询所有的数据
	 */
	public List<T> findAll() {
		return (List<T>) this.getHibernateTemplate().find("from "+clazz.getSimpleName());
	}
	
	/**
	 * 分页查询
	 */
	public PageBean<T> findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria) {
		// 创建分页的对象
		PageBean<T> page = new PageBean<T>();
		// 一个一个设置
		page.setPageCode(pageCode);
		page.setPageSize(pageSize);
		
		// 设置查询聚合函数:SQL已经变成了 select count(*) from 
		criteria.setProjection(Projections.rowCount());
		List<Number> list = (List<Number>) this.getHibernateTemplate().findByCriteria(criteria);
		if(list != null && list.size() > 0){
			int totalCount = list.get(0).intValue();
			// 总记录数
			page.setTotalCount(totalCount);
		}
		
		// 清除SQL select * from xxx
		criteria.setProjection(null);
		
		List<T> beanList = (List<T>) this.getHibernateTemplate().findByCriteria(criteria, (pageCode-1)*pageSize, pageSize);
		// 每页显示的数据
		page.setBeanList(beanList);
		return page;
	}
}


LinkmanDao.java

package com.itheima.dao;

import com.itheima.domain.Linkman;

public interface LinkmanDao extends BaseDao<Linkman>{

}

LinkManDaoImpl.java

package com.itheima.dao;

import com.itheima.domain.Linkman;

public class LinkmanDaoImpl extends BaseDaoImpl<Linkman> implements LinkmanDao {
	
}


抽取BaseAction的功能

1. Action需要完成分页的代码,需要接收pageCode和pageSize的请求参数,可以编写BaseAction用来接收分页的请求参数

BaseAction.java


联系人模块


功能一:查询联系人功能

1. 分页显示所有的联系人的数据

功能二:添加联系人功能

1. 自己完成

功能三:修改联系人功能

1. 自己完成

功能四:删除联系人功能

1. 自己完成

问题 客户和联系人的死循环

在这里插入图片描述

FastJson遍历死循环 Customer.java

// 和联系人配置一对多
	// 默认不把set集合进行json的转换
	@JSONField(serialize=false)
	private Set<Linkman> linkmans = new HashSet<Linkman>();
	

问题2 修改客户时,导致联系人所属客户信息被清空

让客户放弃外键的维护的权力 Customer.hbm2.xml


		<!--Customer放弃外键的维护的权力 -->
		<set name="linkmans" inverse="true">
			<key column="lkm_cust_id"/>
			<one-to-many class="com.itheima.domain.Linkman"/>
		</set>

客户拜访模块

客户拜访,用户 和客户(联系人)是多对多关系

在这里插入图片描述

在这里插入图片描述


功能一:搭建客户拜访表的开发环境(导入资料中的拜访客户的SQL语句)

1. 客户关系拜访表是该系统的用户和客户之间的关系建立表

	* 用户可以拜访多个客户
	* 客户也可以被多个用户所拜访
	* 所以:用户和客户之间应该是多对多的关系,那么客户拜访表就是用户和客户的中间表。
	* 正常的情况下,在用户和客户中添加set集合,在映射的配置文件中配置<set>标签即可。
	* 但是现在客户拜访中间表中存在其他的字段,默认的情况下,中间表只能维护外键。而不能维护其他的字段。所以需要把一对多拆开成两个一对多。

2. 用户与客户拜访表是一对多的关系
3. 客户与客户拜访表是一对多的关系
4. 创建客户拜访表的实体类和映射配置文件
5. 编写客户拜访的Action等类和完成配置
	* 先开启注解的扫描
		* <context:component-scan base-package="com.itheima"/>
	
	* Action编写(@RestController(value="visitAction") @Scope(value="prototype"))
	* Service编写(@Service(value="visitService") @Transactional)
	* Dao编写(@Repository(value="visitDao"))
		* 重点是dao中注入SessionFactory对象
			@Resource(name="sessionFactory")
			public void sSessionFactory(SessionFactory sessionFactory){
				// 重点的代码
				super.setSessionFactory(sessionFactory);
			}

功能二:客户拜访列表查询功能*

1. 先导入客户拜访的页面

	* 在资料中的(visit文件夹和jquery文件夹)
		* visit文件夹复制到jsp的目录下
		* jquery文件夹复制到WebContent目录下

2. 查询我的客户拜访记录

	* 登录的用户,点击客户拜访列表,查询该用户下的所有的拜访记录
	* 通过用户的主键查询该用户下的所有的拜访记录

Visit.java

/**
 * 客户拜访的JavaBean
 * @author Administrator
 */
public class Visit {
		
	// 主键
	private String visit_id;
	// 外键,和客户
	private Customer customer;
	// 外键,和用户
	private User user;

Visit.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	
	<class name="com.itheima.domain.Visit" table="sale_visit">
		<id name="visit_id" column="visit_id">
			<!-- 主键是字符串的类型 -->
			<generator class="uuid"/>
		</id>
		
		<property name="visit_time" column="visit_time"/>
		<property name="visit_interviewee" column="visit_interviewee"/>
		<property name="visit_addr" column="visit_addr"/>
		<property name="visit_detail" column="visit_detail"/>
		<property name="visit_nexttime" column="visit_nexttime"/>
		
		<many-to-one name="customer" class="com.itheima.domain.Customer" column="visit_cust_id"/>
		<many-to-one name="user" class="com.itheima.domain.User" column="visit_user_id"/>
		
	</class>
	
</hibernate-mapping>

VisitAction.java


/**
 * 客户拜访的控制器
 * @author Administrator
 * Controller(value="visitAction") = <bean id="visitAction" class="..." scope="">
 */
@Controller(value="visitAction")
@Scope(value="prototype")
public class VisitAction extends BaseAction implements ModelDriven<Visit>{
	
	private static final long serialVersionUID = -139853886677968072L;
	
	private Visit visit = new Visit();
	
	public Visit getModel() {
		return visit;
	}
	
	@Resource(name="visitService")
	private VisitService visitService;
	
	private String beginDate;
	private String endDate;
	public void setBeginDate(String beginDate) {
		this.beginDate = beginDate;
	}
	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}
	
	/**
	 * 分页的查询
	 * 查询客户的拜访记录,根据用户的主键查询
	 * select * from sale_visit where visit_user_id = ?
	 * @return
	 */
	public String findByPage(){
		// 先获取当前登录的用户
		User user = (User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
		// 判断
		if(user == null){
			// 配置全局结果跳转
			return LOGIN;
		}
		// 查询该用户下所有的拜访记录
		DetachedCriteria criteria = DetachedCriteria.forClass(Visit.class);
		
		// 拼接查询的条件
		if(beginDate != null && !beginDate.trim().isEmpty()){
			criteria.add(Restrictions.ge("visit_time", beginDate));
		}
		// select * from xxx where visit_time >= ? and visit_time <= ?
		if(endDate != null && !endDate.trim().isEmpty()){
			criteria.add(Restrictions.le("visit_time", endDate));
		}
		
		// 添加查询的条件
		criteria.add(Restrictions.eq("user.user_id",user.getUser_id()));
		// 分页查询
		PageBean<Visit> page = visitService.findByPage(this.getPageCode(),this.getPageSize(),criteria);
		this.setVs("page", page);
		return "page";
	}
	
	/**
	 * 保存拜访记录
	 * @return
	 */
	public String save(){
		// 把用户获取到,设置到当前的拜访记录中,再保存
		User user = (User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
		// 判断
		if(user == null){
			// 配置全局结果跳转
			return LOGIN;
		}
		// 设置
		visit.setUser(user);
		// 保存数据
		visitService.save(visit);
		
		return "save";
	}
	
}

VisitDaoImpl.java sessionfactory 注解方式注入问题


/**
 * 客户拜访的持久层
 * @author Administrator
 */
@Repository(value="visitDao")
public class VisitDaoImpl extends BaseDaoImpl<Visit> implements VisitDao {
	
	@Resource(name="sessionFactory")
	public void set2SessionFactory(SessionFactory sessionFactory){
		// 关键,调用父类的方法
		super.setSessionFactory(sessionFactory);
	}
	
}

VisitService.java

/**
 * 客户拜访业务层
 * @author Administrator
 */
@Service(value="visitService")
@Transactional
public class VisitServiceImpl implements VisitService {
	
	@Resource(name="visitDao")
	private VisitDao visitDao;

	/**
	 * 分页查询
	 */
	public PageBean<Visit> findByPage(Integer pageCode, Integer pageSize, DetachedCriteria criteria) {
		return visitDao.findByPage(pageCode, pageSize, criteria);
	}

	public void save(Visit visit) {
		visitDao.save(visit);
	}

}

visit list.jsp 日期控件

<TD>选择日期:</TD>
<TD>
	<INPUT class=textbox id="beginDate" style="WIDTH: 80px" maxLength=50 name="beginDate"><INPUT class=textbox id="endDate" style="WIDTH: 80px" maxLength=50 name="endDate">
</TD>
<!-- 日期插件,使用jquery -->
<script type="text/javascript" src="${pageContext.request.contextPath }/jquery/jquery-1.4.2.js"></script>
<link rel="stylesheet" href="${pageContext.request.contextPath }/jquery/jquery.datepick.css" type="text/css">
<script type="text/javascript" src="${pageContext.request.contextPath }/jquery/jquery.datepick.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/jquery/jquery.datepick-zh-CN.js"></script>




<SCRIPT language=javascript>
	function to_page(page){
		if(page){
			$("#page").val(page);
		}
		document.customerForm.submit();
	}
	
	$(function(){
		// 给beginDate和endDate绑定日期控件的方法
		$('#beginDate').datepick({dateFormat: 'yy-mm-dd'}); 
		$('#endDate').datepick({dateFormat: 'yy-mm-dd'}); 
	});
	
</SCRIPT>

功能三:新增客户拜访记录功能

1. 点击新增客户拜访功能菜单,跳转到新增页面,输入信息,保存数据
	* 从HttpSession中获取到用户的信息,设置到拜访记录中,保存到数据库中

功能四:按条件查询客户信息列表功能

1. 修改list.jsp的页面,添加开始和结束日期的选项
	<TD>拜访时间:</TD>
	<TD>
		<INPUT class=textbox id="beginDate" style="WIDTH: 80px" maxLength=50 name="beginDate">
		至
		<INPUT class=textbox id="endDate" style="WIDTH: 80px" maxLength=50 name="endDate">
	</TD>

统计分析模块


功能一:客户来源统计

1. 想要统计客户的来源,即该来源下有多少个客户
	* SQL语句:SELECT d.dict_item_name,COUNT(*) FROM base_dict d,cst_customer c WHERE d.dict_id = c.cust_source GROUP BY d.dict_id;
	* HQL语句:String hql = "select c.source.dict_item_name,COUNT(*) from Customer c inner join c.source GROUP BY c.source";

CustomerAction.java findBySource()


	/**
	 * 统计来源客户的数量
	
	 * @return
	 */
	public String findBySource(){
		List<Object[]> list = customerService.findBySource();
		// 压栈
		ValueStack vs = ActionContext.getContext().getValueStack();
		// 栈顶是map<"page",page对象>
		vs.set("list", list);
		return "findBySource";
	}

CustomerDaoImpl.java findBySource()

sources.jsp

/**
	 * 统计客户的来源
	 */
	public List<Object[]> findBySource() {
		// 定义HQL
		// SELECT * FROM cst_customer c,base_dict d WHERE d.dict_id = c.cust_source
		// 分组查询 SELECT * FROM cst_customer c,base_dict d WHERE d.dict_id = c.cust_source group by d.dict_id
		// 查询内容:SELECT d.dict_item_name,count(*) FROM cst_customer c,base_dict d 
		//				WHERE d.dict_id = c.cust_source group by d.dict_id
		
		String hql = "select c.source.dict_item_name,count(*) from Customer c inner join c.source group by c.source";
		// 查询
		return (List<Object[]>) this.getHibernateTemplate().find(hql);
	}

public List<Object[]> findBySource2() {
		String hql = "SELECT d.dict_item_name,count(*)  FROM Customer c,Dict d WHERE d.dict_id = c.source.dict_id group by d.dict_id";
		// 查询
		return (List<Object[]>) this.getHibernateTemplate().find(hql);
	}

HQL*SQL

在这里插入图片描述
在这里插入图片描述

HQL*SQL2

在这里插入图片描述

在这里插入图片描述


用户登录的拦截器


用户登录的拦截器功能实现

1. 功能:如果用户没有登录,是不能操作后台的功能的!!

2. 代码如下

	public class UserInterceptor extends MethodFilterInterceptor{

		private static final long serialVersionUID = 335018670739692955L;
		
		/**
		 * 进行拦截的方法
		 */
		protected String doIntercept(ActionInvocation invocation) throws Exception {
			// 获取session对象
			User user = (User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
			if(user == null){
				// 说明,没有登录,后面就不会执行了
				return "login";
			}
			return invocation.invoke();
		}
	}

3. 配置如下

	<interceptors>
		<interceptor name="UserInterceptor" class="com.itheima.web.interceptor.UserInterceptor"/>
	</interceptors>
	<interceptor-ref name="UserInterceptor">
		<!-- login方法不拦截 -->
		<param name="excludeMethods">login</param>
	</interceptor-ref>
	<interceptor-ref name="defaultStack"/>

用户登录

UserAction().java

package com.itheima.web.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.itheima.domain.User;
import com.itheima.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 用户的控制器
 * @author Administrator
 */
public class UserAction extends ActionSupport implements ModelDriven<User>{
	
	private static final long serialVersionUID = -3413092622818913571L;
	
	private User user = new User();
	
	public User getModel() {
		return user;
	}
	
	private UserService userService;
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	/**
	 * 注册功能
	 * @return
	 */
	public String regist(){
		// 接收请求参数
		userService.save(user);
		return LOGIN;
	}
	
	/**
	 * 通过登录名,判断,登录名是否已经存在
	 * @return
	 */
	public String checkCode(){
		// 调用业务层,查询
		User u = userService.checkCode(user.getUser_code());
		// 获取response对象
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/html;charset=UTF-8");
		try {
			// 获取输出流
			PrintWriter writer = response.getWriter();
			// 进行判断
			if(u != null){
				// 说明:登录名查询到用户了,说明登录已经存在了,不能注册
				writer.print("no");
			}else{
				// 说明,不存在登录名,可以注册
				writer.print("yes");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return NONE;
	}
	
	/**
	 * 登录功能
	 * @return
	 */
	public String login(){
		User existUser = userService.login(user);
		// 判断,登录名或者密码错误了
		if(existUser == null){
			return LOGIN;
		}else{
			ServletActionContext.getRequest().getSession().setAttribute("existUser", existUser);
			// 登录成功
			return "loginOK";
		}
	}
	
	/**
	 * 退出功能
	 * @return
	 */
	public String exit(){
		ServletActionContext.getRequest().getSession().removeAttribute("existUser");
		return LOGIN;
	}
}


UserDaoImpl.java

/**
 * 持久层:都可以继承HibernateDaoSupport类
 * 
 * @author Administrator
 */
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

	/**
	 * 通过登录名进行验证
	 */
	public User checkCode(String user_code) {
		List<User> list = (List<User>) this.getHibernateTemplate().find("from User where user_code = ?", user_code);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}
	
	/**
	 * 保存用户
	 */
	public void save(User user) {
		this.getHibernateTemplate().save(user);
	}

	/**
	 * 登录功能
	 * 通过用户名和密码和用户的状态
	 */
	public User login(User user) {
		// QBC的查询,按条件进行查询
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		// 拼接查询的条件
		criteria.add(Restrictions.eq("user_code", user.getUser_code()));
		criteria.add(Restrictions.eq("user_password", user.getUser_password()));
		criteria.add(Restrictions.eq("user_state", "1"));
		// 查询
		List<User> list = (List<User>) this.getHibernateTemplate().findByCriteria(criteria);
		if(list != null && list.size() > 0){
			return list.get(0);
		}
		return null;
	}

}


regist.html

<script type="text/javascript">
	// 验证登录名
	function checkCode(){
		// 获取用户输入的登录名
		var code = $("#user_code").val();
		// 进行判断,说明没有输入登录名
		if(code.trim() == ""){
			// 给提示
			$("#codeId").addClass("error");
			$("#codeId").html("登录名不能为空");
		}else{
			// 登录名不为空,ajax请求,验证
			var url = "${pageContext.request.contextPath}/user_checkCode.action";
			var param = {"user_code":code};
			$.post(url,param,function(data){
				// 操作data,进行判断
				if(data && data == "no"){
					// 提示
					$("#codeId").addClass("error");
					$("#codeId").html("登录名已经存在");
				}else{
					$("#codeId").removeClass("error");
					$("#codeId").html("可以注册");
				}
			});
		}
	}
	
	// 可以阻止表单的提交
	function checkForm(){
		// 先让校验名称的方法先执行以下
		checkCode();
		// 获取error的数量,如果数量 > 0,说明存在错误,不能提交表单
		if($(".error").size() > 0){
			return false;
		}
	}
	
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* * @(#)PageControl.java 1.00 2004-9-22 * * Copyright 2004 2004 . All rights reserved. * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.hexiang.utils; /** * PageControl, 分页控制, 可以判断总页数和是否有上下页. * * 2008-07-22 加入输出上下分页HTML代码功能 * * @author HX * @version 1.1 2008-9-22 */ public class PageBean { /** 每页显示记录数 */ private int pageCount; /** 是否有上一页 */ private boolean hasPrevPage; /** 记录总数 */ private int recordCount; /** 是否有下一页 */ private boolean hasNextPage; /**总页面数 */ private int totalPage; /** 当前页码数 */ private int currentPage; /** * 分页前的页面地址 */ private String pageUrl; /** * 输出分页 HTML 页面跳转代码, 分链接和静态文字两种. * 2008-07-22 * @return HTML 代码 */ public String getPageJumpLinkHtml() { if(StringUtil.isEmpty(pageUrl)) { return ""; } // 检查是否有参数符号, 没有就加上一个? if(pageUrl.indexOf('?') == -1) { pageUrl = pageUrl + '?'; } StringBuffer buff = new StringBuffer("<span id='pageText'>"); // 上一页翻页标记 if(currentPage > 1) { buff.append("[ <a href='" + pageUrl + "&page=" + (currentPage - 1) + "' title='转到第 " + (currentPage - 1) + " 页'>上一页</a> ] "); } else { buff.append("[ 上一页 ] "); } // 下一页翻页标记 if(currentPage < getTotalPage()) { buff.append("[ <a href='" + pageUrl + "&page=" + (currentPage + 1)+ "' title='转到第 " + (currentPage + 1) + " 页'>下一页</a> ] "); } else { buff.append("[ 下一页 ] "); } buff.append("</span>"); return buff.toString(); } /** * 输出页码信息: 第${currentPage}页/共${totalPage}页 * @return */ public String getPageCountHtml() { return "第" + currentPage + "页/共" + getTotalPage() + "页"; } /** * 输出 JavaScript 跳转函数代码 * @return */ public String getJavaScriptJumpCode() { if(StringUtil.isEmpty(pageUrl)) { return ""; } // 检查是否有参数符号, 没有就加上一个? if(pageUrl.indexOf("?") == -1) { pageUrl = pageUrl + '?'; } return "<script>" + "// 页面跳转函数\n" + "// 参数: 包含页码的单元素,例如输入框,下拉框等\n" + "function jumpPage(input) {\n" + " // 页码相同就不做跳转\n" + " if(input.value == " + currentPage + ") {" + " return;\n" + " }" + " var newUrl = '" + pageUrl + "&page=' + input.value;\n" + " document.location = newUrl;\n" + " }\n" + " </script>"; } /** * 输出页面跳转的选择框和输入框. 示例输出: * <pre> 转到 <!-- 输出 HTML SELECT 元素, 并选中当前页面编码 --> <select onchange='jumpPage(this);'> <c:forEach var="i" begin="1" end="${totalPage}"> <option value="${i}" <c:if test="${currentPage == i}"> selected </c:if> >第${i}页</option> </c:forEach> </select> 输入页码:<input type="text" value="${currentPage}" id="jumpPageBox" size="3"> <input type="button" value="跳转" onclick="jumpPage(document.getElementById('jumpPageBox'))"> </pre> * @return */ public String getPageFormJumpHtml() { String s = "转到\n" + "\t <!-- 输出 HTML SELECT 元素, 并选中当前页面编码 -->\n" + " <select onchange='jumpPage(this);'>\n" + " \n"; for(int i = 1; i <= getTotalPage(); i++ ) { s += "<option value=" + i + "\n"; if(currentPage == i) { s+= " selected "; } s += "\t>第" + i + "页</option>\n"; } s+= " </select>\n" + " 输入页码:<input type=\"text\" value=\"" + currentPage + "\" id=\"jumpPageBox\" size=\"3\"> \n" + " <input type=\"button\" value=\"跳转\" onclick=\"jumpPage(document.getElementById('jumpPageBox'))\"> "; return s; } /** * 进行分页计算. */ private void calculate() { if (getPageCount() == 0) { setPageCount(1); } totalPage = (int) Math.ceil(1.0 * getRecordCount() / getPageCount()); // 总页面数 if (totalPage == 0) totalPage = 1; // Check current page range, 2006-08-03 if(currentPage > totalPage) { currentPage = totalPage; } // System.out.println("currentPage=" + currentPage); // System.out.println("maxPage=" + maxPage); // // Fixed logic error at 2004-09-25 hasNextPage = currentPage < totalPage; hasPrevPage = currentPage > 1; return; } /** * @return Returns the 最大页面数. */ public int getTotalPage() { calculate(); return totalPage; } /** * @param currentPage * The 最大页面数 to set. */ @SuppressWarnings("unused") private void setTotalPage(int maxPage) { this.totalPage = maxPage; } /** * 是否有上一页数据 */ public boolean hasPrevPage() { calculate(); return hasPrevPage; } /** * 是否有下一页数据 */ public boolean hasNextPage() { calculate(); return hasNextPage; } // Test public static void main(String[] args) { PageBean pc = new PageBean(); pc.setCurrentPage(2); pc.setPageCount(4); pc.setRecordCount(5); pc.setPageUrl("product/list.do"); System.out.println("当前页 " + pc.getCurrentPage()); System.out.println("有上一页 " + pc.hasPrevPage()); System.out.println("有下一页 " + pc.hasNextPage()); System.out.println("总页面数 " + pc.getTotalPage()); System.out.println("分页 HTML 代码 " + pc.getPageJumpLinkHtml()); } /** * @return Returns the 当前页码数. */ public int getCurrentPage() { return currentPage; } /** * 设置当前页码, 从 1 开始. * @param currentPage * The 当前页码数 to set. */ public void setCurrentPage(int currentPage) { if (currentPage <= 0) { currentPage = 1; } this.currentPage = currentPage; } /** * @return Returns the recordCount. */ public int getRecordCount() { return recordCount; } /** * @param recordCount * The recordCount to set. */ public void setRecordCount(int property1) { this.recordCount = property1; } /** * @return Returns the 每页显示记录数. */ public int getPageCount() { return pageCount; } /** * @param pageCount * The 每页显示记录数 to set. */ public void setPageCount(int pageCount) { this.pageCount = pageCount; } public String getPageUrl() { return pageUrl; } public void setPageUrl(String value) { pageUrl = value; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值