目录
一、项目要求:
项目要求:
- 能根据项目需求设计合理的实体类
- 规范的编码
- 合理选择集合类型
- 关闭程序后,录入的数据下次打开程序还存在
- 商品编码全局唯一,不能出现重复的两个
- 采用Scanner (Scanner s = new Scanner(System.in))提示用户输入,用输出语句实现打印输出
二、项目需求
(1)项目需求一:
项目需求1:【用户管理模块】要求实现配置文件获取用户信息,用户输入用户名和密码与 配置数据一致才可以登录系统操作其它模块。
- 使用db.properties 配置文件配置当前可操作用户名和密码
- 用户登录系统,并检验登录是否成功,成功后可操作下面需求
(2)项目需求二:
项目需求2:【商品维护模块】商品维护模块主要包括,定义变量表示不同的操作0-添加1-删除-2修改3-列表 4-入库 5-出库 9-退出系统:
- 商品添加(输入商品编码、名称、价格、数量),添加的时候要判断商品是否存在,存在就单纯增加数量
- 商品删除
- 输入商品编码,删除对应的商品
- 修改商品价格
- 提示用户输入编号,录入新价格
- 商品列表展示
- 显示商品列表信息
- 商品入库
- 输入商品编号,然后提示用户输入入库数量,进行入库
- 如果商品编码不存在,提示商品不存在
- 商品出库
- 输入商品编号,提示用户输入出库数量,进行出库
- 如果商品编码不存在,提示商品不存在
(3)项目需求三:
项目需求3:【统计报表】
- 使用一个额外的线程,每分钟统计一下当前库存产品,打印如下
- 当前物品总数:10,物品总金额23,物品平均价格2.3
三、思路分析
指定的操作人员才可以操作,必然要利用db.properties来存储信息
关闭程序后,录入的数据下次打开程序还存在 ,也就是我们要想办法将数据写入磁盘,这时就自然想到IO操作中的序列化和反序列化了
统计线程统计数据时,操作员必然不可操作商品,则想到了要用进程的知识,借鉴生产者消费者问题来理解
四、代码分析与展示:
(1)User类代码
定义User类,实例时通过反射获取,User的构造器,User的方法,然后构造对象0,通过invoke()方法,给o的账号密码,赋值为db.properties存储的账号和密码
package cn.kuangtu.goodsMaintain;
public class User {
private String driverClassName;
private String url;
private String username;
private String Password;
public User() {
}
public User(String driverClassName, String url, String username, String password) {
this.driverClassName = driverClassName;
this.url = url;
this.username = username;
Password = password;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return Password;
}
public void setPassword(String password) {
Password = password;
}
}
(2)商品公共资源区管理代码
需求中要求有操作人员操作商品,统计线程统计商品信息,分析知操作人员和统计线程不可同时对商品进行操作,故有一公共资源且两线程不可同时使用。
在操作人员操作商品时,需要判段资源是非正在被使用,若在使用则进入等待状态,且使用完资源,要唤醒统计线程;
统计线程工作前也一样。
package cn.kuangtu.goodsMaintain;
import java.io.*;
import java.util.*;
/**
* 商品管理区,(公共资源)
*/
public class GoodsMaintain {
private boolean isEmpty=true;
List<Store> list=new ArrayList<>();
File file=new File("D:\\大\\Java学习\\IO学习\\test\\store.txt");
/**
*用户登录成功后管理商店
*/
synchronized public void manage(){
try {
if(!isEmpty) {
this.wait();
}
Scanner scanner = new Scanner(System.in);
System.out.println("操作0-添加1-删除-2修改3-列表 4-入库 5-出库 9-退出系统"+"\n"+"请选择你的操作数");
int i = scanner.nextInt();
list=readObject(file);
switch (i){
case 0:
Add(list,file);
break;
case 1:
Remove(list,file);
break;
case 2:
UpGoods(list,file);
break;
case 3:
Input(list);
break;
case 4:
PutStore(list,file);
break;
case 5:
OutStore(list,file);
break;
case 9:
End();
break;
default:
System.out.println("输入错误请重新输入!");
}
isEmpty=false;
//唤醒统计线程
this.notify();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 没有用户操作商店时,统计线程进行统计数量
*/
synchronized public void count(){
try {
while(isEmpty){
this.wait();
}
Thread.sleep(1000);
int sum=0;
double money=0;
for (Store store : list) {
sum+=store.num;
money+=store.num*store.getPrice();
}
System.out.println("当前物品总数:"+" "
+sum+" "+"物品总金额:"+money
+" "+"物品平均价格:"+money/sum);
this.notify();
isEmpty=false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 添加商品操作
* @param list
* @param file
*/
public static void Add(List<Store> list,File file){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入添加的商品编码、名称、价格、数量");
int id = scanner.nextInt();
String name = scanner.next();
int price = scanner.nextInt();
int num = scanner.nextInt();
int count=0;
for (Store store : list) {
count++;
if(store.getId()==id&&store.getName().equals(name)&&store.getPrice()==price){
store.setNum(store.getNum()+num);
break;
}
if(count==list.size()&&store.getId()!=id){
System.out.println("不好意思亲,您要添加的商品不存在!");
}
}
try {
writeObject(file,list);
} catch (IOException e) {
e.printStackTrace();
}
Input(list);
}
/**
* 删除商品
* @param list
* @param file
*/
public static void Remove(List<Store> list,File file){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入删除的商品的编号");
int count=0;
int id = scanner.nextInt();
for (Store store : list) {
count++;
if(store.getId()==id){
list.remove(store);
break;
}
if(count==list.size()&&store.getId()!=id){
System.out.println("您要删除的商品不存在!");
}
}
try {
writeObject(file,list);
} catch (IOException e) {
e.printStackTrace();
}
Input(list);
}
/**
* 更新商品价格
* @param list
* @param file
*/
public static void UpGoods(List<Store> list,File file){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要修改的商品的编号和价钱");
int id = scanner.nextInt();
int price =scanner.nextInt();
int count=0;
for (Store store : list) {
if(store.getId()==id){
store.setPrice(price);
}
if(count==list.size()&&store.getId()!=id){
System.out.println("您要修改的商品不存在!");
}
}
try {
writeObject(file,list);
} catch (IOException e) {
e.printStackTrace();
}
Input(list);
}
/**
* 输出商品清单
* @param list
*/
public static void Input(List<Store> list){
for (Store store : list) {
System.out.println("商品编号:"+store.getId() + " " + "商品名称:"+store.getName() + " " +"商品数量:"+ store.getNum() + " "+"商品数量:"+ store.getPrice());
}
}
/**
* 入库
* @param list
* @param file
*/
public static void PutStore(List<Store> list,File file){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入添加的商品编码:");
int id = scanner.nextInt();
int count=0;
for (Store store : list) {
count++;
if(store.getId()==id){
System.out.println("请输入商品入库的数量:");
int num = scanner.nextInt();
store.setNum(store.getNum()+num);
}
if(count==list.size()&&store.getId()!=id){
System.out.println("商品编号不存在!");
}
}
try {
writeObject(file,list);
} catch (IOException e) {
e.printStackTrace();
}
Input(list);
}
/**
* 出库
* @param list
* @param file
*/
public static void OutStore(List<Store> list,File file){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要出库的商品的编号和数量");
int id = scanner.nextInt();
int num =scanner.nextInt();
int count=0;
for (Store store : list) {
count++;
if(store.getId()==id){
if(num<= store.getNum()){
store.setNum(store.getNum()-num);
}else{
System.out.println("没有这么多商品!");
}
}
if(count==list.size()&&store.getId()!=id){
System.out.println("您要出库的商品不存在!");
}
}
try {
writeObject(file,list);
} catch (IOException e) {
e.printStackTrace();
}
Input(list);
}
/**
* 退出系统
*/
public static void End(){
System.out.println("退出系统");
return ;
}
//序列化(写入磁盘)
public static void writeObject(File file, List<Store> list) throws IOException {
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(list);
outputStream.close();
}
//反序列化(读出)
public static List<Store> readObject(File file) throws IOException, ClassNotFoundException {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file));
Object o = inputStream.readObject();
List<Store> list=( List<Store>) o;
inputStream.close();
return list;
}
}
(3)操作员线程代码
该线程,调用公共资源类 的manage方法
package cn.kuangtu.goodsMaintain;
import java.util.ArrayList;
import java.util.List;
/**
* 操作线程
*/
public class UserDemo implements Runnable{
private GoodsMaintain goodsMaintain=null;
List<Store> list=new ArrayList<>();
public UserDemo(GoodsMaintain goodsMaintain,List<Store> list){
this.goodsMaintain=goodsMaintain;
this.list=list;
}
@Override
public void run() {
goodsMaintain.manage();
}
}
(4)商品统计线程代码
该线程调用公共资源类的count方法
package cn.kuangtu.goodsMaintain;
import java.util.ArrayList;
import java.util.List;
/**
* 统计线程
*/
public class Count implements Runnable{
private GoodsMaintain goodsMaintain=null;
List<Store> list=new ArrayList<>();
public Count(GoodsMaintain goodsMaintain,List<Store> list) {
this.goodsMaintain = goodsMaintain;
this.list=list;
}
@Override
public void run() {
goodsMaintain.count();
}
}
(4)商品类代码
package cn.kuangtu.goodsMaintain;
import java.io.Serializable;
/**
* 商品类
*/
public class Store implements Serializable {
public int id;
public String name;
public int price;
public int num;
public Store(int id, String name, int price, int num) {
this.id = id;
this.name = name;
this.price = price;
this.num = num;
}
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 int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
(5)测试类代码
因要求中要求只有指定的人员才可以对商品进行管理,故要先判断当前登录的人员是否为满足要求的人员,定义两个线程,并启动;
package cn.kuangtu.goodsMaintain;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, IOException {
Class<?> aClass = Class.forName("cn.kuangtu.goodsMaintain.User");
Scanner scanner = new Scanner(System.in);
Constructor<?> constructor = aClass.getConstructor();
//创建对象
Object o = constructor.newInstance();
Method setDriverClassName = aClass.getDeclaredMethod("setDriverClassName", String.class);
Method getDriverClassName = aClass.getDeclaredMethod("getDriverClassName");
Method setUrl = aClass.getDeclaredMethod("setUrl", String.class);
Method getUrl = aClass.getDeclaredMethod("getUrl");
Method setUsername = aClass.getDeclaredMethod("setUsername", String.class);
Method getUsername = aClass.getDeclaredMethod("getUsername");
Method setPassword = aClass.getDeclaredMethod("setPassword", String.class);
Method getPassword = aClass.getDeclaredMethod("getPassword");
Properties properties = new Properties();
properties.load(GoodsMaintain.class.getResourceAsStream("db.properties"));
setUsername.invoke(o,properties.getProperty("username"));
setPassword.invoke(o,properties.getProperty("password"));
System.out.println("请输入您的账号和密码:");
String username = scanner.next();
String password = scanner.next();
if(!username.equals(getUsername.invoke(o))||!(password.equals(getPassword.invoke(o)))){
System.out.println("账号密码有误!");
return;
}
List<Store> list = new ArrayList<>();
GoodsMaintain goodsMaintain = new GoodsMaintain();
UserDemo userDemo = new UserDemo(goodsMaintain,list);
Thread thread = new Thread(userDemo);
thread.start();
Count count = new Count(goodsMaintain,list);
Thread thread1 = new Thread(count);
thread1.start();
}
}
(6)商品初始化
通过序列化,将最初存在的商品进行写入磁盘存储,对商品进行初始化;为后续操作人员管理商品,奠定基础数据。
package cn.kuangtu.goodsMaintain;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 初始化
*/
public class Initialize {
public static void main(String[] args) {
File file = new File("D:\\大\\Java学习\\IO学习\\test\\store.txt");
ArrayList<Store> list = new ArrayList<>();
list.add(new Store(1,"雪碧",3,20));
list.add(new Store(2,"可乐",3,10));
list.add(new Store(3,"脉动",5,60));
list.add(new Store(4,"鲜橙多",4,400));
list.add(new Store(5,"安慕希",6,100));
list.add(new Store(6,"咖啡",8,90));
list.add(new Store(7,"果粒橙",5,70));
list.add(new Store(8,"纯牛奶",4,50));
list.add(new Store(9,"健力宝",3,30));
list.add(new Store(10,"红牛",6,80));
try {
Initialize.writeObject(file,list);
} catch (IOException e) {
e.printStackTrace();
}
}
//序列化,将初始的商品存入
public static void writeObject(File file, List<Store> list) throws IOException {
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(list);
outputStream.close();
}
}
五、运行展示
六、总结
- 序列化与反序列化
- 反射
- 线程,同步