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