从数据库中获取列表数据显示在页面
一 、后端部分
1.建立Meal实体类
这部分不多叙述,Meal类用来作为获取数据库数据的数据模型,主要包含private属性以及对应get和set方法。
代码:
public class Meal {
private Long meal_id;
private Double meal_price;
private String meal_desc;
private String meal_pic;
private Integer sm_store;
private Integer sm_sale;
private Integer sm_click;
public Long getMeal_id() {
return meal_id;
}
public void setMeal_id(Long meal_id) {
this.meal_id = meal_id;
}
public Double getMeal_price() {
return meal_price;
}
public void setMeal_price(Double meal_price) {
this.meal_price = meal_price;
}
public String getMeal_desc() {
return meal_desc;
}
public void setMeal_desc(String meal_desc) {
this.meal_desc = meal_desc;
}
public String getMeal_pic() {
return meal_pic;
}
public void setMeal_pic(String meal_pic) {
this.meal_pic = meal_pic;
}
public Integer getSm_store() {
return sm_store;
}
public void setSm_store(Integer sm_store) {
this.sm_store = sm_store;
}
public Integer getSm_sale() {
return sm_sale;
}
public void setSm_sale(Integer sm_sale) {
this.sm_sale = sm_sale;
}
public Integer getSm_click() {
return sm_click;
}
public void setSm_click(Integer sm_click) {
this.sm_click = sm_click;
}
}
2. MealServlet类新增mealList方法和路径
2.1 在MealServlet类中新增mealList方法,用来向前端发送数据库中的数据。
private void mealList(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String sql ="select * from t_meal";
MealQueryDto mealQueryDto = MyWeb.getBeanFromRequest(MealQueryDto.class,req);
Page page = PageFactory.getMySqlPage(Meal.class,mealQueryDto, DaoCreater.currentDao(),sql);
MyWeb.printJson(resp, R.OK(page));//以Json格式向前端发送数据
}
定义String类型的变量sql用来保存sql语句,向数据库查询数据。
从http请求中获取MealQueryDto的对象,使用getBeanFromRequest方法返回MealQueryDto的对象。
使用PageFactory.getMySqlPage()方法根据查询条件创建一个分页对象Page,其中包含了Meal类的实例
创建MealQueryDto类,暂时用不上,只创建就可以,mealQueryDto是作为查询条件的参数传递给方法,用于构建查询语句,DaoCreater.currentDao()方法调用返回一个当前线程相关联的数据访问对象,是用来执行数据库操作的,sql参数不多说。
printJson方法是以Json格式向前端发送数据。
最后R.OK(page)是一个将分页结果page封装为成功响应的表达,其中R.OK可能是一个状态常量,表示操作成功。
2.2 在@WebServlet注解中增加一个新的路径,在switch分支选择结构中执行新的方法。
@WebServlet({
"/meal/pic"
,"/meal/list"
})
2.3修改switch分支结构,新增 case "/mea/list"部分,执行mealList方法。
switch (path) {
case "/meal/pic":
mealPic(req, resp);
break;
case "/meal/list":
mealList(req,resp);
break;
}
3.MealServlet完整代码
@WebServlet({
"/meal/pic"
,"/meal/list"
})
public class MealServlet extends HttpServlet {
private static final String PIC_DIR = "C:\\Users\\GJC\\Pictures\\素材\\图片素材";
//获取服务端信息。将其作为相应返回给客户端
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
//客户端把数据发到服务端,发送适合大量数据
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getServletPath();
switch (path) {
case "/meal/pic":
mealPic(req, resp);
break;
case "/meal/list":
mealList(req,resp);
break;
}
}
private void mealList(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String sql ="select * from t_meal";
MealQueryDto mealQueryDto = MyWeb.getBeanFromRequest(MealQueryDto.class,req);
Page page = PageFactory.getMySqlPage(Meal.class,mealQueryDto, DaoCreater.currentDao(),sql);
MyWeb.printJson(resp, R.OK(page));//以Json格式向前端发送数据
}
private void mealPic(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String meal_pic = req.getParameter("meal_pic");
File picFile = new File(PIC_DIR, meal_pic);
//设置响应头为二进制数据
resp.setHeader("Content-Type", "application/octet-stream");
resp.setContentLength((int) picFile.length());
//向客户端发送数据
OutputStream out = resp.getOutputStream();
FileInputStream in = new FileInputStream(picFile);
byte[] types = new byte[1024 * 500];
int len = 0;
while ((len = in.read(types)) != -1) {
out.write(types,0,len);
}
out.flush();
out.close();
in.close();
}
}
4.后端运行效果
启动项目,在初始路径后面加上新定义的路径,回车。
效果大概就是这个样子,后面还需要前端将数据获取显示在页面上。
二、前端部分
1.定义变量,用来定义查询条件和存储后端的分页数据
//定义查询条件
const query = {
page:1,
rows:8
};
//从后端获取分页数据
let pageObj ={
total:0,
recIstanbul:[]
};
const和let都是变量定义的关键字,区别是const定义的变量不能再赋新值,let定义的变量则可以。但是如果const声明的变量是对象,那么对象的属性依旧可以赋新值。
2.定义函数,来获取数据
//定义函数从后端获取分页数据
//async表示该函数有异步操作
const getMealList =async (page=1)=> {
query.page = page;
//fetch函数负责向后端发送请求,获取响应
const response = await fetch(`./meal/list?page=${query.page}&rows=${query.rows}`);
if (!response.ok) return;
const result = await response.json();//从响应中取出Json数据
if (!result.success) return;
pageObj = result.data;
const list = pageObj.recList;
console.log(list);
fetch函数发起一个http请求,包含了查询参数page和rows,如果响应是OK状态,那就解析为Json格式的数据,
存在result变量中,如果result.success为真,将result.data赋值给全局变量pageObj,并从中提取出recL
ist属性的值,将其存储在局部变量list中。然后,它打印出list的内容,便于我们检查是否获取到数据。
启动项目,在初始页面,打开开发人员工具(F12),刷新页面,在控制台就可以看到已经获取到了数据
3.将获取的信息显示在页面
let innerHTML = "";
for (let i = 0; i < list.length; i++) {
const meal = list[i];
let card = `
<div class="card border-0 p-2" style="width: 23%;margin-bottom: 20px;" >
<img src="/meal/pic?meal_pic=${meal.meal_pic}" class="h-75 object-fit-cover card-img-top rounded-1" alt="...">
<div class="card-body px-0 pb-0" >
<h5 class="card-title fw-bold text-secondary">${meal.meal_desc}</h5>
<div class="card-text d-flex justify-content-between mb-2">
<span class="text-body-tertiary fs-6">已售 ${meal.sm_sale}</span>
<span class="text-body-tertiary fs-6">库存 ${meal.sm_store}</span>
<span class="text-body-tertiary fs-6">点击 ${meal.sm_click}</span>
</div>
<div class="d-flex justify-content-between align-items-center" >
<span class="text-danger fs-5 fw-bold">¥${meal.meal_price}</span>
<img src="./images/shopping-cart.png" style="height:35px;cursor: pointer;" class="pe-1">
</div>
</div>
</div>
`;
innerHTML += card;
}
document.querySelector("#mealList").innerHTML = innerHTML;
document.querySelector("#pageInfo").innerHTML = `
当前第${pageObj.curr}页${pageObj.currRows}条记录,共${pageObj.paTal}页${
pageObj.total
}条记录`;
}
getMealList();
获取出数据后,就遍历数据显示在元素中,根据list的数组生成一组卡片,
通过ocument.querySelector(“#mealList”).innerHTML = innerHTML;
将这些卡片插入到页面中的mealList元素中,原本mealList元素中的静态的卡片就可以删掉,只保留一行代码,
<div id="mealList" class=" d-flex flex-wrap justify-content-between"></div>
这样从数据库获取的图片数据就可以在mealList元素中显示。
。同时同理更新了页面上的#pageInfo元素,显示当前页数、当前页记录数、总页数和总记录数。最后,调用getMealList()函数来执行这个操作。