Java Web实训项目:西蒙购物网

news2024/12/26 16:30:32

文章目录

  • 一、网站功能需求
  • 二、网站设计思路
    • (一)设计模式
    • (二)网站前台
    • (三)网站后台
      • 1、用户管理
      • 2、类别管理
      • 3、商品管理
      • 4、订单管理
    • (四)购物流程图
  • 三、网站运行效果
  • 四、网站实现步骤
    • (一)创建数据库与表
      • 1、创建数据库
      • 2、创建用户表
      • 3、创建类别表
      • 4、创建商品表
      • 5、创建订单表
    • (二)创建Web项目
      • 1、创建Web项目
      • 2、修改Artifact名称
      • 3、重新部署项目
      • 4、编辑首页
      • 5、启动应用,查看效果
    • (三)创建实体类
      • 1、创建用户实体类
      • 2、创建类别实体类
      • 3、创建商品实体类
      • 4、创建订单实体类
    • (四)创建数据库工具类
      • 1、添加数据库驱动程序包

本项目采用MVC模式进行开发,整合JSP + Servlet + DB(DAO),同学们可以通过本次实战,了解Web开发的一般流程。

一、网站功能需求

1、只有注册用户成功登录后才可查看商品类别,查看商品,选购商品,生成订单、查看订单
2、只有管理员才有权限进入购物网后台管理(用户管理 + 类别管理 + 商品管理 + 订单管理)

二、网站设计思路

(一)设计模式

  • 分层架构:展现层(JSP)<——>控制层(Controller)<——>业务层(Service)<——>数据映射层(Mapper)<——>数据库(DB)
    在这里插入图片描述

(二)网站前台

  1. 登录——显示商品类别——显示某类商品信息——查看购物车——生成订单——支付
  2. 注册<——>登录

(三)网站后台

1、用户管理

  • 查看用户
  • 添加用户
  • 修改用户
  • 删除用户

2、类别管理

  • 查看类别
  • 添加类别
  • 修改类别
  • 删除类别

3、商品管理

  • 查看商品
  • 添加商品
  • 修改商品
  • 删除商品

4、订单管理

  • 查看订单
  • 删除订单

(四)购物流程图

  • 管理员登录成功,进入后台管理
  • 普通用户登录成功,进入前台购物
    在这里插入图片描述

三、网站运行效果

  • 操作演示录屏
    在这里插入图片描述

四、网站实现步骤

(一)创建数据库与表

1、创建数据库

  • 数据库 - simonshop
    在这里插入图片描述

2、创建用户表

  • 创建用户表结构 - t_user
    在这里插入图片描述
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `password` varchar(20) DEFAULT NULL,
  `telephone` varchar(11) DEFAULT NULL,
  `register_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `popedom` int(11) DEFAULT NULL COMMENT '0:管理员;1:普通用户',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
  • 在用户表里插入记录
    在这里插入图片描述
INSERT INTO `t_user` VALUES ('1', 'admin', '12345', '15734345678', '2021-12-02 08:40:35', '0');
INSERT INTO `t_user` VALUES ('2', '郑晓红', '11111', '13956567889', '2022-12-20 09:51:43', '1');
INSERT INTO `t_user` VALUES ('3', '温志军', '22222', '13956678907', '2022-12-20 09:52:36', '1');
INSERT INTO `t_user` VALUES ('4', '涂文艳', '33333', '15890905678', '2022-12-05 09:52:56', '1');
  • 查看用户表
    在这里插入图片描述

3、创建类别表

  • 创建类别表结构 - t_category
    在这里插入图片描述
CREATE TABLE `t_category` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品类别标识符',
  `name` varchar(100) NOT NULL COMMENT '商品类别名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
  • 在类别表里插入记录
    在这里插入图片描述
INSERT INTO `t_category` VALUES ('1', '家用电器');
INSERT INTO `t_category` VALUES ('2', '床上用品');
INSERT INTO `t_category` VALUES ('3', '文具用品');
INSERT INTO `t_category` VALUES ('4', '休闲食品');
  • 查看类别表记录
    在这里插入图片描述

4、创建商品表

  • 创建商品表结构 - t_product
    在这里插入图片描述
CREATE TABLE `t_product` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品标识符',
  `name` varchar(200) NOT NULL COMMENT '商品名称',
  `price` double DEFAULT NULL COMMENT '商品单价',
  `add_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `category_id` int(11) DEFAULT NULL COMMENT '商品类别标识符',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
  • 在商品表里插入记录
    在这里插入图片描述
INSERT INTO `t_product` VALUES ('1', '容声电冰箱', '2000', '2016-12-20 09:54:41', '1');
INSERT INTO `t_product` VALUES ('2', '松下电视', '5000', '2016-12-20 09:54:35', '1');
INSERT INTO `t_product` VALUES ('3', '红岩墨水', '3', '2016-12-20 09:56:05', '3');
INSERT INTO `t_product` VALUES ('4', '海尔洗衣机', '1000', '2016-11-30 08:58:09', '1');
INSERT INTO `t_product` VALUES ('5', '新宇电饭煲', '1200', '2016-12-20 09:55:11', '1');
INSERT INTO `t_product` VALUES ('6', '英雄微波炉', '600', '2016-12-20 09:55:39', '1');
INSERT INTO `t_product` VALUES ('7', '红双喜席梦思', '700', '2016-11-28 08:59:38', '2');
INSERT INTO `t_product` VALUES ('8', '旺仔牛奶糖', '24.4', '2016-12-20 10:00:11', '4');
INSERT INTO `t_product` VALUES ('9', '西蒙枕头', '100', '2016-12-20 09:56:57', '2');
INSERT INTO `t_product` VALUES ('10', '甜甜毛毯', '400', '2016-12-20 09:57:26', '2');
INSERT INTO `t_product` VALUES ('11', '永久钢笔', '50', '2016-12-20 09:57:30', '3');
INSERT INTO `t_product` VALUES ('12', '硬面抄笔记本', '5', '2016-12-20 09:57:53', '3');
INSERT INTO `t_product` VALUES ('13', '晨光橡皮擦', '0.5', '2016-11-30 09:02:40', '3');
INSERT INTO `t_product` VALUES ('14', '美的空调', '3000', '2016-11-03 09:03:02', '1');
INSERT INTO `t_product` VALUES ('15', '迷你深海鱼肠', '14.4', '2016-12-02 10:01:14', '4');
  • 查看商品表记录
    在这里插入图片描述

