Compare commits

...

13 Commits

@ -20,62 +20,87 @@ INSERT INTO t_user(username,`password`,email,address) VALUES('admin','admin','ad
## 查询表
SELECT * FROM t_user;
-- 创建名为t_book的表
CREATE TABLE t_book(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(100),
`price` DECIMAL(11,2),
`author` VARCHAR(100),
`classification` VARCHAR(20),
`sales` INT,
`stock` INT,
`imgpath` VARCHAR(200)
-- 定义名为id的字段数据类型为INT整数类型将其设置为主键并且设置为自增AUTO_INCREMENT这样每插入一条新记录时该字段的值会自动按顺序递增用于为每本图书生成唯一的标识符
`id` INT PRIMARY KEY AUTO_INCREMENT,
-- 定义名为name的字段数据类型为VARCHAR可变长度字符串长度为100用于存储图书的书名信息
`name` VARCHAR(100),
-- 定义名为price的字段数据类型为DECIMAL精确数值类型总长度为11位其中小数部分占2位用于存储图书的价格信息
`price` DECIMAL(11,2),
-- 定义名为author的字段数据类型为VARCHAR长度为100用来记录图书的作者姓名
`author` VARCHAR(100),
-- 定义名为classification的字段数据类型为VARCHAR长度为20可用于存储图书的分类信息例如文学、科技等类别
`classification` VARCHAR(20),
-- 定义名为sales的字段数据类型为INT用于记录图书的销量情况
`sales` INT,
-- 定义名为stock的字段数据类型为INT用于表示图书的库存数量
`stock` INT,
-- 定义名为imgpath的字段数据类型为VARCHAR长度为200可用于存储图书封面图片的路径信息方便在应用中展示图书封面图片
`imgpath` VARCHAR(200)
);
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('解忧杂货店','东野圭吾','文学',27.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('边城','沈从文','文学',23.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('中国哲学史','冯友兰','文学',44.5,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('苏东坡传','林语堂','文学',19.30,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('百年孤独','马尔克斯','文学',29.50,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('扶桑','严歌苓','文学',19.8,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('给孩子的诗','北岛','文学',22.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('为奴十二年','所罗门','文学',16.5,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('平凡的世界','路遥','文学',55.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('悟空传','今何在','文学',14.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('硬派健身','斌卡','文学',31.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('从晚清到民国','唐德刚','文学',39.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('三体','刘慈欣','文学',56.5,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('看见','柴静','文学',19.50,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('活着','余华','文学',11.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('小王子','安托万','文学',19.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('我们仨','杨绛','文学',11.30,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification,price, sales , stock , imgpath) VALUES('生命不息,折腾不止','罗永浩','文学',25.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification,price, sales , stock , imgpath) VALUES('皮囊','蔡崇达','文学',23.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('恰到好处的幸福','毕淑敏','文学',16.40,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('大数据预测','埃里克','文学',37.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('人月神话','布鲁克斯','文学',55.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('C语言入门经典','霍尔顿','文学',45.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('数学之美','吴军','文学',29.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('Java编程思想','埃史尔','文学',70.50,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('设计模式之禅','秦小波','文学',20.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('图解机器学习','杉山将','文学',33.80,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('艾伦图灵传','安德鲁','文学',47.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales , stock , imgpath) VALUES('教父','马里奥普佐','文学',29.00,100,100,'static/img/default.jpg');
-- 向t_book表中插入一条图书数据记录指定要插入值的字段为name, author, classification, price, sales, stock, imgpath并对应给出具体的值分别为图书的书名、作者、分类、价格、销量、库存以及封面图片路径
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('解忧杂货店','东野圭吾','文学',27.20,100,100,'static/img/default.jpg');
-- 同样是向t_book表中插入图书数据记录以下每条INSERT语句的结构和作用与上面类似只是对应不同的图书信息
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('边城','沈从文','文学',23.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('中国哲学史','冯友兰','文学',44.5,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('苏东坡传','林语堂','文学',19.30,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('百年孤独','马尔克斯','文学',29.50,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('扶桑','严歌苓','文学',19.8,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('给孩子的诗','北岛','文学',22.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('为奴十二年','所罗门','文学',16.5,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('平凡的世界','路遥','文学',55.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('悟空传','今何在','文学',14.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('硬派健身','斌卡','文学',31.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('从晚清到民国','唐德刚','文学',39.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('三体','刘慈欣','文学',56.5,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('看见','柴静','文学',19.50,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('活着','余华','文学',11.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('小王子','安托万','文学',19.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('我们仨','杨绛','文学',11.30,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification,price, sales, stock, imgpath) VALUES('生命不息,折腾不止','罗永浩','文学',25.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification,price, sales, stock, imgpath) VALUES('皮囊','蔡崇达','文学',23.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('恰到好处的幸福','毕淑敏','文学',16.40,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('大数据预测','埃里克','文学',37.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('人月神话','布鲁克斯','文学',55.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('C语言入门经典','霍尔顿','文学',45.00,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('数学之美','吴军','文学',29.90,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('Java编程思想','埃史尔','文学',70.50,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('设计模式之禅','秦小波','文学',20.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('图解机器学习','杉山将','文学',33.80,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('艾伦图灵传','安德鲁','文学',47.20,100,100,'static/img/default.jpg');
INSERT INTO t_book (name, author, classification, price, sales, stock, imgpath) VALUES('教父','马里奥普佐','文学',29.00,100,100,'static/img/default.jpg');
-- 创建名为t_order的表
CREATE TABLE t_order(
`order_id` VARCHAR(50) PRIMARY KEY,
`create_time` DATETIME,
`price` DECIMAL(11,2),
`status` INT,
`user_id` INT,
FOREIGN KEY(`user_id`) REFERENCES t_user(`id`)
-- 定义名为order_id的字段数据类型为VARCHAR可变长度字符串长度为50并且将该字段设置为主键用于唯一标识每条订单记录
`order_id` VARCHAR(50) PRIMARY KEY,
-- 定义名为create_time的字段数据类型为DATETIME用于存储日期和时间信息用来记录订单创建的时间
`create_time` DATETIME,
-- 定义名为price的字段数据类型为DECIMAL精确数值类型总长度为11位其中小数部分占2位用于存储订单的价格信息
`price` DECIMAL(11,2),
-- 定义名为status的字段数据类型为INT整数类型可能用于表示订单的状态比如不同的数值对应不同的订单处理阶段等情况
`status` INT,
-- 定义名为user_id的字段数据类型为INT该字段将作为外键与另一个表t_user中的id字段建立关联关系
`user_id` INT,
-- 使用FOREIGN KEY关键字为user_id字段添加外键约束指定它参照t_user表中的id字段意味着t_order表中的user_id值必须在t_user表的id字段值中存在以此建立起两张表之间的关联通常表示订单所属的用户
FOREIGN KEY(`user_id`) REFERENCES t_user(`id`)
);
-- 创建名为t_order_item的表
CREATE TABLE t_order_item(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(100),
`count` INT,
`price` DECIMAL(11,2),
`total_price` DECIMAL(11,2),
`order_id` VARCHAR(50),
FOREIGN KEY(`order_id`) REFERENCES t_order(`order_id`)
-- 定义名为id的字段数据类型为INT整数类型并将该字段设置为主键同时设置为自增AUTO_INCREMENT这样每当插入一条新记录时该字段的值会自动按顺序递增常用于为每条记录生成唯一的标识符
`id` INT PRIMARY KEY AUTO_INCREMENT,
-- 定义名为name的字段数据类型为VARCHAR长度为100可用于存储商品名称等相关信息比如订单中具体商品的名字
`name` VARCHAR(100),
-- 定义名为count的字段数据类型为INT用于记录商品的数量比如某个商品在该订单中的购买数量
`count` INT,
-- 定义名为price的字段数据类型为DECIMAL总长度11位小数部分占2位可能用于存储单个商品的价格信息
`price` DECIMAL(11,2),
-- 定义名为total_price的字段数据类型为DECIMAL总长度11位小数部分占2位用于存储该商品的总价可能是通过商品单价乘以数量计算得出
`total_price` DECIMAL(11,2),
-- 定义名为order_id的字段数据类型为VARCHAR长度为50该字段将作为外键与t_order表中的order_id字段建立关联关系
`order_id` VARCHAR(50),
-- 使用FOREIGN KEY关键字为order_id字段添加外键约束指定它参照t_order表中的order_id字段意味着t_order_item表中的order_id值必须在t_order表的order_id字段值中存在以此建立起两张表之间的关联表明该订单项所属的订单
FOREIGN KEY(`order_id`) REFERENCES t_order(`order_id`)
);

@ -5,88 +5,176 @@ import java.math.BigDecimal;
/**
* @author yj
* @create 2020-10-02 19:51
*
* BookID
*/
public class Book {
private Integer id;//id
private String name;//姓名
private String author;//作者
// 书籍的唯一标识符
private Integer id;
// 书籍的名称
private String name;
// 书籍的作者
private String author;
// 书籍的价格使用BigDecimal类型以确保精度
private BigDecimal price;
// 书籍的销量
private Integer sales;
// 书籍的库存数量
private Integer stock;
// 书籍的分类
private String classification;
private String imgPath="static/img/default.jpg";
// 书籍的图片路径,默认值为"static/img/default.jpg"
private String imgPath = "static/img/default.jpg";
/**
*
* @return
*/
public String getClassification() {
return classification;
}
/**
*
* @param classification
*/
public void setClassification(String classification) {
this.classification = classification;
}
/**
* ID
* @return ID
*/
public Integer getId() {
return id;
}
/**
* ID
* @param id ID
*/
public void setId(Integer id) {
this.id = id;
}
/**
*
* @return
*/
public String getName() {
return name;
}
/**
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* @return
*/
public String getAuthor() {
return author;
}
/**
*
* @param author
*/
public void setAuthor(String author) {
this.author = author;
}
/**
*
* @return
*/
public BigDecimal getPrice() {
return price;
}
/**
*
* @param price
*/
public void setPrice(BigDecimal price) {
this.price = price;
}
/**
*
* @return
*/
public Integer getSales() {
return sales;
}
/**
*
* @param sales
*/
public void setSales(Integer sales) {
this.sales = sales;
}
/**
*
* 00
* @return
*/
public Integer getStock() {
if(stock<0) stock=0;return stock;
if (stock < 0) stock = 0;
return stock;
}
/**
*
* 00
* @param stock
*/
public void setStock(Integer stock) {
if(stock<0) stock=0;
if (stock < 0) stock = 0;
this.stock = stock;
}
/**
*
* @return
*/
public String getImgPath() {
return imgPath;
}
/**
*
* null使"static/img/default.jpg"
* @param imgPath
*/
public void setImgPath(String imgPath) {
if(imgPath==null||"".equals(imgPath)) {
if (imgPath == null || "".equals(imgPath)) {
this.imgPath = "static/img/default.jpg";
} else {
this.imgPath = imgPath;
}
}
/**
* toString
* @return
*/
@Override
public String toString() {
return "Book{" +
@ -101,9 +189,23 @@ public class Book {
'}';
}
/**
*
*/
public Book() {
}
/**
*
* @param id ID
* @param name
* @param author
* @param price
* @param sales
* @param stock
* @param classification
* @param imgPath
*/
public Book(Integer id, String name, String author, BigDecimal price, Integer sales, Integer stock, String classification, String imgPath) {
this.id = id;
this.name = name;
@ -114,4 +216,4 @@ public class Book {
this.classification = classification;
this.imgPath = imgPath;
}
}
}

@ -13,93 +13,128 @@ import java.util.Map;
*
*/
public class Cart {
// 注释掉的代码表示之前可能考虑过直接存储总数和总价,但在此实现中,选择动态计算这些值
//private Integer totalCount;
//private BigDecimal totalPrice;
/**
*
*/
public Integer getTotalCount() {
Integer totalCount = 0;
// 初始化总数量为0
for (Map.Entry<Integer,CartItem>entry : items.entrySet()) {
// 遍历购物车中的每一项
totalCount += entry.getValue().getCount();
// 累加每一项的数量
}
return totalCount;
// 返回总数量
}
/**
*
*/
public BigDecimal getTotalPrice() {
BigDecimal totalPrice = new BigDecimal(0);
// 初始化总价格为0
for (Map.Entry<Integer,CartItem>entry : items.entrySet()) {
// 遍历购物车中的每一项
totalPrice = totalPrice.add(entry.getValue().getTotalPrice());
// 累加每一项的总价格
}
return totalPrice;
// 返回总价格
}
/**
*
*/
public Map<Integer, CartItem> getItems() {
return items;
// 返回购物车中的商品项
}
/**
*
*/
public void setItems(Map<Integer, CartItem> items) {
this.items = items;
// 设置购物车中的商品项
}
/**
* keyvalue
* Mapkeyvalue使LinkedHashMap
*/
private Map<Integer,CartItem> items = new LinkedHashMap<Integer, CartItem>();
/**
* toString
*/
@Override
public String toString() {
return "Cart{" +
"totalCount=" + getTotalCount() +
// 总数量
", totalPrice=" + getTotalPrice() +
// 总价格
", items=" + items +
// 商品项
'}';
}
/**
*
* @param cartItem
*
* @param cartItem
*/
public void addItem(CartItem cartItem) {
//先查看购物车中是否包含次商品,如果有的话,数量更新,总金额更新;如果没有,直接放到集合中即可
// 先查看购物车中是否包含此商品
CartItem item = items.get(cartItem.getId());
if(item == null) {
//之前没有添加过此商品
// 之前没有添加过此商品,直接添加到购物车中
items.put(cartItem.getId(),cartItem);
} else {
item.setCount(item.getCount() + 1);//数量累计
item.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getCount())));//更新总金额
// 购物车中已有此商品数量加1并更新总金额
item.setCount(item.getCount() + 1);
// 数量累计
item.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getCount())));
// 更新总金额
}
}
/**
*
* @param id
*
* @param id
*/
public void deleteItem(Integer id) {
items.remove(id);
// 从购物车中删除指定编号的商品项
}
/**
*
*
*/
public void clear() {
items.clear();
// 清空购物车
}
/**
*
* @param id
* @param count
*
* @param id
* @param count
*/
public void updateCount(Integer id,Integer count) {
//先查看购物车中是否包含次商品,如果有的话,数量更新,总金额更新;
// 先查看购物车中是否包含此商品项
CartItem cartItem = items.get(id);
if(cartItem != null) {
cartItem.setCount(count);
cartItem.setTotalPrice(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount())));
if(cartItem != null) {
// 购物车中已有此商品项,修改数量并更新总金额
cartItem.setCount(count);
// 修改数量
cartItem.setTotalPrice(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount())));
// 更新总金额
}
}
}
}

@ -10,72 +10,101 @@ import java.math.BigDecimal;
/**
*
*/
// 定义一个名为CartItem的类代表购物车中的一个商品项
public class CartItem {
// 定义一个私有变量id用于存储商品的唯一标识符
private Integer id;
// 定义一个私有变量name用于存储商品的名称
private String name;
// 定义一个私有变量count用于存储商品的数量
private Integer count;
// 定义一个私有变量price用于存储商品的单价使用BigDecimal类型以支持精确的小数计算
private BigDecimal price;
// 定义一个私有变量totalPrice用于存储商品的总价单价乘以数量同样使用BigDecimal类型
private BigDecimal totalPrice;
// 定义一个公开的getter方法用于获取商品的id
public Integer getId() {
return id;
}
// 定义一个公开的setter方法用于设置商品的id
public void setId(Integer id) {
this.id = id;
}
// 定义一个公开的getter方法用于获取商品的名称
public String getName() {
return name;
}
// 定义一个公开的setter方法用于设置商品的名称
public void setName(String name) {
this.name = name;
}
// 定义一个公开的getter方法用于获取商品的数量
public Integer getCount() {
return count;
}
// 定义一个公开的setter方法用于设置商品的数量
public void setCount(Integer count) {
this.count = count;
}
// 定义一个公开的getter方法用于获取商品的单价
public BigDecimal getPrice() {
return price;
}
// 定义一个公开的setter方法用于设置商品的单价
public void setPrice(BigDecimal price) {
this.price = price;
}
// 定义一个公开的getter方法用于获取商品的总价
public BigDecimal getTotalPrice() {
return totalPrice;
}
// 定义一个公开的setter方法用于设置商品的总价
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}
// 定义一个公开的构造方法用于创建CartItem对象并初始化其所有属性
public CartItem(Integer id, String name, Integer count, BigDecimal price, BigDecimal totalPrice) {
// 使用this关键字将传入的id参数赋值给当前对象的id属性
this.id = id;
// 设置商品的唯一标识符
// 使用this关键字将传入的name参数赋值给当前对象的name属性
this.name = name;
// 设置商品的名称
// 使用this关键字将传入的count参数赋值给当前对象的count属性
this.count = count;
// 设置商品的数量
// 使用this关键字将传入的price参数赋值给当前对象的price属性
this.price = price;
// 设置商品的单价使用BigDecimal类型以支持精确的小数计算
// 使用this关键字将传入的totalPrice参数赋值给当前对象的totalPrice属性
this.totalPrice = totalPrice;
// 设置商品的总价单价乘以数量同样使用BigDecimal类型
}
// 定义一个无参构造方法用于创建CartItem对象时不初始化任何属性
public CartItem() {
}
// 重写toString方法用于返回CartItem对象的字符串表示形式
@Override
public String toString() {
// 返回的字符串包含CartItem对象的所有属性信息
return "Cart{" +
"id=" + id +
// 显示商品的id
", name='" + name + '\'' +
// 显示商品的名称
", count=" + count +
// 显示商品的数量
", price=" + price +
// 显示商品的单价
", totalPrice=" + totalPrice +
// 显示商品的总价
'}';
}
}

@ -1,90 +1,118 @@
package com.yj.bean;
// 定义包名,用于组织相关的类和接口
import java.util.List;
// 导入List接口用于存储数据集合
/**
* @author yj
* @create 2020-08-25 9:27
* @author yj // 类的作者
* @create 2020-08-25 9:27 // 类的创建时间
*/
public class Page <T>{
// 定义一个泛型类PageT表示该Page类可以持有任何类型的对象
public static final Integer PAGE_SIZE = 4;
// 定义一个常量,表示每页显示的数据条数
//当前页
private Integer pageNo;
// 当前页码
//总页码
private Integer pageTotal;
// 总页数
//当前页显示数量
private Integer pageSize = PAGE_SIZE;
// 每页显示的数据条数默认为常量PAGE_SIZE的值
//总的记录数
private Integer pageTotalCount;
// 数据总条数
//当前页数据
private List<T> items;
// 存储当前页的数据
//分页条的请求地址
private String url;
// 分页条请求的URL地址
// 获取分页条请求的URL地址
public String getUrl() {
return url;
}
// 设置分页条请求的URL地址
public void setUrl(String url) {
this.url = url;
}
// 获取当前页码
public Integer getPageNo() {
return pageNo;
}
// 获取总页数
public Integer getPageTotal() {
return pageTotal;
}
// 设置总页数
public void setPageTotal(Integer pageTotal) {
this.pageTotal = pageTotal;
}
// 获取每页显示的数据条数
public Integer getPageSize() {
return pageSize;
}
// 设置每页显示的数据条数
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
// 获取数据总条数
public Integer getPageTotalCount() {
return pageTotalCount;
}
// 设置数据总条数
public void setPageTotalCount(Integer pageTotalCount) {
this.pageTotalCount = pageTotalCount;
}
// 获取当前页的数据
public List<T> getItems() {
return items;
}
// 设置当前页的数据
public void setItems(List<T> items) {
this.items = items;
}
// 设置当前页码
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
// 重写toString方法用于打印Page对象的详细信息
@Override
public String toString() {
return "Page{" +
"pageNo=" + pageNo +
// 当前页码
", pageTotal=" + pageTotal +
// 总页数
", pageSize=" + pageSize +
// 每页显示的数据条数
", pageTotalCount=" + pageTotalCount +
// 数据总条数
", items=" + items +
// 当前页的数据
", url='" + url + '\'' +
// 分页条请求的URL地址
'}';
}
}
}

@ -8,34 +8,108 @@ import java.util.List;
/**
* @author yj
* @create 2020-08-23 21:08
*
* BookDao
*/
public interface BookDao {
/**
*
* @param book
* @return 10
*/
public int addBook(Book book);
/**
* ID
* @param id ID
* @return 10
*/
public int deleteBookById(Integer id);
/**
*
* @param book
* @return 10
*/
public int updateBook(Book book);
/**
* ID
* @param id ID
* @return null
*/
public Book queryBookById(Integer id);
/**
*
* @return
*/
public List<Book> queryBooks();
/**
*
* @return
*/
Integer queryForPageTotalCount();
/**
*
* @param begin
* @param pageSize
* @return
*/
List<Book> queryForPageItems(int begin, int pageSize);
/**
*
* @param min
* @param max
* @return
*/
Integer queryForPageTotalCountByPrice(int min, int max);
/**
*
* @param begin
* @param pageSize
* @param min
* @param max
* @return
*/
List<Book> queryForPageItemsByPrice(int begin, int pageSize, int min, int max);
/**
*
* @param nameorauthor
* @return
*/
Integer queryForPageTotalCountByNameOrAuthor(String nameorauthor);
/**
*
* @param begin
* @param pageSize
* @param nameorauthor
* @return
*/
List<Book> queryForPageItemsByNameOrAuthor(int begin, int pageSize, String nameorauthor);
/**
*
* @return
*/
List<Book> queryForPageItemsOrder();
/**
*
* @return
*/
BigDecimal queryTotalMoney();
/**
*
* @return
*/
public Integer queryBooknums();
}
}

@ -1,85 +1,124 @@
package com.yj.dao.impl;
// 定义包名,组织相关的类
import com.yj.utils.JDBCUtils;
// 导入JDBC工具类用于获取数据库连接
import org.apache.commons.dbutils.QueryRunner;
// 导入DbUtils的QueryRunner类用于简化JDBC操作
import org.apache.commons.dbutils.handlers.BeanHandler;
// 导入BeanHandler用于将结果集的第一行数据封装为JavaBean对象
import org.apache.commons.dbutils.handlers.BeanListHandler;
// 导入BeanListHandler用于将结果集的每一行数据封装为JavaBean对象并存储在List集合中
import org.apache.commons.dbutils.handlers.ScalarHandler;
// 导入ScalarHandler用于返回结果集的一行一列数据
import java.sql.Connection;
// 导入Connection接口用于数据库连接
import java.sql.SQLException;
// 导入SQLException类处理SQL异常
import java.util.List;
// 导入List接口用于存储数据集合
/**
* @author yj
* @create 2020-08-21 11:32
* @author yj // 类的作者
* @create 2020-08-21 11:32 // 类的创建时间
*/
public abstract class BaseDao {
//使用DbUtils操作数据库
// 定义一个抽象类BaseDao作为数据访问层的基类
// 使用DbUtils操作数据库
private QueryRunner queryRunner = new QueryRunner();
/*
*update()Insert\Update\Delete
// 初始化QueryRunner对象用于执行SQL语句
/**
* update()Insert\Update\Delete
* @param sql SQL
* @param args SQL
* @return -1
*/
public int update(String sql,Object ... args) {
public int update(String sql, Object ... args) {
Connection connection = JDBCUtils.getConnection();
// 调用JDBCUtils工具类获取数据库连接
try {
return queryRunner.update(connection,sql,args);
// 使用QueryRunner的update方法执行更新操作并返回影响的行数
return queryRunner.update(connection, sql, args);
} catch (SQLException e) {
e.printStackTrace();
// 打印SQL异常堆栈信息
throw new RuntimeException(e);
// 将SQL异常转换为运行时异常抛出
} finally {
// 注意原代码中缺少了关闭连接的逻辑应在此处添加但在实际使用中JDBCUtils的getConnection可能已负责关闭
// JDBCUtils.close(connection); // 关闭数据库连接
}
}
/**
*JavabeanSQL
* JavabeanSQL
* @param type
* @param sql sql
* @param args sql
* @param sql SQL
* @param args SQL
* @param <T>
* @return
* @return JavaBean
*/
public <T> T queryForOne(Class<T> type,String sql,Object ... args) {
public <T> T queryForOne(Class<T> type, String sql, Object ... args) {
Connection connection = JDBCUtils.getConnection();
// 获取数据库连接
try {
return queryRunner.query(connection,sql,new BeanHandler<T>(type),args);
// 使用QueryRunner的query方法执行查询操作并将结果集的第一行数据封装为指定的JavaBean对象
return queryRunner.query(connection, sql, new BeanHandler<T>(type), args);
} catch (SQLException e) {
e.printStackTrace();
// 打印SQL异常堆栈信息
throw new RuntimeException(e);
// 将SQL异常转换为运行时异常抛出
} finally {
// 注意:同样缺少了关闭连接的逻辑,应在实际使用中添加
}
}
/**
*JavabeanSQL
* JavabeanSQL
* @param type
* @param sql sql
* @param args sql
* @param sql SQL
* @param args SQL
* @param <T>
* @return
* @return JavaBean
*/
public <T> List<T> queryForList(Class<T> type, String sql, Object ... args) {
Connection connection = JDBCUtils.getConnection();
// 获取数据库连接
try {
return queryRunner.query(connection,sql,new BeanListHandler<T>(type),args);
// 使用QueryRunner的query方法执行查询操作并将结果集的每一行数据封装为指定的JavaBean对象存储在List集合中返回
return queryRunner.query(connection, sql, new BeanListHandler<T>(type), args);
} catch (SQLException e) {
e.printStackTrace();
// 打印SQL异常堆栈信息
throw new RuntimeException(e);
// 将SQL异常转换为运行时异常抛出
} finally {
// 注意:同样缺少了关闭连接的逻辑,应在实际使用中添加
}
}
/**
* sql
* @param sql sql
* @param args sql
* @return
* SQL
* @param sql SQL
* @param args SQL
* @return
*/
public Object queryForSingleValue(String sql,Object ... args) {
public Object queryForSingleValue(String sql, Object ... args) {
Connection connection = JDBCUtils.getConnection();
// 获取数据库连接
try {
return queryRunner.query(connection,sql,new ScalarHandler(),args);
}catch (SQLException e) {
// 使用QueryRunner的query方法执行查询操作并返回结果集的一行一列数据
return queryRunner.query(connection, sql, new ScalarHandler(), args);
} catch (SQLException e) {
e.printStackTrace();
// 打印SQL异常堆栈信息
throw new RuntimeException(e);
// 将SQL异常转换为运行时异常抛出
} finally {
// 注意同样缺少了关闭连接的逻辑但在实际中JDBCUtils的getConnection可能已负责关闭连接
}
}
}
}

@ -9,28 +9,84 @@ import java.util.List;
/**
* @author yj
* @create 2020-08-24 14:40
*
* BookService
*/
public interface BookService {
/**
*
* @param book
*/
public void addBook(Book book);
/**
*
* @param book
*/
public void updateBook(Book book);
/**
* ID
* @param id ID
*/
public void deleteBookById(Integer id);
/**
* ID
* @param id ID
* @return null
*/
public Book queryBookById(Integer id);
/**
*
* @return
*/
public List<Book> queryBooks();
/**
*
* @param pageNo
* @param pageSize
* @return
*/
Page<Book> page(int pageNo, int pageSize);
/**
*
* @param pageNo
* @param pageSize
* @param min
* @param max
* @return
*/
Page<Book> pageByPrice(int pageNo, int pageSize, int min, int max);
/**
*
* @param pageNo
* @param pageSize
* @param nameOrAuthor
* @return
*/
Page<Book> pageByNameOrAuthor(int pageNo, int pageSize, String nameOrAuthor);
/**
*
* @return
*/
Page<Book> pageOrder();
/**
*
* @return
*/
public Integer queryTotalBooks();
/**
*
* @return
*/
BigDecimal queryTotalMoney();
}
}

@ -10,59 +10,102 @@ import java.math.BigDecimal;
/**
* @author yj
* @create 2020-08-24 11:01
*
* BookDaoTestBookDaoBookDaoImpl
* JUnit
*/
public class BookDaoTest {
// 创建BookDao接口的实现类BookDaoImpl对象
BookDao bookDao = new BookDaoImpl();
/**
*
*/
@Test
public void addBook() {
//`name`,`author`,`classification`,`price`,`sales`,`stock`,`img_path`
//Integer id, String name, String author, BigDecimal price, Integer sales, Integer stock, String classification, String imgPath)
bookDao.addBook(new Book(null,"舌的中国","yjjj",new BigDecimal("5"),100,23,"",""));
// 创建一个新的Book对象并调用addBook方法将其添加到数据库中
bookDao.addBook(new Book(null, "舌的中国", "yjjj", new BigDecimal("5"), 100, 23, "", ""));
}
/**
*
*/
@Test
public void deleteBook() {
// 调用deleteBookById方法删除ID为3的书籍
bookDao.deleteBookById(3);
}
/**
* ID
*/
@Test
public void queryById() {
// 调用queryBookById方法查询ID为64的书籍并打印结果
System.out.println(bookDao.queryBookById(64));
}
/**
*
*/
@Test
public void update() {
bookDao.updateBook(new Book(35,"舌尖的中国","yj",new BigDecimal("5"),100,23,"文学",""));
// 创建一个新的Book对象并调用updateBook方法更新ID为35的书籍信息
bookDao.updateBook(new Book(35, "舌尖的中国", "yj", new BigDecimal("5"), 100, 23, "文学", ""));
}
/**
*
*/
@Test
public void queryList() {
// 调用queryBooks方法查询所有书籍并打印结果
System.out.println(bookDao.queryBooks());
}
/**
*
*/
@Test
public void queryForPageTotalCount() {
// 调用queryForPageTotalCount方法查询所有书籍的总记录数并打印结果
System.out.println(bookDao.queryForPageTotalCount());
}
/**
*
*/
@Test
public void queryForPageItems() {
System.out.println(bookDao.queryForPageItems(1,4));
// 调用queryForPageItems方法分页查询书籍并打印结果
System.out.println(bookDao.queryForPageItems(1, 4));
}
/**
*
*/
@Test
public void queryForPageTotalCountByPrice() {
System.out.println(bookDao.queryForPageTotalCountByPrice(10,50));
// 调用queryForPageTotalCountByPrice方法查询价格在10到50之间的书籍总记录数并打印结果
System.out.println(bookDao.queryForPageTotalCountByPrice(10, 50));
}
/**
*
*/
@Test
public void queryForPageItemsByPrice() {
System.out.println(bookDao.queryForPageItemsByPrice(1,4,10,50));
// 调用queryForPageItemsByPrice方法根据价格范围分页查询书籍并打印结果
System.out.println(bookDao.queryForPageItemsByPrice(1, 4, 10, 50));
}
/**
*
*/
@Test
public void queryBooknums() {
// 调用queryBooknums方法查询书籍的总数量并打印结果
System.out.println(bookDao.queryBooknums());
}
}
}

@ -12,43 +12,78 @@ import java.math.BigDecimal;
/**
* @author yj
* @create 2020-08-24 14:57
*
* BookServiceTestBookServiceBookServiceImpl
* JUnit
*/
public class BookServiceTest {
// 创建BookDao接口的实现类BookDaoImpl对象
private BookDao bookDao = new BookDaoImpl();
// 创建BookService接口的实现类BookServiceImpl对象
private BookService bookService = new BookServiceImpl();
/**
*
*/
@Test
public void addBook() {
bookDao.addBook(new Book(null,"舌尖上的中国","yj",new BigDecimal("5"),100,23,"文学",""));
// 创建一个新的Book对象并调用addBook方法将其添加到数据库中
bookDao.addBook(new Book(null, "舌尖上的中国", "yj", new BigDecimal("5"), 100, 23, "文学", ""));
}
/**
*
*/
@Test
public void updateBook() {
bookDao.updateBook(new Book(null,"舌尖上的中国","yj",new BigDecimal("5"),100,23,"文学",""));
// 创建一个新的Book对象并调用updateBook方法更新书籍信息
bookDao.updateBook(new Book(null, "舌尖上的中国", "yj", new BigDecimal("5"), 100, 23, "文学", ""));
}
/**
* ID
*/
@Test
public void deleteBookById() {
// 调用deleteBookById方法删除ID为25的书籍并打印受影响的行数
System.out.println(bookDao.deleteBookById(25));
}
/**
* ID
*/
@Test
public void queryBookById() {
// 调用queryBookById方法查询ID为23的书籍并打印结果
System.out.println(bookDao.queryBookById(23));
}
/**
*
*/
@Test
public void queryBooks() {
// 调用queryBooks方法查询所有书籍并打印结果
System.out.println(bookDao.queryBooks());
}
/**
*
*/
@Test
public void page() {
// 调用queryForPageTotalCount方法查询所有书籍的总记录数并打印结果
System.out.println(bookDao.queryForPageTotalCount());
}
/**
*
*/
@Test
public void queryTotalMoney() {
// 调用queryTotalMoney方法查询所有书籍的总金额并打印结果
System.out.println(bookDao.queryTotalMoney());
}
}

@ -10,44 +10,64 @@ import java.math.BigDecimal;
* @author yj
* @create 2020-08-26 20:30
*/
// 定义一个测试类CartTest用于测试Cart类的功能
public class CartTest {
// 使用@Test注解标记的方法表示这是一个测试方法通常与测试框架如JUnit一起使用
@Test
public void addItem() {
// 创建一个新的Cart对象
Cart cart = new Cart();
// 向购物车中添加一个商品项注意这里totalPrice应该是根据price和count计算得出的但此处直接给出
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
// 再次添加相同的商品项,理论上应该更新数量而不是添加新项(但根据代码,它会添加新项)
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
// 添加一个不同的商品项
cart.addItem(new CartItem(2,"你妹的",1,new BigDecimal(5),new BigDecimal(66)));
// 打印购物车的内容输出将取决于Cart类的toString方法实现
System.out.println(cart);
}
// 另一个测试方法,用于测试删除商品项的功能
@Test
public void deleteItem() {
// 创建一个新的Cart对象并添加一些商品项
Cart cart = new Cart();
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
cart.addItem(new CartItem(2,"你妹的",1,new BigDecimal(5),new BigDecimal(66)));
// 根据商品ID删除商品项理论上应该删除所有ID匹配的项
cart.deleteItem(1);
// 打印购物车的内容,查看删除操作的结果
System.out.println(cart);
}
// 测试清空购物车的方法
@Test
public void clear() {
// 创建一个新的Cart对象并添加一些商品项
Cart cart = new Cart();
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
cart.addItem(new CartItem(2,"你妹的",1,new BigDecimal(5),new BigDecimal(66)));
// 清空购物车中的所有商品项
cart.clear();
// 打印购物车的内容,应该为空
System.out.println(cart);
}
// 测试更新商品数量的方法
@Test
public void updateCount() {
// 创建一个新的Cart对象并添加一些商品项
Cart cart = new Cart();
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
cart.addItem(new CartItem(1,"lkjs",1,new BigDecimal(5),new BigDecimal(66)));
cart.addItem(new CartItem(2,"你妹的",1,new BigDecimal(5),new BigDecimal(66)));
// 根据商品ID更新商品数量注意这里可能需要根据业务逻辑决定是更新现有项还是添加新项
cart.updateCount(1,5);
// 假设意图是将ID为1的商品数量更新为5
// 打印购物车的内容,查看更新操作的结果
System.out.println(cart);
}
}

@ -1,29 +1,44 @@
package com.yj.test;
// 声明包名,用于组织类
import com.yj.utils.JDBCUtils;
// 导入JDBCUtils工具类用于数据库连接
import org.junit.Test;
// 导入JUnit测试注解
import java.sql.Connection;
// 导入Connection接口用于数据库连接
import java.sql.ResultSet;
// 导入ResultSet接口用于处理查询结果集
import java.sql.Statement;
// 导入Statement接口用于执行SQL语句
/**
* @author yj
* @create 2020-08-21 11:25
*/
public class JDBCUtilsTest {
@Test
public class JDBCUtilsTest { // 定义一个测试类
@Test // 标记此方法为一个测试方法
public void testJdbcUtils() {
// 定义一个测试方法
Connection connection = JDBCUtils.getConnection();
// 通过JDBCUtils工具类获取数据库连接
String sql = "select * from t_book";
// 定义SQL查询语句查询t_book表中的所有记录
try (Statement st = connection.createStatement()) {
// 创建Statement对象用于执行SQL语句使用try-with-resources语法自动关闭资源
ResultSet rs = st.executeQuery(sql);
while(rs.next()){
// 执行查询语句并将结果存储在ResultSet对象中
while(rs.next()){ // 遍历ResultSet对象中的每一条记录
System.out.println(rs.getString("author")+" "
// 从当前记录中获取"author"字段的值,并输出
+rs.getString("name"));
// 从当前记录中获取"name"字段的值,并输出,与"author"字段的值用空格分隔
}
}catch (Exception e) {
// 捕获并处理异常
e.printStackTrace();
// 打印异常堆栈信息
}
}
}
}

@ -1,79 +1,107 @@
package com.yj.utils;
// 声明包名
import com.alibaba.druid.pool.DruidDataSource;
// 导入Druid连接池的数据源类
import com.alibaba.druid.pool.DruidDataSourceFactory;
// 导入Druid连接池的工厂类
import com.alibaba.druid.util.JdbcUtils;
// 导入Druid的工具类注意此处的JdbcUtils并非JDK自带的而是Druid框架提供的但在此代码中未直接使用
import java.io.InputStream;
// 导入输入流接口
import java.sql.Connection;
// 导入数据库连接接口
import java.sql.SQLException;
// 导入SQL异常类
import java.util.Properties;
// 导入属性类
/**
* @author yj
* @create 2020-08-21 10:48
*/
public class JDBCUtils {
// 定义一个工具类
private static DruidDataSource dataSource;
// 定义一个静态的Druid数据源对象
private static ThreadLocal<Connection> conns = new ThreadLocal<Connection>();
// 定义一个ThreadLocal对象用于存储每个线程的数据库连接
static {
// 静态代码块,用于初始化静态变量
try {
Properties properties = new Properties();
//读取jdbc.properties属性配置文件
InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties" );
//从流中加载数据
// 创建一个属性对象
// 读取jdbc.properties属性配置文件
InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
// 从流中加载数据到属性对象中
properties.load(inputStream);
//创建数据库连接池
// 创建数据库连接池
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
// 使用Druid工厂类创建数据源对象
} catch (Exception e) {
// 捕获异常
e.printStackTrace();
// 打印异常堆栈信息
}
}
/*
@retrun null
/**
*
* @return null
*/
public static Connection getConnection() {
Connection conn = conns.get();
if(conn == null) {
try {
conn = dataSource.getConnection();//从数据库池中获取连接
conns.set(conn);//保存到ThreadLocal对象中供后面的JDBC操作使用
conn.setAutoCommit(false);//设置为手动管理事务
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
return conn;
// 定义一个静态方法,用于获取数据库连接
Connection conn = conns.get();
// 从ThreadLocal对象中获取当前线程的连接
if(conn == null) {
// 如果当前线程没有连接
try {
conn = dataSource.getConnection();
// 从数据库池中获取连接
conns.set(conn);
// 将连接保存到ThreadLocal对象中供后面的JDBC操作使用
conn.setAutoCommit(false);
// 设置为手动管理事务
} catch (SQLException throwables) {
// 捕获SQL异常
throwables.printStackTrace();
// 打印异常堆栈信息
}
}
return conn;
// 返回连接
}
/**
*
*/
public static void commitAndClose() {
// 定义一个静态方法,用于提交事务并关闭连接
Connection connection = conns.get();
// 从ThreadLocal对象中获取连接
if(connection!=null) {
// 如果连接不为空
try {
connection.commit();//提交事务
connection.commit();// 提交事务
} catch (SQLException throwables) {
// 捕获SQL异常
throwables.printStackTrace();
// 打印异常堆栈信息
}finally {
try {
connection.close();//关闭连接释放资源
connection.close();
// 关闭连接释放资源
} catch (SQLException throwables) {
// 捕获SQL异常
throwables.printStackTrace();
// 打印异常堆栈信息
}
}
}
//一定要执行remove操作否则就会出错因为tomcat底层使用了线程池技术
// 移除ThreadLocal对象中的连接防止内存泄漏特别是在使用线程池时
conns.remove();
}
@ -81,35 +109,45 @@ public class JDBCUtils {
*
*/
public static void rollbackAndClose() {
// 定义一个静态方法,用于回滚事务并关闭连接
Connection connection = conns.get();
// 从ThreadLocal对象中获取连接
if(connection!=null) {
// 如果连接不为空
try {
connection.rollback();//回滚事务
connection.rollback();
// 回滚事务
} catch (SQLException throwables) {
// 捕获SQL异常
throwables.printStackTrace();
// 打印异常堆栈信息
}finally {
try {
connection.close();//关闭连接释放资源
connection.close();
// 关闭连接释放资源
} catch (SQLException throwables) {
// 捕获SQL异常
throwables.printStackTrace();
// 打印异常堆栈信息
}
}
}
//一定要执行remove操作否则就会出错因为tomcat底层使用了线程池技术
// 移除ThreadLocal对象中的连接防止内存泄漏特别是在使用线程池时
conns.remove();
}
/*
使
public static void close(Connection conn) {
if(conn != null) {
try {
conn.close();
// 这里实际上并不是将连接关闭,而是将连接归还给连接池(对于连接池而言)
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}*/
}
}

@ -12,10 +12,11 @@ import java.util.Arrays;
public class PaymentUtil {
// 定义字符编码
private static String encodingCharset = "UTF-8";
/**
* hmac
* hmac
*
* @param p0_Cmd
* @param p1_MerId
@ -31,45 +32,34 @@ public class PaymentUtil {
* @param pd_FrpId
* @param pr_NeedResponse
* @param keyValue
* @return
* @return hmac
*/
public static String buildHmac(String p0_Cmd,String p1_MerId,
String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat,
String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId,
String pr_NeedResponse,String keyValue) {
public static String buildHmac(String p0_Cmd, String p1_MerId,
String p2_Order, String p3_Amt, String p4_Cur, String p5_Pid, String p6_Pcat,
String p7_Pdesc, String p8_Url, String p9_SAF, String pa_MP, String pd_FrpId,
String pr_NeedResponse, String keyValue) {
StringBuilder sValue = new StringBuilder();
// 业务类型
// 依次追加所有参数到StringBuilder
sValue.append(p0_Cmd);
// 商户编号
sValue.append(p1_MerId);
// 商户订单号
sValue.append(p2_Order);
// 支付金额
sValue.append(p3_Amt);
// 交易币种
sValue.append(p4_Cur);
// 商品名称
sValue.append(p5_Pid);
// 商品种类
sValue.append(p6_Pcat);
// 商品描述
sValue.append(p7_Pdesc);
// 商户接收支付成功数据的地址
sValue.append(p8_Url);
// 送货地址
sValue.append(p9_SAF);
// 商户扩展信息
sValue.append(pa_MP);
// 银行编码
sValue.append(pd_FrpId);
// 应答机制
sValue.append(pr_NeedResponse);
// 调用hmacSign方法生成签名
return PaymentUtil.hmacSign(sValue.toString(), keyValue);
}
/**
* hmac
* hmac
*
* @param hmac
* @param p1_MerId
@ -84,57 +74,54 @@ public class PaymentUtil {
* @param r8_MP
* @param r9_BType
* @param keyValue
* @return
* @return true
*/
public static boolean verifyCallback(String hmac, String p1_MerId,
String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt,
String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid,
String r8_MP, String r9_BType, String keyValue) {
StringBuilder sValue = new StringBuilder();
// 商户编号
// 依次追加所有回调参数到StringBuilder
sValue.append(p1_MerId);
// 业务类型
sValue.append(r0_Cmd);
// 支付结果
sValue.append(r1_Code);
// 易宝支付交易流水号
sValue.append(r2_TrxId);
// 支付金额
sValue.append(r3_Amt);
// 交易币种
sValue.append(r4_Cur);
// 商品名称
sValue.append(r5_Pid);
// 商户订单号
sValue.append(r6_Order);
// 易宝支付会员ID
sValue.append(r7_Uid);
// 商户扩展信息
sValue.append(r8_MP);
// 交易结果返回类型
sValue.append(r9_BType);
// 调用hmacSign方法生成签名并与支付网关的签名比较
String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue);
return sNewString.equals(hmac);
}
/**
* @param aValue
* @param aKey
* @return
* 使HMAC-MD5
*
* @param aValue
* @param aKey
* @return
*/
public static String hmacSign(String aValue, String aKey) {
// 初始化内部填充字节数组
byte k_ipad[] = new byte[64];
byte k_opad[] = new byte[64];
byte keyb[];
byte value[];
try {
// 使用指定的字符编码获取字节数组
keyb = aKey.getBytes(encodingCharset);
value = aValue.getBytes(encodingCharset);
} catch (UnsupportedEncodingException e) {
// 如果不支持指定的字符编码,则使用默认字符编码
keyb = aKey.getBytes();
value = aValue.getBytes();
}
// 填充k_ipad和k_opad数组
Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
for (int i = 0; i < keyb.length; i++) {
@ -142,23 +129,32 @@ public class PaymentUtil {
k_opad[i] = (byte) (keyb[i] ^ 0x5c);
}
// 获取MD5算法的MessageDigest实例
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
// 如果MD5算法不可用则返回null
return null;
}
// 对k_ipad和待签名数据进行更新
md.update(k_ipad);
md.update(value);
byte dg[] = md.digest();
md.reset();
byte dg[] = md.digest(); // 进行第一次摘要
md.reset(); // 重置MessageDigest实例
// 对k_opad和第一次摘要结果进行更新
md.update(k_opad);
md.update(dg, 0, 16);
dg = md.digest();
return toHex(dg);
dg = md.digest(); // 进行第二次摘要,得到最终的签名
return toHex(dg); // 将字节数组转换为十六进制字符串
}
/**
*
*
* @param input
* @return
*/
public static String toHex(byte input[]) {
if (input == null)
return null;
@ -169,15 +165,15 @@ public class PaymentUtil {
output.append("0");
output.append(Integer.toString(current, 16));
}
return output.toString();
}
/**
* HMAC
*
* @param args
* @param key
* @return
* @param args
* @param key
* @return HMAC
*/
public static String getHmac(String[] args, String key) {
if (args == null || args.length == 0) {
@ -191,8 +187,10 @@ public class PaymentUtil {
}
/**
* @param aValue
* @return
* 使SHA
*
* @param aValue
* @return
*/
public static String digest(String aValue) {
aValue = aValue.trim();

@ -10,26 +10,54 @@ import java.lang.reflect.Method;
/**
* @author yj
* @create 2020-08-23 16:51
*
* BaseServletServletServlet
* ServletdoGetdoPost
*/
public abstract class BaseServlet extends HttpServlet {
/**
* GETdoPost
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
doPost(req, resp);
}
/**
* POST
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决post请求中文乱码
// 解决POST请求中文乱码问题
req.setCharacterEncoding("utf-8");
//解决相应的中文乱码
// 解决响应的中文乱码问题
resp.setContentType("text/html;charset=UTF-8");
// 获取请求参数action该参数用于指定要调用的方法名
String action = req.getParameter("action");
try {
Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class,HttpServletResponse.class);
method.invoke(this,req,resp);
// 通过反射获取当前类中指定名称的方法
Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
// 调用方法,传入请求和响应对象
method.invoke(this, req, resp);
} catch (Exception e) {
// 捕获异常并打印堆栈信息
e.printStackTrace();
// 将异常包装为运行时异常抛出,便于上层处理
throw new RuntimeException(e);
}
}
}
}

@ -15,72 +15,137 @@ import java.util.List;
/**
* @author yj
* @create 2020-08-24 15:25
*
* BookServletBaseServlet
* BookServiceBookServiceImpl
*/
public class BookServlet extends BaseServlet {
// 创建BookService接口的实现类BookServiceImpl对象
private BookService bookService = new BookServiceImpl();
/**
*
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),0);
pageNo+=1;
Book book = (Book) WebUtils.copyParamToBean(req.getParameterMap(),new Book());
// 获取当前页码默认从0开始
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 0);
// 页码加1表示添加书籍后跳转到下一页
pageNo += 1;
// 将请求参数封装到Book对象中
Book book = (Book) WebUtils.copyParamToBean(req.getParameterMap(), new Book());
// 调用BookService的addBook方法添加书籍
bookService.addBook(book);
//req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp);
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo="+pageNo);
}
// 重定向到书籍管理页面,并跳转到添加书籍后的页码
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + pageNo);
}
/**
*
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
int i = Integer.parseInt(id);
bookService.deleteBookById(i);
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo="+req.getParameter("pageNo"));
}
// 获取要删除的书籍ID
String id = req.getParameter("id");
int i = Integer.parseInt(id);
// 调用BookService的deleteBookById方法删除书籍
bookService.deleteBookById(i);
// 重定向到书籍管理页面,并保持当前页码
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
/**
*
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Book book = (Book) WebUtils.copyParamToBean(req.getParameterMap(),new Book());
// 将请求参数封装到Book对象中
Book book = (Book) WebUtils.copyParamToBean(req.getParameterMap(), new Book());
// 调用BookService的updateBook方法更新书籍
bookService.updateBook(book);
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo="+req.getParameter("pageNo"));
// 重定向到书籍管理页面,并保持当前页码
resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
/**
*
* @param req
* @param resp
*
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取要查询的书籍ID
String id = req.getParameter("id");
int i = Integer.parseInt(id);
// 调用BookService的queryBookById方法查询书籍
Book book = bookService.queryBookById(i);
req.setAttribute("book",book);
req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp);
}
// 将查询到的书籍信息保存到request域中
req.setAttribute("book", book);
// 请求转发到书籍编辑页面
req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req, resp);
}
/**
*
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、通过BookService查询数据
List<Book>books = bookService.queryBooks();
//2、将数据保存在request域中
req.setAttribute("books",books);
//3、请求转发到pages/manager/book_manager.jsp
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
// 调用BookService的queryBooks方法查询所有书籍
List<Book> books = bookService.queryBooks();
// 将查询到的书籍列表保存到request域中
req.setAttribute("books", books);
// 请求转发到书籍管理页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req, resp);
}
/**
*
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @throws ServletException
* @throws IOException
*/
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取请求的参数pageNo和pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);
// 获取请求参数pageNo和pageSize
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
//2、调用BookService.page(pageNo,pageSize)方法返回page对象
Page<Book> page = bookService.page(pageNo,pageSize);
// 调用BookService的page方法进行分页查询
Page<Book> page = bookService.page(pageNo, pageSize);
// 设置分页请求的URL
page.setUrl("manager/bookServlet?action=page");
//3、保存Page对象到request域中
req.setAttribute("page",page);
//4、请求转发到page/manager/book_manager.jsp页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
// 将分页对象保存到request域中
req.setAttribute("page", page);
// 请求转发到书籍管理页面
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req, resp);
}
}
}

@ -1,12 +1,20 @@
// 导入所需的包和类
package com.yj.web;
import com.google.gson.Gson;
// 用于将Java对象转换为JSON字符串
import com.yj.bean.Book;
// 书籍实体类
import com.yj.bean.Cart;
// 购物车实体类
import com.yj.bean.CartItem;
// 购物车商品项实体类
import com.yj.service.BookService;
// 书籍服务接口
import com.yj.service.impl.BookServiceImpl;
// 书籍服务接口的实现类
import com.yj.utils.WebUtils;
// 工具类用于处理Web请求中的常见操作
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -15,100 +23,93 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author yj
* @create 2020-08-27 9:47
*/
// 定义一个Servlet类用于处理与购物车相关的请求
public class CartServlet extends BaseServlet {
// 创建一个书籍服务实例,用于访问书籍数据
private BookService bookService = new BookServiceImpl();
// 处理通过AJAX方式添加商品到购物车的请求
protected void ajaxAddItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = WebUtils.parseInt(req.getParameter("id"),0);
// 从请求中获取书籍ID并转换为整数类型默认为0
int id = WebUtils.parseInt(req.getParameter("id"), 0);
// 根据书籍ID查询书籍信息
Book book = bookService.queryBookById(id);
CartItem cartItem = new CartItem(book.getId(),book.getName(),1,book.getPrice(),book.getPrice());
// 创建一个购物车商品项实例数量为1单价和总价均为书籍价格
CartItem cartItem = new CartItem(book.getId(), book.getName(), 1, book.getPrice(), book.getPrice());
// 从会话中获取购物车对象,如果不存在则创建一个新的购物车对象
Cart cart = (Cart) req.getSession().getAttribute("cart");
if(cart==null) {
if (cart == null) {
cart = new Cart();
req.getSession().setAttribute("cart",cart);
req.getSession().setAttribute("cart", cart);
}
// 将商品项添加到购物车中
cart.addItem(cartItem);
req.getSession().setAttribute("lastName",cartItem.getName());
// 在会话中保存最后添加的商品名称(可能用于显示或提示)
req.getSession().setAttribute("lastName", cartItem.getName());
//返回购物车总数量和最后一个商品的名称
Map<String,Object> resultMap = new HashMap<String,Object>();
resultMap.put("totalCount",cart.getTotalCount());
resultMap.put("lastName",cartItem.getName());
// 准备返回给客户端的数据,包括购物车总数量和最后一个商品的名称
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("totalCount", cart.getTotalCount());
resultMap.put("lastName", cartItem.getName());
// 使用Gson将Map对象转换为JSON字符串
Gson gson = new Gson();
String resultMapJsonString = gson.toJson(resultMap);
// 将JSON字符串写入响应中
resp.getWriter().write(resultMapJsonString);
}
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
// 处理添加商品到购物车的请求非AJAX方式
protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = WebUtils.parseInt(req.getParameter("id"),0);
Book book = bookService.queryBookById(id);
CartItem cartItem = new CartItem(book.getId(),book.getName(),1,book.getPrice(),book.getPrice());
// 以下代码与ajaxAddItem方法中的代码大致相同只是最后返回的是页面重定向
int id = WebUtils.parseInt(req.getParameter("id"), 0);
Book book = bookService.queryBookById(id);
CartItem cartItem = new CartItem(book.getId(), book.getName(), 1, book.getPrice(), book.getPrice());
Cart cart = (Cart) req.getSession().getAttribute("cart");
if(cart==null) {
if (cart == null) {
cart = new Cart();
req.getSession().setAttribute("cart",cart);
req.getSession().setAttribute("cart", cart);
}
cart.addItem(cartItem);
req.getSession().setAttribute("lastName",cartItem.getName());
req.getSession().setAttribute("lastName", cartItem.getName());
// 重定向到请求来源页面通常是通过Referer头部获取的
resp.sendRedirect(req.getHeader("Referer"));
}
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
// 处理删除购物车中商品项的请求
protected void deleteItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = WebUtils.parseInt(req.getParameter("id"),0);
// 从请求中获取要删除的商品项ID
int id = WebUtils.parseInt(req.getParameter("id"), 0);
// 从会话中获取购物车对象
Cart cart = (Cart) req.getSession().getAttribute("cart");
if(cart!=null) {
// 如果购物车对象存在则删除指定ID的商品项
if (cart != null) {
cart.deleteItem(id);
resp.sendRedirect(req.getHeader("Referer"));
}
// 重定向到请求来源页面
resp.sendRedirect(req.getHeader("Referer"));
}
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
// 处理清空购物车中所有商品项的请求
protected void clearItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().removeAttribute("cart");
// 从会话中移除购物车对象,从而清空购物车
req.getSession().removeAttribute("cart");
// 重定向到请求来源页面
resp.sendRedirect(req.getHeader("Referer"));
}
/**
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
// 处理修改购物车中商品项数量的请求
protected void updateCount(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = WebUtils.parseInt(req.getParameter("id"),0);
int count = WebUtils.parseInt(req.getParameter("count"),1);
// 从请求中获取要修改的商品项ID和新的数量
int id = WebUtils.parseInt(req.getParameter("id"), 0);
int count = WebUtils.parseInt(req.getParameter("count"), 1);
// 从会话中获取购物车对象
Cart cart = (Cart) req.getSession().getAttribute("cart");
if(cart!=null) {
cart.updateCount(id,count);
resp.sendRedirect(req.getHeader("Referer"));
// 如果购物车对象存在则修改指定ID的商品项数量
if (cart != null) {
cart.updateCount(id, count);
}
// 重定向到请求来源页面
resp.sendRedirect(req.getHeader("Referer"));
}
}
}

@ -1,28 +1,45 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 引入JSTL核心标签库用于简化JSP页面的内容 -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 设置页面内容类型和字符编码 -->
<!DOCTYPE html>
<!-- 声明文档类型为HTML5 -->
<html>
<head>
<meta charset="UTF-8">
<title>购物车</title>
<meta charset="UTF-8">
<!-- 设置页面的字符编码 -->
<title>购物车</title>
<!-- 设置页面标题 -->
<%@include file="/pages/common/header.jsp"%>
<!-- 引入头部文件通常包含CSS和JavaScript的引用 -->
<script type="text/javascript">
$(function () {
// 当文档加载完成后执行的函数
$("a.deleteItem").click(function () {
// 为删除按钮绑定点击事件
return confirm("你确定要删除【"+$(this).parent().parent().find("td:first").text() +"】么?");
// 弹出确认框询问是否删除
});
$("#clearCart").click(function () {
// 为清空购物车按钮绑定点击事件
return confirm("你确定要清空购物车么?");
// 弹出确认框询问是否清空购物车
});
$(".updateCount").change(function () {
// 为数量输入框绑定值改变事件
var name = $(this).parent().parent().find("td:first").text();
// 获取商品名称
var count = this.value;
// 获取输入的新数量
var id = $(this).attr("bookId");
// 获取商品的ID
if(confirm("你确定要修改【"+name+"】数量为"+count+"么?")) {
location.href="http://localhost:8080/Book/cartServlet?action=updateCount&count="+count+"&id="+id;
// 弹出确认框询问是否修改数量
location.href="http://localhost:8080/Book/cartServlet?action=updateCount&count="+count+"&id="+id; // 跳转到更新数量的Servlet
} else {
this.value = this.defaultValue;
// 如果取消,则恢复默认数量
}
})
});
@ -30,58 +47,80 @@
</script>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo.jpg" >
<span class="wel_word">购物车</span>
<%@include file="/pages/common/login_success_menu.jsp"%>
</div>
<div id="main">
<table>
<div id="header">
<!-- 头部区域 -->
<img class="logo_img" alt="" src="static/img/logo.jpg" >
<!-- 引入logo图片 -->
<span class="wel_word">购物车</span>
<!-- 显示欢迎文字 -->
<%@include file="/pages/common/login_success_menu.jsp"%>
<!-- 引入登录成功后的菜单 -->
</div>
<div id="main">
<!-- 主内容区域 -->
<table>
<!-- 商品列表表格 -->
<tr>
<td>商品名称</td>
<td>数量</td>
<td>单价</td>
<td>金额</td>
<td>操作</td>
</tr>
<c:if test="${empty sessionScope.cart.items}">
<!-- 判断购物车是否为空 -->
<tr>
<td>商品名称</td>
<td>数量</td>
<td>单价</td>
<td>金额</td>
<td>操作</td>
<td colspan="5"><a href="index.jsp">亲,当前购物车为空,快去和小伙伴浏览书籍吧! </a> </td>
<!-- 显示购物车为空的信息 -->
</tr>
</c:if>
<c:if test="${empty sessionScope.cart.items}">
<c:if test="${not empty sessionScope.cart.items}">
<!-- 判断购物车是否不为空 -->
<c:forEach items="${sessionScope.cart.items}" var="entry">
<!-- 遍历购物车中的商品 -->
<tr>
<td colspan="5"><a href="index.jsp">亲,当前购物车为空,快去和小伙伴浏览书籍吧! </a> </td>
<td>${entry.value.name}</td>
<!-- 显示商品名称 -->
<td>
<input class="updateCount" style="width: 70px;" bookId="${entry.value.id}" type="text" value="${entry.value.count}">
<!-- 数量输入框 -->
</td>
<td>${entry.value.price}</td>
<!-- 显示商品单价 -->
<td>${entry.value.totalPrice}</td>
<!-- 显示商品总价 -->
<td><a class="deleteItem" href="cartServlet?action=deleteItem&id=${entry.value.id}">删除</a></td>
<!-- 删除按钮 -->
</tr>
</c:if>
</c:forEach>
</c:if>
<c:if test="${not empty sessionScope.cart.items}">
<c:forEach items="${sessionScope.cart.items}" var="entry">
<tr>
<td>${entry.value.name}</td>
<td>
<input class="updateCount" style="width: 70px;" bookId="${entry.value.id}" type="text" value="${entry.value.count}">
</td>
<td>${entry.value.price}</td>
<td>${entry.value.totalPrice}</td>
<td><a class="deleteItem" href="cartServlet?action=deleteItem&id=${entry.value.id}">删除</a></td>
</tr>
</c:forEach>
</c:if>
</table>
<c:if test="${not empty sessionScope.cart.items}">
</table>
<c:if test="${not empty sessionScope.cart.items}">
<!-- 判断购物车是否不为空 -->
<div class="cart_info">
<!-- 购物车信息区域 -->
<span class="cart_span">购物车中共有<span class="b_count">${sessionScope.cart.totalCount}</span>本书籍</span>
<!-- 显示购物车中商品的总数 -->
<span class="cart_span">总金额<span class="b_price">${sessionScope.cart.totalPrice}</span>元</span>
<!-- 显示购物车中商品的总金额 -->
<span class="cart_span"><a id="clearCart" href="cartServlet?action=clearItem">清空购物车</a></span>
<!-- 清空购物车按钮 -->
<span class="cart_span"><a href="client/orderServlet?action=isLogin">去结账</a></span>
<!-- 去结账按钮 -->
</div>
</c:if>
</c:if>
</div>
</div>
<%@include file="/pages/common/footer.jsp"%>
<%@include file="/pages/common/footer.jsp"%>
<!-- 引入页脚文件 -->
</body>
</html>
</html>

@ -1,32 +1,52 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 指定页面使用的内容类型为HTML字符集为UTF-8并声明使用Java作为脚本语言 -->
<!DOCTYPE html>
<!-- 声明文档类型为HTML5 -->
<html>
<!-- HTML文档的根元素 -->
<head>
<meta charset="UTF-8">
<title>结算页面</title>
<!-- 头部元素,包含文档的元数据 -->
<meta charset="UTF-8">
<!-- 设置文档的字符编码为UTF-8 -->
<title>结算页面</title>
<!-- 设置网页的标题 -->
<%@include file="/pages/common/header.jsp"%>
<style type="text/css">
<!-- 包含插入一个公共的头部JSP文件通常包含CSS和JavaScript链接 -->
<style type="text/css">
<!-- 定义内嵌的CSS样式 -->
h1 {
<!-- 设置h1标签的样式 -->
text-align: center;
<!-- 文本居中对齐 -->
margin-top: 200px;
<!-- 上边距为200像素 -->
}
</style>
</style>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo.jpg" >
<span class="wel_word">结算</span>
<%@include file="/pages/common/login_success_menu.jsp"%>
</div>
<div id="main">
<h1>你的订单已结算,订单号为${sessionScope.orderId},店主很快就会发货啦!</h1>
</div>
<!-- 网页的主体部分 -->
<%@include file="/pages/common/footer.jsp"%>
<div id="header">
<!-- 头部区域的容器 -->
<img class="logo_img" alt="" src="static/img/logo.jpg" >
<!-- 显示网站的logo图片 -->
<span class="wel_word">结算</span>
<!-- 显示欢迎词或当前页面标识 -->
<%@include file="/pages/common/login_success_menu.jsp"%>
<!-- 包含登录成功后的菜单JSP文件 -->
</div>
<div id="main">
<!-- 主要内容的容器 -->
<h1>你的订单已结算,订单号为${sessionScope.orderId},店主很快就会发货啦!</h1>
<!-- 显示订单结算成功的消息,${sessionScope.orderId}用于从会话范围获取订单号 -->
</div>
<%@include file="/pages/common/footer.jsp"%>
<!-- 包含页脚的JSP文件通常包含版权信息和链接 -->
</body>
</html>
</html>
<!-- HTML文档的结束 -->

@ -1,78 +1,98 @@
<%--
这是一个JSP注释不会被发送到客户端。它包含了文件的创建信息。
Created by IntelliJ IDEA.
User: jhu
Date: 2020/10/5
Time: 14:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 指定页面内容类型、字符集和脚本语言 -->
<html>
<!-- HTML文档的根元素 -->
<head>
<!-- 文档的头部 -->
<title>结算页面</title>
<!-- 设置页面标题 -->
<%@include file="/pages/common/header.jsp"%>
<!-- 包含公共头部文件通常包含CSS、JavaScript链接等 -->
<!-- 下面的div元素应该放在body内而不是head内但这里可能是个错误或复制粘贴时的疏忽 -->
<div id="header">
<!-- 头部容器 -->
<img class="logo_img" alt="" src="static/img/logo.jpg" >
<!-- 网站logo图片 -->
<span class="wel_word">结算</span>
<!-- 欢迎词或当前页面标识 -->
<%@include file="/pages/common/login_success_menu.jsp"%>
<!-- 包含登录成功后的菜单 -->
</div>
<!-- 注意上面的div元素应该被移除到body标签内 -->
</head>
<body>
<!-- 文档的主体 -->
<div id="main">
<!-- 主要内容容器 -->
<form action="client/orderServlet?action=createOrder" method="post">
<!-- 提交表单到orderServlet的createOrder动作 -->
<input type="hidden">
<!-- 隐藏输入字段此处未指定name属性可能是个占位符 -->
<table width="80%">
<!-- 表格宽度为页面宽度的80% -->
<tr>
<td bgcolor="#F7FEFF" colspan="4">
支付金额:<INPUT id="money" TYPE="text" NAME="money" size="6" value="${sessionScope.cart.totalPrice}">元</td>
<!-- 表格单元格,背景色为#F7FEFF横跨4列 -->
支付金额:<INPUT id="money" TYPE="text" NAME="money" size="6" value="${sessionScope.cart.totalPrice}">元</td> <!-- 显示支付金额,从会话中获取购物车总价 -->
</tr>
<tr>
<td><br />
</td>
<td><br /></td>
<!-- 空行 -->
</tr>
<tr>
<td colspan="4">请您选择在线支付银行</td>
<!-- 提示用户选择支付银行 -->
</tr>
<!-- 下面的几行是银行选择项,每个单选按钮代表一个银行 -->
<tr>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBCHINA-NET">招商银行
</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBCHINA-NET">招商银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="ICBC-NET">工商银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="ABC-NET">农业银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CCB-NET">建设银行
</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CCB-NET">建设银行</td>
</tr>
<tr>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBC-NET">中国民生银行总行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CEB-NET">光大银行
</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CEB-NET">光大银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="BOCO-NET">交通银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="SDB-NET">深圳发展银行</td>
</tr>
<tr>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="BCCB-NET">北京银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CIB-NET">兴业银行
</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="SPDB-NET">上海浦东发展银行
</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="CIB-NET">兴业银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="SPDB-NET">上海浦东发展银行</td>
<td><INPUT TYPE="radio" NAME="pd_FrpId" value="ECITIC-NET">中信银行</td>
</tr>
<tr>
<td><br />
</td>
<td><br /></td>
<!-- 空行 -->
</tr>
<tr>
<td colspan="4"><INPUT TYPE="submit" value="确定支付">
</td>
<td colspan="4"><INPUT TYPE="submit" value="确定支付"></td>
<!-- 提交按钮 -->
</tr>
</table>
</form>
</div>
<%@include file="/pages/common/footer.jsp"%>
<!-- 包含公共页脚文件 -->
</body>
</body>
</html>
<!-- 注意:这里有一个多余的</body>标签,应该被移除 -->
</html>

@ -1,11 +1,6 @@
<%--
Created by IntelliJ IDEA.
User: jhu
Date: 2020/10/5
Time: 15:44
To change this template use File | Settings | File Templates.
此文件的创建信息注释,表明是由 IntelliJ IDEA 创建,作者是 jhu创建日期是 2020 年 10 月 5 日,时间是 15 时 44 分,并且提示修改此模板的相关设置路径。
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
@ -13,21 +8,25 @@
<head>
<meta charset="UTF-8">
<title>书城首页</title>
<%-- 包含公共的头部页面header.jsp可能包含一些通用的样式、脚本或者页面头部结构相关的内容方便复用。 --%>
<%@include file="/pages/common/header.jsp"%>
<script type="text/javascript">
// 当页面 DOM 加载完成后执行以下函数(这是 jQuery 的 $(function() {}) 语法的作用,相当于 DOMContentLoaded 事件的简写形式)
$(function () {
//给加入购物车绑定单击事件
// 给所有 class 为 addToCart 的 button 元素绑定单击事件(通过 jQuery 的 click 方法实现事件绑定)
$("button.addToCart").click(function () {
// 获取当前被点击按钮的 bookId 属性值(通过 jQuery 的 attr 方法获取元素的自定义属性值),这个 bookId 应该是对应书籍的唯一标识,用于后续操作。
var bookId = $(this).attr("bookId");
//发ajax请求添加商品到购物车
// 使用 jQuery 的 $.getJSON 方法发送一个 AJAX 请求,请求的 URL 是 "http://localhost:8080/Book/cartServlet",同时传递了参数 "action=ajaxAddItem&id=" 加上获取到的 bookId期望服务器返回 JSON 格式的数据。
// 并且在请求成功后的回调函数中处理返回的数据(这里回调函数接收一个 data 参数,就是服务器返回的 JSON 数据解析后的对象)。
$.getJSON("http://localhost:8080/Book/cartServlet", "action=ajaxAddItem&id=" + bookId, function (data) {
// 更新购物车商品总数的显示内容,通过 jQuery 的 text 方法将指定元素id 为 cartTotalCount 的元素的文本内容更新为包含服务器返回的商品总数data.totalCount的提示信息。
$("#cartTotalCount").text("您的购物车中有" + data.totalCount + "件商品");
// 更新购物车中最新添加的商品名称的显示内容,通过 jQuery 的 html 方法将指定元素id 为 cartLastName 的元素)的 HTML 内容更新为包含服务器返回的最新添加商品名称data.lastName的提示信息这里使用双引号包裹文本所以里面的文本可以包含 HTML 标签(如果有的话)。
$("#cartLastName").html("您刚刚将【" + data.lastName + "】加入到了购物车中");
});
});
});
</script>
</head>
<body>
@ -35,35 +34,40 @@
<img class="logo_img" alt="" src="static/img/logo1.jpg" >
<span class="wel_word">Bookstore</span>
<div>
<!-- 使用 JSTL 的 c:if 标签判断 sessionScope 中 user 对象是否为空以此来区分用户是否登录empty 关键字用于判断是否为空值(比如 null、空字符串等。 -->
<c:if test="${empty sessionScope.user}">
<!-- 如果 user 对象为空,说明用户未登录,显示登录和注册链接,以及热榜链接,方便用户进行相应操作。 -->
<a href="pages/user/login.jsp">登录</a> |
<a href="pages/user/regist.jsp">注册</a> &nbsp;&nbsp;
<a href="client/bookServlet?action=pageOrder">热榜</a>
</c:if>
<c:if test="${not empty sessionScope.user}">
<!-- 如果 user 对象不为空,说明用户已登录,显示欢迎语以及包含用户用户名的个性化欢迎信息,同时提供我的订单、个人信息、注销等相关操作链接。 -->
<span>欢迎<span class="um_span">${sessionScope.user.username}</span>光临书城</span>
<a href="client/orderServlet?action=myOrders">我的订单</a>
<a href="pages/user/userinfo.jsp">个人信息</a>
<a href="userServlet?action=logout">注销</a>&nbsp;&nbsp;
</c:if>
<!-- 始终显示购物车和后台管理的链接,方便用户进入购物车页面查看商品或者进入后台管理页面(可能需要相应权限)。 -->
<a href="pages/cart/cart.jsp">购物车</a>
<a href="pages/manager/manager.jsp">后台管理</a>
</div>
</div>
<div id="main">
<!-- 图书搜索功能区域 -->
<div class="book_check">
<form action="client/bookServlet" method="get">
<!-- 隐藏域,用于传递特定的参数 action其值为 pageByNameOrAuthor用于告知服务器此次请求是按照书名或作者名进行页面查询相关操作。 -->
<input type="hidden" name="action" value="pageByNameOrAuthor">
图书搜索<input id="nameorauthor" type="text" placeholder="请输入书名或作者名" name="nameorauthor" value="${param.nameorauthor}">
<input type="submit" value="查询" />
</form>
</div>
<div id="book">
<!-- 价格区间筛选功能区域 -->
<div class="book_cond">
<form action="client/bookServlet" method="get">
<!-- 同样是隐藏域,传递 action 参数,值为 pageByPrice用于告知服务器此次请求是按照价格区间进行页面查询相关操作。 -->
<input type="hidden" name="action" value="pageByPrice">
价格:<input id="min" type="text" name="min" value="${param.min}"> 元 -
<input id="max" type="text" name="max" value="${param.max}"> 元
@ -71,6 +75,7 @@
</form>
</div>
<div style="text-align: center">
<!-- 再次使用 JSTL 的 c:if 标签判断 sessionScope 中 cart 对象的 items 属性是否为空,以此来判断购物车是否为空。 -->
<c:if test="${empty sessionScope.cart.items}">
<span id="cartTotalCount"></span>
<div>
@ -78,13 +83,16 @@
</div>
</c:if>
<c:if test="${not empty sessionScope.cart.items}">
<!-- 如果购物车不为空,显示购物车商品总数,通过 EL 表达式(${sessionScope.cart.totalCount})获取购物车中商品的总数并展示出来。 -->
<span id="cartTotalCount">您的购物车中有${sessionScope.cart.totalCount}件商品</span>
<div>
<!-- 显示最新加入购物车的商品名称,同样通过 EL 表达式获取最新加入商品的名称并展示,这里还设置了颜色为红色,用于突出显示。 -->
您刚刚将<span style="color: red" id="cartLastName">${sessionScope.lastName}</span>加入到了购物车中
</div>
</c:if>
</div>
<!-- 使用 JSTL 的 c:forEach 标签遍历 requestScope 中 page 对象的 items 属性(这里的 items 应该是一个集合,可能是书籍信息的列表),每次遍历将当前元素赋值给变量 book然后在循环体中进行相应的页面展示操作。 -->
<c:forEach items="${requestScope.page.items}" var="book">
<div class="b_list">
<div class="img_div">
@ -112,6 +120,7 @@
<span class="sp2">${book.stock}</span>
</div>
<div class="book_add">
<!-- 加入购物车按钮,设置了自定义属性 bookId其值为当前遍历的书籍的 id方便前面的 JavaScript 代码获取并发送对应的添加到购物车的请求。 -->
<button bookId=${book.id} class="addToCart">加入购物车</button>
</div>
</div>
@ -120,10 +129,12 @@
</div>
<!-- 包含公共的分页导航页面page_nav.jsp可能包含分页相关的链接、页码显示等功能方便复用。 -->
<%@include file="/pages/common/page_nav.jsp"%>
</div>
<!-- 包含公共的页脚页面footer.jsp可能包含版权信息、联系方式等页面底部相关的通用内容方便复用。 -->
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
</html>

@ -1,9 +1,5 @@
<%--
Created by IntelliJ IDEA.
User: jhu
Date: 2020/10/19
Time: 22:56
To change this template use File | Settings | File Templates.
此部分为文件的创建相关注释,表明该文件是通过 IntelliJ IDEA 创建的,创建者是 jhu创建时间为 2020 年 10 月 19 日 22 时 56 分,同时说明了修改该模板的相关设置操作的路径信息。
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
@ -12,11 +8,10 @@
<head>
<meta charset="UTF-8">
<title>图书热销榜单</title>
<%-- 包含公共的头部页面header.jsp这里面通常会放置页面通用的样式表引入、脚本引入或者一些页面头部布局相关的内容以实现代码复用。 --%>
<%@include file="/pages/common/header.jsp"%>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo1.jpg" >
<span class="wel_word">图书热销榜单</span>
@ -35,6 +30,7 @@
<td>作者</td>
<td style="color: red">销量</td>
</tr>
<%-- 在 JSP 页面中嵌入 Java 代码片段,定义一个整型变量 i 并初始化为 1这个变量将用于记录图书的排名。 --%>
<%int i=1;%>
<c:forEach items="${requestScope.page.items}" var="book">
<tr>
@ -44,10 +40,9 @@
<td>${book.author}</td>
<td style="color: red">${book.sales}</td>
</tr>
<%-- 使用 JSTL 的 c:forEach 标签来遍历 requestScope 中 page 对象的 items 属性(通常这里是一个包含图书信息的集合),每次循环将集合中的一个元素赋值给变量 book然后在表格行tr中展示对应图书的各项信息包括通过表达式输出的排名通过 Java 代码片段中的 i 变量来展示,并且每次循环自增 1以及图书的名称、价格、作者和销量通过 EL 表达式 ${book.name} 等获取相应属性值进行展示)。 --%>
</c:forEach>
<tr>
<td></td>
<td></td>
@ -61,4 +56,4 @@
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
</html>

@ -7,17 +7,27 @@
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme()
+"://"
+request.getServerName()
+":"
+request.getServerPort()
+request.getContextPath()
+"/";
pageContext.setAttribute("bastPath",basePath);
// 获取当前请求的协议如http或https
String scheme = request.getScheme();
// 获取服务器的主机名或IP地址
String serverName = request.getServerName();
// 获取服务器的端口号
int serverPort = request.getServerPort();
// 获取当前应用的上下文路径
String contextPath = request.getContextPath();
// 拼接basePath用于构建项目的根路径
String basePath = scheme + "://" + serverName + ":" + serverPort + contextPath + "/";
// 将basePath存储到pageContext中方便在页面中使用
pageContext.setAttribute("basePath", basePath);
%>
<!-- 写base标签永远固定相对路径跳转的结果 -->
<base href=<%=basePath%>>
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>
<base href="<%=basePath%>">
<!-- 引入外部的CSS样式文件 -->
<link type="text/css" rel="stylesheet" href="static/css/style.css">
<!-- 引入外部的jQuery库 -->
<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>

@ -8,71 +8,82 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div id="page_nav">
<!-- 首页链接 -->
<a href="${requestScope.page.url}&pageNo=1">首页</a>
<c:if test="${requestScope.page.pageNo>1}">
<a href="${requestScope.page.url}&pageNo=${requestScope.page.pageNo-1}">上一页</a>
<!-- 上一页链接 -->
<c:if test="${requestScope.page.pageNo > 1}">
<a href="${requestScope.page.url}&pageNo=${requestScope.page.pageNo - 1}">上一页</a>
</c:if>
<!-- 分页逻辑 -->
<c:choose>
<%-- 当总页码小于等于5的情况 --%>
<c:when test="${ requestScope.page.pageTotal <= 5 }">
<c:when test="${requestScope.page.pageTotal <= 5}">
<c:set var="begin" value="1"></c:set>
<c:set var="end" value="${ requestScope.page.pageTotal }"></c:set>
<c:set var="end" value="${requestScope.page.pageTotal}"></c:set>
</c:when>
<c:otherwise>
<%-- 当总页码大于5的情况 --%>
<c:choose>
<%-- 当前页码是前三 --%>
<c:when test="${ requestScope.page.pageNo <= 3 }">
<c:when test="${requestScope.page.pageNo <= 3}">
<c:set var="begin" value="1"></c:set>
<c:set var="end" value="5"></c:set>
</c:when>
<%-- 当前页码是后三 --%>
<c:when test="${ requestScope.page.pageNo >= requestScope.page.pageTotal - 2 }">
<c:set var="begin" value="${ requestScope.page.pageTotal - 4 }"></c:set>
<c:set var="end" value="${ requestScope.page.pageTotal }"></c:set>
<c:when test="${requestScope.page.pageNo >= requestScope.page.pageTotal - 2}">
<c:set var="begin" value="${requestScope.page.pageTotal - 4}"></c:set>
<c:set var="end" value="${requestScope.page.pageTotal}"></c:set>
</c:when>
<c:otherwise>
<c:set var="begin" value="${ requestScope.page.pageNo - 2 }"></c:set>
<c:set var="end" value="${ requestScope.page.pageNo + 2 }"></c:set>
<%-- 当前页码在中间 --%>
<c:set var="begin" value="${requestScope.page.pageNo - 2}"></c:set>
<c:set var="end" value="${requestScope.page.pageNo + 2}"></c:set>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
<c:forEach begin="${ begin }" end="${ end }" var="i">
<c:if test="${ i == requestScope.page.pageNo }">【${ i }】</c:if>
<c:if test="${ i != requestScope.page.pageNo }"><a href="${requestScope.page.url}&pageNo=${i}">${i}</a></c:if>
<!-- 显示页码 -->
<c:forEach begin="${begin}" end="${end}" var="i">
<c:if test="${i == requestScope.page.pageNo}">【${i}】</c:if>
<c:if test="${i != requestScope.page.pageNo}">
<a href="${requestScope.page.url}&pageNo=${i}">${i}</a>
</c:if>
</c:forEach>
<c:if test="${requestScope.page.pageNo<requestScope.page.pageTotal}">
<a href="${requestScope.page.url}&pageNo=${requestScope.page.pageNo+1}">下一页</a>
<!-- 下一页链接 -->
<c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
<a href="${requestScope.page.url}&pageNo=${requestScope.page.pageNo + 1}">下一页</a>
</c:if>
<!-- 末页链接 -->
<a href="${requestScope.page.url}&pageNo=${requestScope.page.pageTotal}">末页</a>
<!-- 显示总页数和总记录数 -->
共${requestScope.page.pageTotal}页,${requestScope.page.pageTotalCount}条记录
<!-- 跳转页码输入框 -->
到第<input value="${param.pageNo}" name="pn" id="pn_input"/>页
<input id="searchPageBtn" type="button" value="确定">
<!-- 跳转页码的JavaScript脚本 -->
<script type="text/javascript">
$(function () {
// 点击“确定”按钮时触发跳转
$("#searchPageBtn").click(function () {
var pageNo = $("#pn_input").val()
var pageTotal = ${requestScope.page.pageTotal}
if(pageNo<1) pageNo=1
if(pageNo>pageTotal) pageNo=pageTotal
location.href="${requestScope.basePath}${requestScope.page.url}&pageNo="+pageNo;
// 获取用户输入的页码
var pageNo = $("#pn_input").val();
// 获取总页数
var pageTotal = ${requestScope.page.pageTotal};
// 校验页码范围
if (pageNo < 1) pageNo = 1;
if (pageNo > pageTotal) pageNo = pageTotal;
// 跳转到指定页码
location.href = "${requestScope.basePath}${requestScope.page.url}&pageNo=" + pageNo;
});
});
</script>

@ -1,37 +1,35 @@
<%--
Created by IntelliJ IDEA.
User: jhu
Date: 2020/10/5
Time: 22:17
To change this template use File | Settings | File Templates.
此部分为文件的创建相关注释,说明该文件是由 IntelliJ IDEA 创建的,创建用户是 jhu创建时间为2020年10月5日22时17分同时告知若要修改此模板可通过文件设置里的文件模板相关功能来操作。
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>404</title>
<%-- 引入公共的头部页面header.jsp一般这个头部页面中会包含诸如页面通用的样式文件引入、脚本文件引入或者一些页面头部通用布局结构等内容方便在多个页面间复用代码。 --%>
<%@include file="/pages/common/header.jsp"%>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo.gif" >
<span class="wel_word">404error</span>
</div>
<div id="main">
<table>
<tr>
<td style="width: 300px">亲,您访问的页面不存在或已被删除!</td>
<%-- 在表格的第一行的单元格中,显示提示信息,告知用户所访问的页面出现了不存在或者已被删除的情况。 --%>
</tr>
<tr>
<td>
<a href="index.jsp" style="size: 300px;color: red">返回首页</a>
<%-- 在表格的第二行单元格中设置一个超链接链接到“index.jsp”页面并且设置了链接文字的样式包括字号原代码中“size”属性写法有误正确的是“font-size”这里是按原代码注释和颜色引导用户点击返回首页。 --%>
</td>
</tr>
</table>
</div>
<!-- 这是页脚的引入 -->
<%@ include file="/pages/common/footer.jsp" %>
<%-- 通过此指令引入公共的页脚页面footer.jsp该页脚页面通常包含页面底部的一些通用信息比如版权声明、联系方式等内容同样是为了实现代码复用。 --%>
</body>
</html>

@ -1,37 +1,36 @@
<%--
Created by IntelliJ IDEA.
User: jhu
Date: 2020/10/5
Time: 22:17
To change this template use File | Settings | File Templates.
这部分是文件创建相关的注释信息表明该文件是由IntelliJ IDEA创建的创建者是“jhu”创建时间是2020年10月5日22时17分同时提示若要修改这个模板文件可以通过“File | Settings | File Templates”这个路径去操作。
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>500</title>
<%-- 通过JSP的指令引入公共的头部页面header.jsp通常在这个公共头部页面里会包含页面通用的样式表链接、JavaScript脚本引入或者一些通用的页面头部布局相关的代码等目的是实现代码复用让多个页面能共享这些公共部分的设置。 --%>
<%@include file="/pages/common/header.jsp"%>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo.gif" >
<span class="wel_word">500error</span>
<%-- 在“header”这个div区域中展示了一个logo图片虽然图片的替代文本为空可适当补充使其更友好以及显示“500error”字样用于提示当前页面出现的是500相关错误情况。 --%>
</div>
<div id="main">
<table>
<tr>
<td style="width: 300px">HTTP状态 500 - 内部服务器错误</td>
<%-- 在表格的第一行单元格里明确给出提示信息告知用户当前出现了HTTP状态码为500的内部服务器错误让用户知晓页面无法正常显示的原因所在。 --%>
</tr>
<tr>
<td>
<a href="index.jsp" style="size: 300px;color: red">返回首页</a>
<%-- 在表格的第二行单元格里创建了一个超链接链接指向“index.jsp”页面同时设置了这个链接文字的样式原代码中“size”属性写法不符合规范正确的是“font-size”用于设置字号这里按原代码注释颜色设置为红色引导用户点击该链接返回首页去尝试其他操作。 --%>
</td>
</tr>
</table>
</div>
<!-- 这是页脚的引入 -->
<%@ include file="/pages/common/footer.jsp" %>
<%-- 此处使用JSP的指令引入公共的页脚页面footer.jsp一般在页脚页面里会放置诸如版权信息、联系方式、网站相关声明等页面底部通用的内容同样是为了复用代码保持网站各页面底部信息的一致性。 --%>
</body>
</html>
</html>

@ -1,38 +1,38 @@
<%--
Created by IntelliJ IDEA.
User: jhu
Date: 2020/10/5
Time: 10:45
To change this template use File | Settings | File Templates.
这部分是关于该文件创建的相关注释内容说明了此文件是通过IntelliJ IDEA创建的创建者是“jhu”创建时间为2020年10月5日10时45分并且告知若要对这个模板文件进行修改可以在文件设置里找到文件模板相关功能来操作。
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>404</title>
<%-- 通过JSP的指令引入公共的头部页面header.jsp通常这个公共头部页面包含了页面通用的一些元素比如样式表的链接、脚本文件的引入或者是页面头部通用的布局结构代码等这样做是为了实现代码复用多个页面可以共用这些设置减少重复编写代码的工作量。 --%>
<%@include file="/pages/common/header.jsp"%>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo.gif" >
<span class="wel_word">错误提示</span>
<%-- 在“header”这个div区域中展示了一个图片其替代文本为空最好能补充合适的替代文本方便屏幕阅读器等识别同时显示“错误提示”字样用于给用户一个直观的页面提示信息的开头部分告知用户当前页面是用于提示出现错误情况的。 --%>
</div>
<div id="main">
<table>
<tr>
<td style="width: 300px">亲,你没有管理员权限哦!</td>
<%-- 在表格的第一行单元格中,明确给出提示信息,告知用户当前操作因为没有管理员权限而无法进行,让用户清楚知晓出现此页面的原因。 --%>
</tr>
<tr>
<td>
<a href="pages/user/login.jsp" style="size: 300px;color: red">管理员登录</a>
<%-- 创建一个超链接链接指向“pages/user/login.jsp”页面也就是引导用户去进行管理员登录操作同时设置了链接文字的样式不过原代码中“size”属性的写法不符合规范正确的应该是“font-size”用于设置字号这里按原代码注释颜色设置为红色使其更醒目方便用户看到并点击操作。 --%>
<a href="index.jsp" style="size: 300px;color: red">返回首页</a>
<%-- 再创建一个超链接指向“index.jsp”页面用于引导用户返回首页同样设置了字号原代码中写法有误和颜色样式给用户提供另一种操作选择方便用户离开当前提示页面。 --%>
</td>
</tr>
</table>
</div>
<!-- 这是页脚的引入 -->
<%@ include file="/pages/common/footer.jsp" %>
<%-- 使用JSP指令引入公共的页脚页面footer.jsp一般来说页脚页面里会放置像版权信息、网站的联系方式、相关声明等页面底部通用的内容通过这种引入方式实现代码复用保证整个网站各个页面的页脚部分信息呈现的一致性。 --%>
</body>
</html>
</html>

@ -2,59 +2,74 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>编辑图书</title>
<meta charset="UTF-8">
<title>编辑图书</title>
<%@include file="/pages/common/header.jsp"%>
<style type="text/css">
h1 {
text-align: center;
margin-top: 200px;
}
h1 a {
color:red;
}
input {
text-align: center;
}
</style>
<style type="text/css">
h1 {
text-align: center;
margin-top: 200px;
}
h1 a {
color:red;
}
input {
text-align: center;
}
</style>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo1.jpg" >
<span class="wel_word">编辑图书</span>
<%@include file="/pages/common/manager_menu.jsp"%>
</div>
<div id="main">
<form action="manager/bookServlet" method="post">
<input type="hidden" name="pageNo" value="${param.pageNo}">
<input type="hidden" name="action" value="${empty param.id ? "add":"update"}"/>
<input type="hidden" name="id" value="${requestScope.book.id}"/>
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<tr>
<td><input name="name" type="text" value="${requestScope.book.name}"/></td>
<td><input name="price" type="text" value="${requestScope.book.price}"/></td>
<td><input name="author" type="text" value="${requestScope.book.author}"/></td>
<td><input name="sales" type="text" value="${requestScope.book.sales}"/></td>
<td><input name="stock" type="text" value="${requestScope.book.stock}"/></td>
<td><input type="submit" value="提交"/></td>
</tr>
</table>
</form>
</div>
<%@include file="/pages/common/footer.jsp"%>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo1.jpg" >
<span class="wel_word">编辑图书</span>
<%@include file="/pages/common/manager_menu.jsp"%>
</div>
<div id="main">
<form action="manager/bookServlet" method="post">
<!-- 隐藏域,用于传递当前页码 -->
<input type="hidden" name="pageNo" value="${param.pageNo}">
<!-- 隐藏域,用于判断是添加还是更新操作 -->
<input type="hidden" name="action" value="${empty param.id ? "add":"update"}"/>
<!-- 隐藏域用于传递图书ID -->
<input type="hidden" name="id" value="${requestScope.book.id}"/>
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<tr>
<!-- 图书名称输入框 -->
<td><input name="name" type="text" value="${requestScope.book.name}"/></td>
<!-- 图书价格输入框 -->
<td><input name="price" type="text" value="${requestScope.book.price}"/></td>
<!-- 图书作者输入框 -->
<td><input name="author" type="text" value="${requestScope.book.author}"/></td>
<!-- 图书销量输入框 -->
<td><input name="sales" type="text" value="${requestScope.book.sales}"/></td>
<!-- 图书库存输入框 -->
<td><input name="stock" type="text" value="${requestScope.book.stock}"/></td>
<!-- 提交按钮 -->
<td><input type="submit" value="提交"/></td>
</tr>
</table>
</form>
</div>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save