源码资源包地址已经修改,可以正常下载了。
模拟实现以下商品管理业务系统,商品管理系统的整体功能有:
注:商品数据存储在一个数据库中(用静态HashMap来模拟),MySQL
要求:
- 整个程序要分成:交互层、 业务逻辑(service)层、 数据访问(dao)层
- 交互层和service层之间要用“面向接口编程”的模式来写
- 业务逻辑层和dao层之间要用“面向接口编程”的模式来写
- MYSQL入门知识:SQL指令基础
- GUI入门知识:Swing速成
- 优秀博主:ChuiyuGin、Alleyf
DAO层主要完成对底层数据库的连接,与数据库进行数据交互,作为后面业务服务层的基础,java实现数据库的连接需要用到JDBC包(jar),使用包中相应的类方法完成数据库连接,下面展示了DAO层的实现代码。
package DAO;
import java.sql.*;
public class DAO implements DAOApi{
protected static Statement statement;
protected static Connection connection;
public void connect()
{
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/goodsmag", "root","123456");
if(connection != null)
{
System.out.println("连接成功"+connection);
}
assert connection != null;
statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (SQLException e) {
System.exit(0);
throw new RuntimeException(e);
}
}
}
本层主要是实现对数据库的数据处理的各种功能,包括对数据库中表的数据的增删改查,以及各种基础功能和附加功能,本层采用接口的方法实现,通过JDBC的各种命令对数据库中数据表的数据进行各种操作,以下介绍各个功能的实现。
各种功能的接口提前定义好,以便于在后面的服务层中实现。
package Service;
import java.sql.SQLException;
public interface ServiceApi extends SearchApi, AlterApi, JudgeApi{
}
interface SearchApi
{
Object[][] alllook() throws SQLException;
Object[][] idlook(int id) throws SQLException;
Object[][] namelook(String name) throws SQLException;
Object[][] pricelook(float a, float b) throws SQLException;
}
interface AlterApi{
void iddel(int id) throws SQLException;
void alldel() throws SQLException;
void add(String namevalue,String pricevalue,String numvalue) throws SQLException;
void rename(int id, String newname) throws SQLException;
void reprice(int id, float newprice) throws SQLException;
void renumber(int id, int newnumber) throws SQLException;
}
interface JudgeApi
{
boolean idexist(int id) throws SQLException;
boolean nameexist(String name) throws SQLException;
}
该方法采用**Vector**来临时存储输入的需要添加的商品的各种信息,然后通过JDBC命令将其添加到数据库中,从而实现对商品的添加功能。
public void add(String namevalue,String pricevalue,String numvalue) {
String key = "insert into goods (name, price, num) values ";
int i = 1;
while (i<4)
{
switch(i++)
{
case 1:
{
goods.put("name", namevalue);
break;
}
case 2:
{
goods.put("price", pricevalue);
break;
}
case 3:
{
goods.put("num", numvalue);
break;
}
}
}
i = 1;
v.add(goods);
try{
statement.executeUpdate(key+"( \""+goods.get("name")+"\","+goods.get("price")+","+goods.get("num")+")");
} catch (SQLException e) {
e.printStackTrace();
}
}
本方法通过使用一个Object数组来临时存储从数据库中查询到的所有商品数据,并将其循环添加到数组中保存,待需要时使用。
public Object[][] alllook() throws SQLException {
String retnumsql = "SET @rownum = 0";
String reranksql = "UPDATE goods SET id = @rownum := @rownum +1";
statement.execute(retnumsql);
statement.execute(reranksql);
String sql1 = "select count(*) totalCount from goods";
ResultSet rs = statement.executeQuery(sql1);
rs.next();
int i = 0;
int count = rs.getInt("totalCount");
Object[][] rowdata = new Object[count][4];
String sql2 = "select * from goods";
ResultSet resultSet = statement.executeQuery(sql2);
while(resultSet.next())
{
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
float price = resultSet.getFloat("price");
int num = resultSet.getInt("num");
rowdata[i++] = new Object[]{id, name, price, num};
}
return rowdata;
}
通过查询指定键的键值即ID来从数据库中查询该ID的商品,实现原理与全查询类似。
public Object[][] idlook (int id) throws SQLException {
Object[][] rowdata = new Object[1][4];
if(idexist(id))
{
ResultSet resultSet = statement.executeQuery("select * from goods where id = " + id);
if(resultSet.next()){
int ID = resultSet.getInt("id");
String name = resultSet.getString("name");
float price = resultSet.getFloat("price");
int num = resultSet.getInt("num");
rowdata[0] = new Object[]{ID, name, price, num};
}
}
return rowdata;
}
通过传递输入的商品名字到服务层到数据库中查询指定名字的商品,原理与上文类似。
public Object[][] namelook(String name) throws SQLException {
Object[][] rowdata = new Object[1][4];
if(nameexist(name))
{
String sql = "select * from goods where name = \"" + name + "\"";
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()){
int ID = resultSet.getInt("id");
String Name = resultSet.getString("name");
float price = resultSet.getFloat("price");
int num = resultSet.getInt("num");
rowdata[0] = new Object[]{ID, Name, price, num};
}
}
return rowdata;
}
通过传递商品ID通过JDBC指令直接删除数据库中指定ID的商品。
public void iddel(int id) throws SQLException {
if (idexist(id))
{
statement.executeUpdate("delete from goods where id=" + id);
System.out.println("ID = " + id + " 的商品信息删除成功");
}
else
System.out.println("您的输入ID有误请查证后重新删除");
}
通过传递maxprice和minprice两个浮点数调用JDBC指令到数据库中查询处于该范围内的商品并返回。
public Object[][] pricelook(float a, float b) throws SQLException {
String sql1 = "select count(*) totalCount from goods where price>=" + a + "and price<=" + b + "order by price";
ResultSet rs = statement.executeQuery(sql1);
rs.next();
int i = 0;
int count = rs.getInt("totalCount");
Object[][] rowdata = new Object[count][4];
String sql2 = "select * from goods where price>=" + a + " and price<=" + b +"order by price";
ResultSet resultSet = statement.executeQuery(sql2);
while(resultSet.next())
{
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
float price = resultSet.getFloat("price");
int num = resultSet.getInt("num");
rowdata[i++] = new Object[]{id, name, price, num};
}
return rowdata;
}
通过传递对应的Name、Price和Number利用JDBC指令修改为输入的数据,三种修改方式实现代码如下。
public void rename(int id, String newname) throws SQLException{
if(idexist(id))
{
String sql = "update goods set name=\"" + newname + "\" where id=" + id;
statement.executeUpdate(sql);
System.out.println("商品名修改成功");
}
}
public void reprice(int id, float newprice) throws SQLException{
if(idexist(id))
{
String sql = "update goods set price=" + newprice + " where id=" + id;
statement.executeUpdate(sql);
System.out.println("商品价格修改成功");
}
}
public void renumber(int id, int newnumber) throws SQLException{
if(idexist(id))
{
String sql = "update goods set num=" + newnumber + " where id=" + id;
statement.executeUpdate(sql);
System.out.println("商品数量修改成功");
}
}
该层主要采用Swing类的各种组件和方法实现自己想要的图形用户界面,实现过程简要分为一下几个步骤。
- 创建JFrame组件作为面板组件的载体。
- 创建JPanel组件作为基础组件的载体,并且设置面板的大小,位置以及布局方式。
- 创建JLabel、JTextField、JButton、JPassword等基本组件并且设置其格式,包括颜色、大小、位置等。
- 将创建的基本组件添加到面板中,为组件添加监视器来实现动态响应,然后设置JFrame的内容为面板,设置其居中可见即可。
下面只展示部分代码作为示例:
private static void showmanual(Frame owner){
//设置对话框为非模态
final JDialog dialog = new JDialog(owner, "教程", false);
// 设置对话框的宽高
dialog.setSize(800, 600);
// 设置对话框大小不可改变
dialog.setResizable(false);
// 设置对话框相对显示的位置
dialog.setLocationRelativeTo(GuiInteractApi.jf);
// 创建一个标签显示消息内容
JLabel background = new JLabel(new ImageIcon("resources/img/教程视频.gif"));
// 添加组件到面板
JPanel panel = new JPanel();
panel.add(background);
dialog.setContentPane(panel);
dialog.setVisible(true);
}
程序下载链接:项目资源包
登录的用户名为root,密码为123456.
本程序使用的为私人云端数据库,可以直接运行程序,不需要切换为自己本地的数据库,不过也实现了软件内切换登录本地数据库,具体请自行测试.
项目创作不易,精心打磨耗时较久,从底层代码设计编写到GUI的Logo图标均为自己设计,但是仍然还有很多做的不够好的地方,请大家加以指正,有兴趣的小伙伴可以相互交流合作.
该资源包中包含了一个完整的可执行程序可以供大家学习使用,有需要的小伙伴可以联系我获取项目源代码.