功能需求
1、只有注册用户成功登录之后才可查看商品类别,查看商品,选购商品,生成订单、查看订单。
2、只有管理员才有权限进行购物网后台管理(用户管理+类别管理+商品管理+订单管理)
目录
一、设计思路
1、采用MVC设计模式
2、前台
3、后台
4、西蒙购物网业务流程图
二、运行效果
(一)前台操作
(二)后台操作
三、创建数据库
四、项目结构图
五、系统实现
(一)实体类(net.hw.bean)
1、用户实体(User)
2、类别实体(Category)
3、商品实体(Product)
4、订单实体(Order)
(二)数据库工具类(net.hw.dbutil)
(三)数据访问层接口(XXXDao)
1、用户数据访问接口(UserDao)
2、类别数据访问接口(CategoryDao)
3、商品数据访问接口(ProductDao)
4、订单数据访问接口(OrderDao)
(四)数据访问层实现类(XXXDaoImpl)
1、用户数据访问接口实现类(UserDaoImpl)
2、类别数据访问接口实现类(CategoryDaoImpl)
3、商品数据访问接口实现类(ProductDaoImpl)
4、订单数据访问接口实现类(OrderDaoImpl)
(五)数据服务层接口(XXXService)
1、用户服务接口(UserService)
2、类别服务接口(CategoryService)
3、商品服务接口(ProductService)
4、订单服务接口(OrderService)
(六)数据服务实现类(XXXServiceImpl)
1、用户服务实现类(UserServiceImpl)
2、类别服务实现类(CategoryServiceImpl)
3、商品服务实现类(ProductServiceImpl)
4、订单服务实现类(OrderServiceImpl)
(七)控制层(Servlet)
1、登录处理类(LoginServlet)
2、注销处理类(LogoutServlet)
3、注册处理类(RegisterServlet)
4、显示类别处理类(ShowCategoryServlet)
5、显示商品处理类(ShowProductServlet)
6、显示购物车处理类(ShowCartServlet)
7、操作购物车处理类(OperateCartServlet)
8、生成订单处理类(MakeOrderServlet)
9、支付处理类(PayServlet)
10、显示用户处理类(ShowUserServlet)
(八)部署描述文件web.xml
(九)图片资源(/images/XXX.jpg或XXX.png)
(十)CSS文件(/css/main.css)
(十一)JavaScript文件(/scripts/check.js)
(十二)展现层页面(JSP)
1、登录页面(/login.jsp)
2、前台页面(/frontend/XXX.jsp)
3、后台页面(/backend/XXX.jsp)
一、设计思路
1、采用MVC设计模式
分层架构:展现层(JSP)<——>控制层(Servlet)<——>业务层(Service)<——>模型层(Dao)<——>数据库(DB)
2、前台
(1)登录——显示商品类别——显示某类商品信息——查看购物车——生成订单——支付
(2)注册<——>登录
3、后台
(1)用户管理
(2)类别管理
(3)商品管理
(4)订单管理
说明:只完成了用户管理中的查看用户功能。其他功能,有兴趣的不妨拿来操练一下。
4、西蒙购物网业务流程图
暂时跳过第二点
三、创建数据库
创建MySQL数据库simonshop,包含四张表:用户表(t_user)、类别表(t_category)、商品表(t_product)和订单表(t_order)。
1、用户表结构及记录
2、类别表结构及记录
3、商品表结构及记录
4、订单表结构及记录
四、项目结构图
五、系统实现
现在开始编写系统代码
创建一个包
(一)、实体类:net.azc.shop.bean
在创建4个实体类
1.用户实体类(User):
import java.util.Date;
/**
* 功能:用户实体类
* 作者:azc
* 日期:2019年12月2日
*/
public class User {
/**
* 用户标识符
*/
private int id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 电话号码
*/
private String telephone;
/**
* 注册时间
*/
private Date registerTime;
/**
* 权限(0:管理员;1:普通用户)
*/
private int popedom;
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.类别实体(Category):
/**
* 功能:商品类别实体类
* 作者:azc
* 日期:2019年12月2日
*/
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.商品实体(Product):
import java.util.Date;
/**
* 功能:商品实体类
* 作者:azc
* 日期:2019年12月2日
*/
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.订单实体(Order):
import java.util.Date;
/**
* 功能:订单实体类
* 作者:azc
* 日期:2019年12月2日
*/
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 +
'}';
}
}
(二)数据库工具类(net.azc.shop.dbutil)
package net.azc.shop.dbutil;
import javax.swing.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 功能:数据库连接管理类
* 作者:azc
* 日期:2019年12月2日
*/
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 = "1";
/**
* 私有化构造方法,拒绝实例化
*/
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);
}
}
(三)数据访问层接口(net.azc.shop.Dao)
在src里创建net.hw.shop.dao包,在里面创建UserDao、CategoryDao、ProductDao与OrderDao。
1、用户数据访问接口UserDao
2、类别数据访问接口CategoryDao
3、商品数据访问接口ProductDao
4、订单数据访问接口OrderDao
(四)数据访问接口实现类(net.azc.shop.Dao.Impl)
在src下创建net.hw.shop.dao.impl包,在里面创建UserDaoImpl、CategoryDaoImpl、ProductDaoImpl与OrderDaoImpl。
1、用户数据访问接口实现类UserDaoImpl
package net.azc.shop.dao.impl;
/**
* 功能:用户数据访问接口实现类
* 作者:azc
* 日期: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.azc.shop.bean.User;
import net.azc.shop.dao.UserDao;
import net.azc.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",这样文件夹颜色变成绿色。
(1)编写测试登录方法testLogin()
查看单元测试结果:
这是让你自己输入要查找的用户名和密码的方法,但是在这里会有错,所以不用这种方法,用下面的方法:
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。
(3)编写测试方法testInsert()
(4)编写测试方法testDeleteById()
(5)编写测试方法testFindById()
(6)编写测试方法testFindByUsername()
换一个没有的用户来查找:
(7)编写测试方法testFindAll()
2、类别数据访问接口实现类CategoryDaoImpl
package net.azc.shop.dao.impl;
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.azc.shop.bean.Category;
import net.azc.shop.dao.CategoryDao;
import net.azc.shop.dbutil.ConnectionManager;
/**
* 功能:类别数据访问接口实现类
* 作者:azc
* 日期:2019年12月10日
*/
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;
}
}
3、商品数据访问接口实现类ProductDaoImpl
package net.azc.shop.dao.impl;
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.azc.shop.bean.Product;
import net.azc.shop.bean.User;
import net.azc.shop.dao.ProductDao;
import net.azc.shop.dbutil.ConnectionManager;
/**
* 功能:产品数据访问接口实现类
* 作者:azc
* 日期:2019年12月16日
*/
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,比如改成8,再运行测试方法testFindByCategoryId(),结果如下:
打开t_category表,插入一条新数据:
此时,再运行测试方法testFindByCategoryId(),结果如下:
4、订单数据访问接口实现类OrderDaoImpl
package net.azc.shop.dao.impl;
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.azc.shop.bean.Category;
import net.azc.shop.bean.Order;
import net.azc.shop.bean.User;
import net.azc.shop.dao.OrderDao;
import net.azc.shop.dbutil.ConnectionManager;
/**
* 功能:订单数据访问接口实现类
* 作者:azc
* 日期:2019年12月25日
*/
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(),结果如下:
(五)、数据访问服务类(net.azc.shop.Service)
在src里创建net.hw.shop.service包,在里面创建四个服务类:UserService、CategoryService、ProductService与OrderService。
1、用户服务类UserService
package net.azc.shop.service;
import java.util.List;
import net.azc.shop.bean.User;
import net.azc.shop.dao.UserDao;
import net.azc.shop.dao.impl.UserDaoImpl;
/**
* 功能:用户服务类
* 作者:azc
* 日期:2019年12月2日
*/
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.azc.shop.service;
import java.util.List;
import net.azc.shop.bean.Category;
import net.azc.shop.dao.CategoryDao;
import net.azc.shop.dao.impl.CategoryDaoImpl;
import net.azc.shop.service.CategoryService;
/**
* 功能:类别服务类
* 作者:azc
* 日期:2019年12月10日
*/
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.azc.shop.service;
/**
* 功能:商品服务类
* 作者:azc
* 日期:2019年12月16日
*/
import java.util.List;
import net.azc.shop.bean.Product;
import net.azc.shop.dao.ProductDao;
import net.azc.shop.dao.impl.ProductDaoImpl;
import net.azc.shop.service.ProductService;
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.azc.shop.service;
/**
* 功能:订单服务类
* 作者:azc
* 日期:2019年12月19日
*/
import java.util.List;
import net.azc.shop.bean.Order;
import net.azc.shop.dao.OrderDao;
import net.azc.shop.dao.impl.OrderDaoImpl;
import net.azc.shop.service.OrderService;
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();
}
}