5、创建订单表

  • 创建订单表结构 - t_order
    在这里插入图片描述
CREATE TABLE `t_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单标识符',
  `username` varchar(20) DEFAULT NULL COMMENT '用户名',
  `telephone` varchar(11) DEFAULT NULL COMMENT '电话号码',
  `total_price` double DEFAULT NULL COMMENT '总金额',
  `delivery_address` varchar(50) DEFAULT NULL COMMENT '送货地址',
  `order_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '下单时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
  • 在订单表里插入记录
    在这里插入图片描述
INSERT INTO `t_order` VALUES ('1', '郑晓红', '13956567889', '2000', '泸职院大数据学院', '2023-05-25 17:12:36');
INSERT INTO `t_order` VALUES ('2', '温志军', '13956678907', '1000', '泸职院机械工程学院', '2023-05-26 17:12:17');
  • 查看订单表记录
    在这里插入图片描述

(二)创建Web项目

1、创建Web项目

  • 创建Java Enterprise项目,添加Web Application功能
    在这里插入图片描述
  • 设置项目名称与保存位置
    在这里插入图片描述
  • 单击【Finish】按钮
    在这里插入图片描述

2、修改Artifact名称

  • 将Artifact名称改为simonshop
    在这里插入图片描述

3、重新部署项目

  • 先移除,后添加,重新部署项目
    在这里插入图片描述
  • 切换到【Server】选项卡在这里插入图片描述

4、编辑首页

  • 首页 - index.jsp
    在这里插入图片描述
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>首页</title>
    </head>
    <body>
        <h1 style="color: blue; text-align: center">Java Web实训项目:西蒙购物网</h1>
        <h3 style="text-align: center"><%= new Date()%></h3>
        <p style="text-align: center"><a href="login.jsp">跳转到登录页面</a></p>
    </body>
</html>

5、启动应用,查看效果

  • 启动服务器,显示首页
    在这里插入图片描述

(三)创建实体类

  • 创建四个实体类:UserCategoryProductOrder,与四张表t_usert_categoryt_productt_order一一对应。ORM(Object Relation Mapping)——对象关系映射。

1、创建用户实体类

  • 创建net.huawei.shop.bean包,在包里创建User
    在这里插入图片描述
package net.huawei.shop.bean;

import java.util.Date;

/**
 * 功能:用户实体类
 * 作者:华卫
 * 日期:2023年05月29日
 */
public class User {
    private int id; // 用户标识符
    private String username; // 用户名
    private String password; // 密码
    private String telephone; // 电话
    private Date registerTime; // 注册时间
    private int popedom; // 权限(0:管理员;1:普通用户)

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public Date getRegisterTime() {
        return registerTime;
    }

    public void setRegisterTime(Date registerTime) {
        this.registerTime = registerTime;
    }

    public int getPopedom() {
        return popedom;
    }

    public void setPopedom(int popedom) {
        this.popedom = popedom;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", telephone='" + telephone + '\'' +
                ", registerTime=" + registerTime +
                ", popedom=" + popedom +
                '}';
    }
}

2、创建类别实体类

  • net.huawei.shop.bean包里创建Category
    在这里插入图片描述
package net.huawei.shop.bean;

/**
 * 功能:类别实体类
 * 作者:华卫
 * 日期:2023年05月29日
 */
