客户修改功能--抽取Dao、Action--联系人模块以及对应的一对多问题

1、客户修改功能

1、修改链接跳转action。获取id对应的customer。
2、默认的customer压栈的了,action默认压栈,model(模型驱动)是action类的书写,getModel(返回customer对象)
3、跳转到edit的jsp页面
4、页面使用model获取对应的信息。ajax异步获得 select选择

从前端干起,通过list.jsp点击修改向后端传递用户id,后端action代码

public String initUpdate(){
		// 默认customer压栈的了,Action默认压栈,model是Action类的书写  getModel(返回customer对象)
		customer = customerService.findById(customer.getCust_id());
		return "initUpdate";
	}

将获得的对象回显示到edit.jsp页面上,在页面进行修改信息。注意上传文件这个点。点击保存后台代码

/**
	 * 修改客户的功能
	 * @return
	 * @throws IOException 
	 */
	public String update() throws IOException{
		// 判断,说明客户上传了新的图片
		if(uploadFileName != null){
			// 先删除旧的图片
			String oldFilepath = customer.getFilepath();
			if(oldFilepath != null && !oldFilepath.trim().isEmpty()){
				// 说明,旧的路径存在的,删除图片
				File f = new File(oldFilepath);
				f.delete();
			}
			// 上传新的图片
			// 先处理文件的名称的问题
			String uuidname = UploadUtils.getUUIDName(uploadFileName);
			String path = "D:\\apache-tomcat-7.0.52\\webapps\\upload\\";
			File file = new File(path+uuidname);
			FileUtils.copyFile(upload, file);
			// 把客户新图片的路径更新到数据库中
			customer.setFilepath(path+uuidname);
		}
		// 更新客户的信息就OK了
		customerService.update(customer);
		
		return "update";
	}
1. 先通过客户的主键查询出客户的详细信息,显示到修改的页面上
* 默认的customer压栈的了,action默认压栈,model(模型驱动)是action类的书写,getModel(返回customer对象)
* 要把客户的主键和上传文件的路径使用隐藏域保存起来
* 在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">

2、抽取dao层 先继承后实现

1、BaseDao<T>{} 定义一个泛型。包括 保存 删除 更新 根据id查询对象 查询所有 分页PageBean<T> findByPage(1,2,3)
2、创建实现类 BaseDaoImp 实现接口
3、CustomerDao 继承 BaseDao<Customer> 
4、CustomerDaoImp实现类 (java单继承多实现)BaseDaoImp
5、实现BaseDaoImp中的方法 *泛型*  难点:两个查询。 t.getclass是错误的。泛型的class 表示 private Class clazz
分页内容:创建分页对象,泛型、设置page对象的属性set方法 四个属性

当前页、展示的尺寸、总数量、封装查询的集合

BaseDao层代码

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);
	
}

BaseDaoImp代码

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 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;
	}
}

CustomerDaoImp层就可以什么都不写了

public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao {}

还有 第二种方式 

BaseDaoImp

BaseDaoImp 中 
	private Class clazz;
	public BaseDaoImp(Class clazz){
		this.clazz=clazz;
	}
在CustomerDaoImp中
	public CustomerDaoImpl() {
		super(Customer.class);调用父类的构造参数  进行传参
		// TODO Auto-generated constructor stub
	}


分页过程中代码是一样的,想到静态包含 <%@ include file="/jsp/page.jsp"%>

3、联系人模块

客户和联系人 理解为公司和员工比较好

一对多的关系,一方设置set集合,多方设置公司对象,并且一方放弃维护外键

在Customer中添加

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

同时在配置文件中加入

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

在联系人的实体类中,和配置文件中


抽取page的action 能够封装pageBean

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);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值