实训第六周/8/22/一个web项目的优化和升级(四)+菜品模块+分页+文件上传+2张表查询

菜品模块 难度高

分析回顾

分页+文件上传+2张表查询

首先菜系同之前的菜系类似的有 增删改查 的功能.
区别是 加入了分页 功能
在这里插入图片描述
这里菜的编号 不是主键
添加功能: 文件上传 + 数据回显 (2表查询菜系+菜品)
在这里插入图片描述
菜系本身是一张表,用的就是主外键关联. 同时会员价格注意使用精度高的属性 double等是不合适的
在这里插入图片描述
在这里插入图片描述

分页代码

https://blog.csdn.net/qq_39088066/article/details/100061186

这一部分最关键的就是SQL语句了
将查询到的数据 进行分页 获取
整个数据被分割成 一块一块的
整个数据可以根据条件做减法来 获得满足要求的数据

public class FoodDao implements IFoodDao {

	private QueryRunner qr = JdbcUtils.getQuerrRunner();


	@Override
	public Food findById(int id) {
		try {
			String sql = "SELECT * FROM food where id =?";
			return qr.query(sql, new BeanHandler<Food>(Food.class), id);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	@Override
	public List<Food> findByType(int type) {
		try {
			// 根据食物类型找到食物
			String sql = "SELECT * FROM food WHERE foodType_id =?";
			return qr.query(sql, new BeanListHandler<Food>(Food.class), type);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	@Override
	public List<Food> query(String keyword) {
		try {
			String sql = "SELECT * FROM food WHERE foodName LIKE ?";
			return qr.query(sql, new BeanListHandler<Food>(Food.class), "%" + keyword + "%");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}


@Override
	public int getTotalCount(PageBean<Food> pb) {
		// TODO Auto-generated method stub
		//按条件查询PageBean.Condition
		//因为s q l语句有大量相同的部分 所以使用字符串拼接的方法 节约代码String s = new String();[final类型定长 无法拼接]
		StringBuilder sb = new StringBuilder();//分配地址绝对空  toString()变为String
		sb.append("select count(*) from food f ,foodtype ft where f.foodType_id = ft.id ");
	
		List<Object> list = new ArrayList<Object>();//存放sql 内? 的参数
		
		//拿条件并分析 
		Condition condition = pb.getCondition();
		if(condition!=null){
			//按菜名查询
			String foodName =condition.getFoodName();
			if(foodName!=null&&!foodName.isEmpty()){//null ,new ,"" 情况都判断了
				//String a = new String此时a是分配了内存空间,但值为空,是绝对的空,是一种有值(值存在为空而已)
				//String b = ""此时b是分配了内存空间,值为空字符串,是相对的空,是一种有值(值存在为空字串)
				//String c =null此时c是未分配内存空间,无值,是一种无值(值不存在
			
				sb.append(" and f.foodName like ?");
				list.add("%"+foodName+"%");
			}
			
			// 菜系
			int type_id = condition.getFoodType_id();
			if (type_id > 0) {
				sb.append(" and f.foodType_id= ?");
				list.add(type_id);
			}
			
		}
		//sql凑完成 , ? 参数 编写完成
		//最终我们要一个记录数
		 
		try {
			
			Long count = qr.query(sb.toString(),new ScalarHandler<Long>(), list.toArray());//查询返回结果记录的第一行的第一列  (在聚合函数统计的时候用)
			//集合转数组  
			return count.intValue(); //Long 转换为整型
		
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}
		
	
		
	
	}

    //拿到分页后的每页的内容  没有返回值是因为返回内容传到PageBean类中了
	@Override
	public void getAll(PageBean<Food> pb) {
		 //1.拿到总记录数,并设置到PageBean
		int totalCount = this.getTotalCount(pb);
		pb.setTotalCount(totalCount);
		// 控制翻页 首页 尾页 边界控制
		if (pb.getCurrentPage() <= 0) {
			pb.setCurrentPage(1);
		} else if (pb.getCurrentPage() > pb.getTotalPage()) {
			pb.setCurrentPage(pb.getTotalPage());
		}

		// 2.获取当前页:计算limit index,count
		int currentPage = pb.getCurrentPage();
		int index = (currentPage - 1) * pb.getPageCount();//起始
		int count = pb.getPageCount();//返回行数

		// 3.分页查询数据,按foodName和foodType_id
		Condition condition = pb.getCondition();
		StringBuilder sb = new StringBuilder();
		sb.append("select f.id,f.foodName,f.foodType_id,f.price,f.mprice,f.remark,f.img,ft.typeName "
			+ "from food f,foodtype ft " + " where f.foodType_id=ft.id");
		// 存储查询条件的集合
				List<Object> list = new ArrayList<Object>();
				if (condition != null) {
					String foodName = condition.getFoodName();
					if (foodName != null && !foodName.isEmpty()) {
						sb.append(" and f.foodName like ?");
						list.add("%" + foodName + "%");
					}
					int type_id = condition.getFoodType_id();
					if (type_id > 0) {
						sb.append(" and f.foodType_id=?");
						list.add(type_id);
					}
				}
				sb.append(" limit ?,?");
				list.add(index);
				list.add(count);
				try {
					if (index >= 0) {
						List<Food> pageData = qr.query(sb.toString(), new BeanListHandler<Food>(Food.class), list.toArray());
						pb.setPageData(pageData);
					}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					throw new RuntimeException(e);
				}
			}
	
	
	
	

测试省略

下面开始业务层 业务层最有难度的就是 文件上传 和分页
下面重点介绍一下

文件上传

// 添加菜 (之前已经拿到菜系内容)
	private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
		FileItemFactory factory = new DiskFileItemFactory(); //拿到工厂对象
		ServletFileUpload upload = new ServletFileUpload(factory);//调用工具
		upload.setFileSizeMax(10 * 1024 * 1024);
		upload.setSizeMax(50 * 1024 * 1024);
		upload.setHeaderEncoding("UTF-8");
		
		
		if(upload.isMultipartContent(request)){
		 List<FileItem> list= upload.parseRequest(request);//拿到数据集合
		 Food food = new Food();
		 for(FileItem item : list){
//item---就是一条一条输入的内容 
			//是否文本
			 if(item.isFormField()){//法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,
				                    //如果是普通表单字段则返回true,否则返回false
				
				 String name=item.getFieldName(); //方法用于返回表单标签name属性的值:foodName
				String value=item.getString(); //对象中保存的数据流内容以一个字符串返回:麻婆豆腐
				value=new String(value.getBytes("ISO-8859-1"),"UTF-8");
				BeanUtils.setProperty(food, name, value);
			
			
			 } else {
					//文件
					String fieldName=item.getFieldName();//img
				    String path = this.getServletContext().getRealPath("/upload");
					
					File f=new File(path);
					if(!f.exists()){
						f.mkdirs();
					}
					String name=item.getName();//获得文件上传字段中的文件名
					BeanUtils.setProperty(food, fieldName, "upload/"+name);
					
					File file=new File(path,name);
					if(!file.isDirectory()){//是否是目录
						item.write(file);//write方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中
					}
					item.delete();
				 
					//InputStream getInputStream()    以流的形式返回上传文件的数据内容。
					// isInMemory方法用来判断FileItem对象封装的数据内容是存储在内存中,还是存储在临时文件中,
					//如果存储在内存中则返回true,否则返回false。
			 }
			 
		 }
		 
		 foodService.add(food);
		 list(request,response);
			
			
		}
		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


//dao
@Override
	public void add(Food food) {
		String sql = " INSERT food(foodName,foodType_id,price,mprice,remark,img) VALUES(?,?,?,?,?,?)";
		try {
			qr.update(sql, 
			food.getFoodName(), 
			food.getFoodType_id(), 
			food.getPrice(), 
			food.getMprice(),
            ood.getRemark(), 
            food.getImg());//照片
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

// 分页显示全部内容

	private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String currPage = request.getParameter("currentPage");//前台传来的当前页
		if (currPage == null || "".equals(currPage.trim())) {
			currPage = "1";
		}
		int currentPage = Integer.parseInt(currPage);
		PageBean<Food> pageBean = new PageBean<Food>();//拿到分页工具类
		pageBean.setCurrentPage(currentPage);
		foodService.getAll(pageBean);//拿到第一页的所有内容 5条存在了pageBean对象
		
		List<Food> list = pageBean.getPageData(); // 拿出food数据
		List<FoodType> types = new ArrayList<FoodType>(); // foodtype
		if (list != null) {
			for (Food food : list) {
				FoodType foodtype = foodTypeService.findById(food.getFoodType_id());//外键起作用 拿到对应的内容
				types.add(foodtype);
			}
		}
		request.setAttribute("list", list);
		request.setAttribute("types", types);
		request.setAttribute("pageBean", pageBean);

		uri = request.getRequestDispatcher("/sys/food/foodList.jsp");
		goTo(request, response, uri);
		
		
	}
	

// 统一跳转 优化 避免了重复写代码的尴尬

```javascript
private void goTo(HttpServletRequest request, HttpServletResponse response, Object uri)
		throws ServletException, IOException {
if (uri instanceof RequestDispatcher){
	((RequestDispatcher) uri).forward(request, response);
} else {
	response.sendRedirect(request.getContextPath()+(String) uri);
	
} }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值