public class Category {
    private int id; // 类别标识符
    private String name; // 类别名称

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Category{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

3、创建商品实体类

  • net.huawei.shop.bean包里创建Product
    在这里插入图片描述
package net.huawei.shop.bean;

import java.util.Date;

/**
 * 功能:商品实体类
 * 作者:华卫
 * 日期:2023年05月29日
 */
public class Product {
    private int id; // 商品标识符
    private String name; // 商品名称
    private double price; // 商品价格
    private Date addTime; // 商品上架时间
    private int categoryId; // 类别标识符

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public Date getAddTime() {
        return addTime;
    }

    public void setAddTime(Date addTime) {
        this.addTime = addTime;
    }

    public int getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(int categoryId) {
        this.categoryId = categoryId;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", addTime=" + addTime +
                ", categoryId=" + categoryId +
                '}';
    }
}

4、创建订单实体类

  • net.huawei.shop.bean包里创建Order
    在这里插入图片描述
package net.huawei.shop.bean;

import java.util.Date;

/**
 * 功能:订单实体类
 * 作者:华卫
 * 日期:2023年05月29日
 */
public class Order {
    private int id; // 订单标识符
    private String username; // 用户名
    private String telephone; // 联系电话
    private double totalPrice; // 订单总金额
    private String deliveryAddress; // 送货地址
    private Date orderTime; // 下单时间

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public String getDeliveryAddress() {
        return deliveryAddress;
    }

    public void setDeliveryAddress(String deliveryAddress) {
        this.deliveryAddress = deliveryAddress;
    }

    public Date getOrderTime() {
        return orderTime;
    }

    public void setOrderTime(Date orderTime) {
        this.orderTime = orderTime;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", telephone='" + telephone + '\'' +
                ", totalPrice=" + totalPrice +
                ", deliveryAddress='" + deliveryAddress + '\'' +
                ", orderTime=" + orderTime +
                '}';
    }
}

(四)创建数据库工具类

1、添加数据库驱动程序包

  • \WEB-INF里创建lib子目录,添加MySQL驱动程序的jar包
    在这里插入图片描述
  • 将数据库驱动程序包作为库添加到项目
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

2、在src下创建net.hw.shop.dbutil包,在里面创建ConnectionManager类

package net.hw.shop.dbutil;

/**

  • 功能:数据库连接管理类
  • 作者:华卫
  • 日期:2019年12月2日
    */

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.swing.JOptionPane;

public class ConnectionManager {
/**
* 数据库驱动程序
/
private static final String DRIVER = “com.mysql.jdbc.Driver”;
/
*
* 数据库统一资源标识符
/
private static final String URL = “jdbc:mysql://localhost:3306/simonshop”;
/
*
* 数据库用户名
/
private static final String USERNAME = “root”;
/
*
* 数据库密码
*/
private static final String PASSWORD = “P@ssw0rd”;

/**
 * 私有化构造方法,拒绝实例化
 */
private ConnectionManager() {
}

/**
 * 获取数据库连接静态方法
 *
 * @return 数据库连接对象
 */
public static Connection getConnection() {
    // 定义数据库连接
    Connection conn = null;
    try {
        // 安装数据库驱动程序
        Class.forName(DRIVER);
        // 获得数据库连接
        conn = DriverManager.getConnection(URL
                + "?useUnicode=true&characterEncoding=UTF8", USERNAME, PASSWORD);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    // 返回数据库连接
    return conn;
}

/**
 * 关闭数据库连接静态方法
 *
 * @param conn
 */
public static void closeConnection(Connection conn) {
    // 判断数据库连接是否为空
    if (conn != null) {
        // 判断数据库连接是否关闭
        try {
            if (!conn.isClosed()) {
                // 关闭数据库连接
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 测试数据库连接是否成功
 *
 * @param args
 */
public static void main(String[] args) {
    // 获得数据库连接
    Connection conn = getConnection();
    // 判断是否连接成功
    if (conn != null) {
        JOptionPane.showMessageDialog(null, "恭喜,数据库连接成功!");
    } else {
        JOptionPane.showMessageDialog(null, "遗憾,数据库连接失败!");
    }

    // 关闭数据库连接
    closeConnection(conn);
}

}
3、运行程序,查看结果

采用数据库连接池,效率更高,建议大家使用数据源方式来获取数据库连接。大家可以参看:Java Web学习笔记07:数据源和JavaBean

4、常见错误解析
(1)连接异常

启动MySQL服务即可解决此问题。

(2)密码错误异常

(3)时区异常

错误原因:这个异常是由于本地时区和MySQL服务器设置的时区不一致造成的。

解决办法:在数据库链接配置后添加?serverTimezone=UTC参数,告知服务器采用UTC时间格式。

(五)数据访问接口(XXXDao)
在src里创建net.hw.shop.dao包,在里面创建UserDao、CategoryDao、ProductDao与OrderDao。

1、用户数据访问接口UserDao

package net.hw.shop.dao;

/**

  • 功能:用户数据访问接口
  • 作者:华卫
  • 日期:2019年12月2日
    */
    import java.util.List;

import net.hw.shop.bean.User;

public interface UserDao {
// 插入用户
int insert(User user);
// 按标识符删除用户
int deleteById(int id);
// 更新用户
int update(User user);
// 按标识符查询用户
User findById(int id);
// 按用户名查询用户
List findByUsername(String username);
// 查询全部用户
List findAll();
// 用户登录
User login(String username, String password);
}
2、类别数据访问接口CategoryDao

package net.hw.shop.dao;

/**

  • 功能:类别数据访问接口
  • 作者:华卫
  • 日期:2019年12月2日
    */
    import java.util.List;

import net.hw.shop.bean.Category;

public interface CategoryDao {
// 插入类别
int insert(Category category);
// 按标识符删除类别
int deleteById(int id);
// 更新类别
int update(Category category);
// 按标识符查询类别
Category findById(int id);
// 查询全部类别
List findAll();
}
3、商品数据访问接口ProductDao

package net.hw.shop.dao;

/**

  • 功能:商品数据访问接口
  • 作者:华卫
  • 日期:2019年12月2日
    */
    import java.util.List;

import net.hw.shop.bean.Product;

public interface ProductDao {
// 插入商品
int insert(Product product);
// 按标识符删除商品
int deleteById(int id);
// 更新商品
int update(Product product);
// 按标识符查询商品
Product findById(int id);
// 按类别查询商品
List findByCategoryId(int categoryId);
// 查询全部商品
List findAll();
}
4、订单数据访问接口OrderDao

package net.hw.shop.dao;

/**

  • 功能:订单数据访问接口
  • 作者:华卫
  • 日期:2019年12月2日
    */
    import java.util.List;

import net.hw.shop.bean.Order;

public interface OrderDao {
// 插入订单
int insert(Order order);
// 按标识符删除订单
int deleteById(int id);
// 更新订单
int update(Order order);
// 按标识符查询订单
Order findById(int id);
// 查询最后一个订单
Order findLast();
// 查询全部订单
List findAll();
}
(六)数据访问接口实现类XXXDaoImpl
在src下创建net.hw.shop.dao.impl包,在里面创建UserDaoImpl、CategoryDaoImpl、ProductDaoImpl与OrderDaoImpl。

1、用户数据访问接口实现类UserDaoImpl

package net.hw.shop.dao.impl;

/**

  • 功能:用户数据访问接口实现类
  • 作者:华卫
  • 日期:2019年12月2日
    */
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.sql.Timestamp;
    import java.util.ArrayList;
    import java.util.List;

import net.hw.shop.bean.User;
import net.hw.shop.dao.UserDao;
import net.hw.shop.dbutil.ConnectionManager;

public class UserDaoImpl implements UserDao {
/**
* 插入用户
*/
@Override
public int insert(User user) {
// 定义插入记录数
int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "INSERT INTO t_user (username, password, telephone, register_time, popedom)"
            + " VALUES (?, ?, ?, ?, ?)";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, user.getUsername());
        pstmt.setString(2, user.getPassword());
        pstmt.setString(3, user.getTelephone());
        pstmt.setTimestamp(4, new Timestamp(user.getRegisterTime().getTime()));
        pstmt.setInt(5, user.getPopedom());
        // 执行更新操作,插入新记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回插入记录数
    return count;
}

/**
 * 删除用户记录
 */
@Override
public int deleteById(int id) {
    // 定义删除记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "DELETE FROM t_user WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行更新操作,删除记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回删除记录数
    return count;
}

/**
 * 更新用户
 */
@Override
public int update(User user) {
    // 定义更新记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "UPDATE t_user SET username = ?, password = ?, telephone = ?,"
            + " register_time = ?, popedom = ? WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, user.getUsername());
        pstmt.setString(2, user.getPassword());
        pstmt.setString(3, user.getTelephone());
        pstmt.setTimestamp(4, new Timestamp(user.getRegisterTime().getTime()));
        pstmt.setInt(5, user.getPopedom());
        pstmt.setInt(6, user.getId());
        // 执行更新操作,更新记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回更新记录数
    return count;
}

/**
 * 按标识符查询用户
 */
@Override
public User findById(int id) {
    // 声明用户
    User user = null;

    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_user WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行SQL查询,返回结果集
        ResultSet rs = pstmt.executeQuery();
        // 判断结果集是否有记录
        if (rs.next()) {
            // 实例化用户
            user = new User();
            // 利用当前记录字段值去设置商品类别的属性
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setPassword(rs.getString("password"));
            user.setTelephone(rs.getString("telephone"));
            user.setRegisterTime(rs.getTimestamp("register_time"));
            user.setPopedom(rs.getInt("popedom"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回用户
    return user;
}

@Override
public List<User> findByUsername(String username) {
    // 声明用户列表
    List<User> users = new ArrayList<User>();
    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_user WHERE username = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, username);
        // 执行SQL查询,返回结果集
        ResultSet rs = pstmt.executeQuery();
        // 遍历结果集
        while (rs.next()) {
            // 创建类别实体
            User user = new User();
            // 设置实体属性
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setPassword(rs.getString("password"));
            user.setTelephone(rs.getString("telephone"));
            user.setRegisterTime(rs.getTimestamp("register_time"));
            user.setPopedom(rs.getInt("popedom"));
            // 将实体添加到用户列表
            users.add(user);
        }
        // 关闭结果集
        rs.close();
        // 关闭语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭数据库连接
        ConnectionManager.closeConnection(conn);
    }
    // 返回用户列表
    return users;
}

@Override
public List<User> findAll() {
    // 声明用户列表
    List<User> users = new ArrayList<User>();
    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_user";
    try {
        // 创建语句对象
        Statement stmt = conn.createStatement();
        // 执行SQL,返回结果集
        ResultSet rs = stmt.executeQuery(strSQL);
        // 遍历结果集
        while (rs.next()) {
            // 创建用户实体
            User user = new User();
            // 设置实体属性
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setPassword(rs.getString("password"));
            user.setTelephone(rs.getString("telephone"));
            user.setRegisterTime(rs.getTimestamp("register_time"));
            user.setPopedom(rs.getInt("popedom"));
            // 将实体添加到用户列表
            users.add(user);
        }
        // 关闭结果集
        rs.close();
        // 关闭语句对象
        stmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭数据库连接
        ConnectionManager.closeConnection(conn);
    }
    // 返回用户列表
    return users;
}

/**
 * 登录方法
 */
@Override
public User login(String username, String password) {
    // 定义用户对象
    User user = null;
    // 获取数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_user WHERE username = ? AND password = ?";
    try {
        // 创建预备语句对象
        PreparedStatement psmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        psmt.setString(1, username);
        psmt.setString(2, password);
        // 执行查询,返回结果集
        ResultSet rs = psmt.executeQuery();
        // 判断结果集是否有记录
        if (rs.next()) {
            // 实例化用户对象
            user = new User();
            // 用记录值设置用户属性
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("username"));
            user.setPassword(rs.getString("password"));
            user.setTelephone(rs.getString("telephone"));
            user.setRegisterTime(rs.getDate("register_time"));
            user.setPopedom(rs.getInt("popedom"));
        }
        // 关闭结果集
        rs.close();
        // 关闭预备语句
        psmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭数据库连接
        ConnectionManager.closeConnection(conn);
    }

    // 返回用户对象
    return user;
}

}
我们需要对用户数据访问接口实现类的各个方法进行单元测试,采用JUnit来进行单元测试。

在项目根目录创建一个test文件夹,然后在项目结构窗口里将其标记为"Tests",这样文件夹颜色变成绿色。

在test文件夹里创建net.hw.shop.dao.impl包,在里面创建测试类TestUserDaoImpl:

(1)编写测试登录方法testLogin()

将光标定位到@Test注解符,按组合键Alt + Enter:

package net.hw.shop.dao.impl;

import net.hw.shop.bean.User;
import net.hw.shop.dao.UserDao;
import org.junit.Test;

public class TestUserDaoImpl {
@Test
public void testLogin() {
String username, password;

    username = "admin";
    password = "12345";
    
    // 父接口指向子类对象
    UserDao userDao = new UserDaoImpl();
    User user = userDao.login(username, password);

    // 判断用户登录是否成功
    if (user != null) {
        System.out.println("恭喜,登录成功!");
    } else {
        System.out.println("遗憾,登录失败!");
    }
}

}
运行单元测试方法testLogin():

查看单元测试结果:

修改一下登录密码,再进行单元测试,看结果如何:

(2)编写测试方法testUpdate()

将用户【涂文艳】的密码改为“903213",电话改为“13945457890”。涂文艳用户的id是4。

运行单元测试方法testUpdate(),结果如下:

修改一下测试代码再测试,结果如下:

课堂练习:完成UserDaoImpl其余方法的单元测试。

思考题:

(1)如何避免插入同名用户?插入同名用户时,提示用户名已存在。

(2)如何避免更新用户记录时注册时间在当前时间之后的问题?

2、类别数据访问接口实现类CategoryDaoImpl

package net.hw.shop.dao.impl;

/**

  • 功能:类别数据访问接口实现类
  • 作者:华卫
  • 日期:2019年12月10日
    */
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;

import net.hw.shop.bean.Category;
import net.hw.shop.dao.CategoryDao;
import net.hw.shop.dbutil.ConnectionManager;

public class CategoryDaoImpl implements CategoryDao {
/**
* 插入类别
*/
@Override
public int insert(Category category) {
// 定义插入记录数
int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "INSERT INTO t_category (name) VALUES (?)";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, category.getName());
        // 执行更新操作,插入新录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回插入记录数
    return count;
}

/**
 * 删除类别
 */
@Override
public int deleteById(int id) {
    // 定义删除记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "DELETE FROM t_category WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行更新操作,删除记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回删除记录数
    return count;
}

/**
 * 更新类别
 */
@Override
public int update(Category category) {
    // 定义更新记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "UPDATE t_category SET name = ? WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, category.getName());
        pstmt.setInt(2, category.getId());
        // 执行更新操作,更新记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回更新记录数
    return count;
}

/**
 * 按标识符查询类别
 */
@Override
public Category findById(int id) {
    // 声明商品类别
    Category category = null;

    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_category WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行SQL查询,返回结果集
        ResultSet rs = pstmt.executeQuery();
        // 判断结果集是否有记录
        if (rs.next()) {
            // 实例化商品类别
            category = new Category();
            // 利用当前记录字段值去设置商品类别的属性
            category.setId(rs.getInt("id"));
            category.setName(rs.getString("name"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回商品类别
    return category;
}

/**
 * 查询全部类别
 */
@Override
public List<Category> findAll() {
    // 声明类别列表
    List<Category> categories = new ArrayList<Category>();
    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_category";
    try {
        // 创建语句对象
        Statement stmt = conn.createStatement();
        // 执行SQL,返回结果集
        ResultSet rs = stmt.executeQuery(strSQL);
        // 遍历结果集
        while (rs.next()) {
            // 创建类别实体
            Category category = new Category();
            // 设置实体属性
            category.setId(rs.getInt("id"));
            category.setName(rs.getString("name"));
            // 将实体添加到类别列表
            categories.add(category);
        }
        // 关闭结果集
        rs.close();
        // 关闭语句对象
        stmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭数据库连接
        ConnectionManager.closeConnection(conn);
    }
    // 返回类别列表
    return categories;
}

}
创建测试类TestCategoryDaoImpl,编写测试方法testFindAll():

运行测试方法testFindAll(),结果如下:

此时,再运行测试方法testFindAll(),结果如下:

运行simonshop.sql数据库脚本,恢复数据库:

判断集合categories是否为空,可以有两种处理方式:

categories.size() > 0
!categories.isEmpty()
课堂练习:编写方法测试CatetoryDaoImpl其余的方法。

3、商品数据访问接口实现类ProductDaoImpl

package net.hw.shop.dao.impl;

/**

  • 功能:产品数据访问接口实现类
  • 作者:华卫
  • 日期:2019年12月2日
    */

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import net.hw.shop.bean.Product;
import net.hw.shop.dao.ProductDao;
import net.hw.shop.dbutil.ConnectionManager;

public class ProductDaoImpl implements ProductDao {
/**
* 插入商品
*/
@Override
public int insert(Product product) {
// 定义插入记录数
int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "INSERT INTO t_product (name, price, add_time, category_id)" + " VALUES (?, ?, ?, ?)";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, product.getName());
        pstmt.setDouble(2, product.getPrice());
        pstmt.setTimestamp(3, new Timestamp(product.getAddTime().getTime()));
        pstmt.setInt(4, product.getCategoryId());
        // 执行更新操作,插入新记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回插入记录数
    return count;
}

/**
 * 删除商品
 */
@Override
public int deleteById(int id) {
    // 定义删除记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "DELETE FROM t_product WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行更新操作,删除记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回删除记录数
    return count;
}

/**
 * 更新商品
 */
@Override
public int update(Product product) {
    // 定义更新记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "UPDATE t_product SET name = ?, price = ?, add_time = ?,"
            + " category_id = ? WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, product.getName());
        pstmt.setDouble(2, product.getPrice());
        pstmt.setTimestamp(3, new Timestamp(product.getAddTime().getTime()));
        pstmt.setInt(4, product.getCategoryId());
        pstmt.setInt(5, product.getId());
        // 执行更新操作,更新记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回更新记录数
    return count;
}

/**
 * 按标识符查找商品
 */
@Override
public Product findById(int id) {
    // 声明商品
    Product product = null;
    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_product WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行SQL查询,返回结果集
        ResultSet rs = pstmt.executeQuery();
        // 判断结果集是否有记录
        if (rs.next()) {
            // 实例化商品
            product = new Product();
            // 利用当前记录字段值去设置商品类别的属性
            product.setId(rs.getInt("id"));
            product.setName(rs.getString("name"));
            product.setPrice(rs.getDouble("price"));
            product.setAddTime(rs.getTimestamp("add_time"));
            product.setCategoryId(rs.getInt("category_id"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回商品
    return product;
}

/**
 * 按类别查询商品
 */
@Override
public List<Product> findByCategoryId(int categoryId) {
    // 定义商品列表
    List<Product> products = new ArrayList<Product>();

    // 获取数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_product WHERE category_id = ?";
    try {
        // 创建预备语句
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, categoryId);
        // 执行SQL语句,返回结果集
        ResultSet rs = pstmt.executeQuery();
        // 遍历结果集,将其中的每条记录生成商品对象,添加到商品列表
        while (rs.next()) {
            // 实例化商品对象
            Product product = new Product();
            // 利用当前记录字段值设置实体对应属性
            product.setId(rs.getInt("id"));
            product.setName(rs.getString("name"));
            product.setPrice(rs.getDouble("price"));
            product.setAddTime(rs.getTimestamp("add_time"));
            product.setCategoryId(rs.getInt("category_id"));
            // 将商品添加到商品列表
            products.add(product);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }
    // 返回商品列表
    return products;
}

/**
 * 查询全部商品
 */
@Override
public List<Product> findAll() {
    // 声明商品列表
    List<Product> products = new ArrayList<Product>();
    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_product";
    try {
        // 创建语句对象
        Statement stmt = conn.createStatement();
        // 执行SQL,返回结果集
        ResultSet rs = stmt.executeQuery(strSQL);
        // 遍历结果集
        while (rs.next()) {
            // 创建商品实体
            Product product = new Product();
            // 设置实体属性
            product.setId(rs.getInt("id"));
            product.setName(rs.getString("name"));
            product.setPrice(rs.getDouble("price"));
            product.setAddTime(rs.getTimestamp("add_time"));
            product.setCategoryId(rs.getInt("category_id"));
            // 将实体添加到商品列表
            products.add(product);
        }
        // 关闭结果集
        rs.close();
        // 关闭语句对象
        stmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭数据库连接
        ConnectionManager.closeConnection(conn);
    }
    // 返回商品列表
    return products;
}

}

创建测试类TestProductDaoImpl,编写测试方法testFindByCategoryId():

运行测试方法testFindByCategoryId(),结果如下:

修改一下查询的类别id,比如改成5,再运行测试方法testFindByCategoryId(),结果如下:

我们打开t_category表,添加一条新记录:

此时,再运行测试方法testFindByCategoryId(),结果如下:

为了不影响后面的操作,我们还是将【时尚服装】类别删除。

课堂练习:编写方法测试ProductDaoImpl其余方法。

4、订单数据访问接口实现类OrderDaoImpl

package net.hw.shop.dao.impl;
/**

  • 功能:订单数据访问接口实现类
  • 作者:华卫
  • 日期:2019年12月2日
    */

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import net.hw.shop.bean.Order;
import net.hw.shop.dao.OrderDao;
import net.hw.shop.dbutil.ConnectionManager;

public class OrderDaoImpl implements OrderDao {
/**
* 插入订单
*/
@Override
public int insert(Order order) {
// 定义插入记录数
int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "INSERT INTO t_order (username, telephone, total_price, delivery_address, order_time)"
            + " VALUES (?, ?, ?, ?, ?)";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, order.getUsername());
        pstmt.setString(2, order.getTelephone());
        pstmt.setDouble(3, order.getTotalPrice());
        pstmt.setString(4, order.getDeliveryAddress());
        pstmt.setTimestamp(5, new Timestamp(order.getOrderTime().getTime()));
        // 执行更新操作,插入记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回插入记录数
    return count;
}

/**
 * 删除订单
 */
@Override
public int deleteById(int id) {
    // 定义删除记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "DELETE FROM t_order WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行更新操作,删除记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回删除记录数
    return count;
}

/**
 * 更新订单
 */
@Override
public int update(Order order) {
    // 定义更新记录数
    int count = 0;

    // 获得数据库连接
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "UPDATE t_order SET username = ?, telephone = ?, total_price = ?,"
            + " delivery_address = ?, order_time = ? WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setString(1, order.getUsername());
        pstmt.setString(2, order.getTelephone());
        pstmt.setDouble(3, order.getTotalPrice());
        pstmt.setString(4, order.getDeliveryAddress());
        pstmt.setTimestamp(5, new Timestamp(order.getOrderTime().getTime()));
        pstmt.setInt(6, order.getId());
        // 执行更新操作,更新记录
        count = pstmt.executeUpdate();
        // 关闭预备语句对象
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回更新记录数
    return count;
}

/**
 * 查询最后一个订单
 */
@Override
public Order findLast() {
    // 声明订单
    Order order = null;
    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_order";
    try {
        // 创建语句对象
        Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
        // 执行SQL,返回结果集
        ResultSet rs = stmt.executeQuery(strSQL);
        // 定位到最后一条记录
        if (rs.last()) {
            // 创建订单实体
            order = new Order();
            // 设置实体属性
            order.setId(rs.getInt("id"));
            order.setUsername(rs.getString("username"));
            order.setTelephone(rs.getString("telephone"));
            order.setTotalPrice(rs.getDouble("total_price"));
            order.setDeliveryAddress(rs.getString("delivery_address"));
            order.setOrderTime(rs.getTimestamp("order_time"));
        }
        // 关闭结果集
        rs.close();
        // 关闭语句对象
        stmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭数据库连接
        ConnectionManager.closeConnection(conn);
    }
    // 返回订单对象
    return order;
}

/**
 * 按标识符查询订单
 */
@Override
public Order findById(int id) {
    // 声明订单
    Order order = null;

    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_order WHERE id = ?";
    try {
        // 创建预备语句对象
        PreparedStatement pstmt = conn.prepareStatement(strSQL);
        // 设置占位符的值
        pstmt.setInt(1, id);
        // 执行SQL查询,返回结果集
        ResultSet rs = pstmt.executeQuery();
        // 判断结果集是否有记录
        if (rs.next()) {
            // 实例化订单
            order = new Order();
            // 利用当前记录字段值去设置订单的属性
            order.setId(rs.getInt("id"));
            order.setUsername(rs.getString("username"));
            order.setTelephone(rs.getString("telephone"));
            order.setDeliveryAddress(rs.getString("delivery_address"));
            order.setOrderTime(rs.getTimestamp("order_time"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        ConnectionManager.closeConnection(conn);
    }

    // 返回订单
    return order;
}

/**
 * 查询全部订单
 */
@Override
public List<Order> findAll() {
    // 声明订单列表
    List<Order> orders = new ArrayList<Order>();
    // 获取数据库连接对象
    Connection conn = ConnectionManager.getConnection();
    // 定义SQL字符串
    String strSQL = "SELECT * FROM t_order";
    try {
        // 创建语句对象
        Statement stmt = conn.createStatement();
        // 执行SQL,返回结果集
        ResultSet rs = stmt.executeQuery(strSQL);
        // 遍历结果集
        while (rs.next()) {
            // 创建订单实体
            Order order = new Order();
            // 设置实体属性
            order.setId(rs.getInt("id"));
            order.setUsername(rs.getString("username"));
            order.setTelephone(rs.getString("telephone"));
            order.setDeliveryAddress(rs.getString("delivery_address"));
            order.setOrderTime(rs.getTimestamp("order_time"));
            // 将实体添加到订单列表
            orders.add(order);
        }
        // 关闭结果集
        rs.close();
        // 关闭语句对象
        stmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭数据库连接
        ConnectionManager.closeConnection(conn);
    }
    // 返回用户列表
    return orders;
}

}
创建测试类TestOrderDaoImpl,编写测试方法testFinAll():

运行测试方法testFinAll(),结果如下:

此时,再运行测试方法testFinAll(),结果如下:

课堂练习:编写方法测试OrderDaoImpl其余方法。

(七)数据访问服务类XXXService
在src里创建net.hw.shop.service包,在里面创建四个服务类:UserService、CategoryService、ProductService与OrderService。

1、用户服务类UserService

package net.hw.shop.service;

/**

  • 功能:用户服务类
  • 作者:华卫
  • 日期:2019年12月2日
    */

import java.util.List;

import net.hw.shop.bean.User;
import net.hw.shop.dao.UserDao;
import net.hw.shop.dao.impl.UserDaoImpl;

public class UserService {
/**
* 声明用户访问对象
*/
private UserDao userDao = new UserDaoImpl();

public int addUser(User user) {
    return userDao.insert(user);
}

public int deleteUserById(int id) {
    return userDao.deleteById(id);
}

public int updateUser(User user) {
    return userDao.update(user);
}

public User findUserById(int id) {
    return userDao.findById(id);
}

public List<User> findUsersByUsername(String username) {
    return userDao.findByUsername(username);
}

public List<User> findAllUsers() {
    return userDao.findAll();
}

public User login(String username, String password) {
    return userDao.login(username, password);
}

}
2、类别服务类CategoryService

package net.hw.shop.service;

/**

  • 功能:类别服务类
  • 作者:华卫
  • 日期:2019年12月2日
    */

import java.util.List;

import net.hw.shop.bean.Category;
import net.hw.shop.dao.CategoryDao;
import net.hw.shop.dao.impl.CategoryDaoImpl;

public class CategoryService {
/**
* 声明类别数据访问对象
*/
private CategoryDao categoryDao = new CategoryDaoImpl();

public int addCategory(Category category) {
    return categoryDao.insert(category);
}

public int deleteCategoryById(int id) {
    return categoryDao.deleteById(id);
}

public int updateCategory(Category category) {
    return categoryDao.update(category);
}

public Category findCategoryById(int id) {
    return categoryDao.findById(id);
}

public List<Category> findAllCategories() {
    return categoryDao.findAll();
}

}
3、商品服务类ProductService

package net.hw.shop.service;

/**

  • 功能:商品服务类
  • 作者:华卫
  • 日期:2019年12月2日
    */

import java.util.List;

import net.hw.shop.bean.Product;
import net.hw.shop.dao.ProductDao;
import net.hw.shop.dao.impl.ProductDaoImpl;

public class ProductService {
/**
* 声明商品数据访问对象
*/
private ProductDao productDao = new ProductDaoImpl();

public int addProduct(Product product) {
    return productDao.insert(product);
}

public int deleteProductById(int id) {
    return productDao.deleteById(id);
}

public int updateProduct(Product product) {
    return productDao.update(product);
}

public Product findProductById(int id) {
    return productDao.findById(id);
}

public List<Product> findProductsByCategoryId(int categoryId) {
    return productDao.findByCategoryId(categoryId);
}

public List<Product> findAllProducts() {
    return productDao.findAll();
}

}
4、订单服务类OrderService

package net.hw.shop.service;

/**

  • 功能:订单服务类
  • 作者:华卫
  • 日期:2019年12月2日
    */

import java.util.List;

import net.hw.shop.bean.Order;
import net.hw.shop.dao.OrderDao;
import net.hw.shop.dao.impl.OrderDaoImpl;

public class OrderService {
/**
* 声明订单数据访问对象
*/
OrderDao orderDao = new OrderDaoImpl();

public int addOrder(Order order) {
    return orderDao.insert(order);
}

public int deleteOrderById(int id) {
    return orderDao.deleteById(id);
}

public int updateOrder(Order order) {
    return orderDao.update(order);
}

public Order findOrderById(int id) {
    return orderDao.findById(id);
}

public Order findLastOrder() {
    return orderDao.findLast();
}

public List<Order> findAllOrders() {
    return orderDao.findAll();
}

}
课堂练习:创建四个测试类TestUserService、TestCategoryService、TestProductService与TestOrderService,编写测试方法测试四个服务类里的各个方法。

模型层的工作告一个段落,在【Java Web实训项目:西蒙购物网(中)】里做控制层的工作。

Java Web实训项目:西蒙购物网(中)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/583211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法设计 || 实验四 回溯算法-八皇后问题(纯手敲保姆级详细讲解+小白适用+头歌解析)

&#xff08;一&#xff09;八皇后问题描述 在一个8x8的棋盘上放置8个皇后&#xff0c;使得每个皇后都不会互相攻击&#xff0c;即任意两个皇后都不能在同一行、同一列或同一条对角线上。 &#xff08;二&#xff09;算法思路 由于八皇后问题的解法数量较多&#xff0c;本文将介…

mysql+Galera+haproxy高可用

文件下载地址环境准备 1.1准备三台服务器 服务器名称 Ip 描述 Node0 xxx.xxx.xxx.xxx Node1 xxx.xxx.xxx.xxx Node2 xxx.xxx.xxx.xxx 1.3 安装依赖包 sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config setenforce 0 yum -y install lsof ne…

Axure教程—堆积面积图

本文将教大家如何用AXURE制作堆积面积图 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://d4nsae.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87838160 二、功能介绍 简单填写中继器内容即可动态显示值 样式颜色等可…

热榜!阿里出品2023版Java架构师面试指南,涵盖Java所有核心技能

最近很多粉丝朋友私信我说&#xff1a;熬过了去年的寒冬却没熬过现在的内卷&#xff1b;打开Boss直拒一排已读不回&#xff0c;回的基本都是外包&#xff0c;薪资还给的不高&#xff0c;对技术水平要求也远超从前&#xff1b;感觉Java一个初中级岗位有上千人同时竞争&#xff0…

sqlmap的使用详细讲解

一、sqlmap介绍 简介&#xff1a;是一个自动化的sql注入工具&#xff0c;主要功能扫描、发现并利用给定的 url的sql注入漏洞&#xff0c;内置了很多插件 sqlmap支持的数据库&#xff1a; MySQL、oracle、sql-server、DB2.... 注意&#xff1a;sqlmap只用来检测和sq…

用户需求调研的6大注意事项

1、调研目标要清晰具体 调研目标需明确、清晰、具体&#xff0c;只有这样&#xff0c;才能确保在样本选择和问卷设置时&#xff0c;具有明确的目标性和针对性。 2、调研用户精细化梳理 由于用户间存在个体差异&#xff0c;如果只是随机选取部分用户作为调研样本的话&#xff0c…

Tcl-9. string 命令

字符串是 Tcl 中的基本数据类型&#xff0c;所以有大量的字符串操作命令。一个比较重要的问题就是 模式匹配&#xff0c;通过模式匹配将字符串与指定的模式&#xff08;格式&#xff09;相匹配来进行字符串的比较、搜索等 操作。下面string 命令提供了一些简单的模式匹配机制。…

MSP432学习笔记9:定时器A-----捕获

今日得以继续我的MSP432电赛速通之旅~~~ 目录 基础知识&#xff1a; 相关库函数&#xff1a; 一般配置步骤&#xff1a; 首先定义一个初始化函数&#xff1a; 1.复用引脚: 2.配置连续计数结构体: 3.初始化定时器连续计数: 4.配置捕获结构体: 5.初始化定时器为捕获: …

缺少vcruntime140.dll如何修复?电脑小白也能学会修复vcruntime140.dll教程

Vcruntime140.dll是一个用于微软的Visual C软件的动态链接库文件&#xff0c;DLL的全称是动态连接库(Dynamic Link Library)&#xff0c;它是许多不同软件中所共用的文件类型。这个文件被广泛用作其他软件的依赖库&#xff08;dependency&#xff09;。每当您尝试运行一个应用程…

大体量数据迁移成难题,亚马逊云科技如何让迁移能效两不误

逼真的人物设定&#xff0c;精美的主题布局&#xff0c;沉浸式的互动体验&#xff0c;交互式的多元场景……一系列虚拟与现实高度契合又相互映射的设定&#xff0c;成就了“元宇宙”游戏世界的无穷魅力。GVERSE开发的Blockman Go平台就是有着相当大体量的UGC&#xff08;用户生…

优秀的开源测试工具和框架推荐:精选十大神器!

目录 引言 Katalon Studio Selenium Appium JMeter SOAP UI Robot Framework Watir JUnit Robotium Citrus 结语 引言 你是一位测试从业者&#xff0c;时刻关注着最新的测试工具和框架。但在众多的选择面前&#xff0c;你是否感到困惑和无从下手&#xff1f; 别担…

Android音视频开发1:Android Studio安装

1.JDK安装&#xff0c;至少安装JAVA 1.7 对比项目 Android iOS 开发语言 Java Objective-c&#xff0c;Swift 系统开放性 Android源代码开放&#xff0c;开放性更好 封闭操作系统&#xff0c;开放性较差 系统安全性 源代码开放&#xff0c;安全性较差 封闭操作系统&…

电力电子课设|数控产生PWM波|使用51单片机输出占空比可调PWM波(按钮控制、数码管显示)速成教程

我们学校电气专业开始做电力电子的课设了&#xff0c;小组选了一项制作硬件电路的任务&#xff0c;里面有要求采用数控方式实现DC-DC电压变换的输出电压调节&#xff0c;数控在电路中的体现就是用单片机输出可调占空比的PWM作用于IRF520模块&#xff0c;实现电压的变化&#xf…

chatgpt赋能python:Python不等于0:为什么Python成为SEO的热门选择?

Python不等于0&#xff1a;为什么Python成为SEO的热门选择&#xff1f; 如果你正在寻找一门适合SEO的编程语言&#xff0c;Python可能就是你的不二选择。Python在SEO行业越来越流行&#xff0c;因为它具有许多与SEO相关的功能和特点。通过本文&#xff0c;我们将会介绍Python为…

Flutter调优--深入探究MediaQuery引起界面Rebuild的原因及解决办法 | 京东云技术团队

前言 我们可以通过MediaQuery.of(context)方法获取到一些设备和系统的相关信息&#xff0c;比如状态栏的高度、当前是否是黑暗模式等等&#xff0c;使用起来相当方便&#xff0c;但是也要注意可能引起的页面rebuild问题。本文会介绍一个典型的例子&#xff0c;并深入源码来探讨…

chatgpt赋能python:用Python下载MP3的方法

用Python下载MP3的方法 如果你想从互联网上下载MP3&#xff0c;那么你可以使用Python来实现这个任务。在本文中&#xff0c;我们将介绍如何用Python编写程序来下载MP3&#xff0c;同时还将分享一些有用的工具和资源。 Python中使用的库 要下载MP3&#xff0c;你需要使用Pyth…

接口测试简介以及接口测试用例设计思路

接口测试简介 1.什么是接口 接口就是内部模块对模块&#xff0c;外部系统对其他服务提供的一种可调用或者连接的能力的标准&#xff0c;就好比usb接口&#xff0c;他是系统向外接提供的一种用于物理数据传输的一个接口&#xff0c;当然仅仅是一个接口是不能进行传输的&#x…

如何快速入门高性能计算?五个实用学习建议分享

高性能计算 &#xff08;High-Performance Computing&#xff0c;HPC&#xff09;是指通过计算机技术实现高速运算&#xff0c;对大规模科学计算、数据分析、复杂制造等领域的研究与应用提供支撑。目前&#xff0c;HPC已经广泛应用于医学、天文、材料科学、地球科学、气象科学、…

【cmake 学习】cmake判断当前所处系统(CMAKE_SYSTEM_NAME)

目录 1、使用内置变量判断 2、使用变量 CMAKE_SYSTEM_NAME 判断 1、使用内置变量判断 cmake 内置了许多用于表示系统的变量&#xff0c;如 UNIX、WIN32、LINUX、IOS等。假设当前系统为Linux系统&#xff0c;那么 LINUX 变量的值为 1。 更多变量可以参考&#xff1a;cmake-v…

最近距离 | EXCEL中批量查找与原点最近距离的目标点

一 需求 企业送餐、物流、通勤、选址等经常会遇到这样的需求&#xff0c;仓储地是固定的&#xff0c;客户下单后由于客户的地址具有随机性&#xff0c;需按照地理位置分布结合仓储位置进行分析&#xff0c;按距离近及远合理分配仓储&#xff0c;以便节省配送成本。 本文就以这…