数据库准备
--Source Server : MySQL
--Source Host : localhost:3306
--Source Schema : myshop
drop table goods; --建立goods表
create table goods(
gid int(10) not null auto_increment,
gname varchar(20) default null, --default null 设定不为空
tid int(10) default null,
price double(10,4) default null,
outdate datetime default null comment '出产日期', --comment 是写的标记,解释
sup varchar(10) default null comment '供应商',
num int(10) default null comment '库存数量',
primary key(gid) using btree, --设置主键
INDEX `goods_tid_fk`(`tid`) USING BTREE,
CONSTRAINT `goods_tid_fk` FOREIGN KEY (`tid`) REFERENCES `goodstype` (`tid`) ON DELETE RESTRICT ON UPDATE RESTRICT
);
drop table goodstype;
create table goodstype(
tid int(10) not null auto_increment,
tname varchar(20) default null,
remark varchar(50) default null
primary key (tid) using BTREE
);
DROP TABLE IF EXISTS user;
CREATE TABLE user (
uid int(8) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
name varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
password varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
money int(9) DEFAULT NULL,
PRIMARY KEY (uid) USING BTREE
);
--开始添加数据
INSERT INTO goods VALUES(101, '华硕天选者', 2, 8999.00, '2020-08-14 09:11:11', '陕西华硕公司', 20);
INSERT INTO goods VALUES(102, '联想拯救者', 2, 7999.00, '2020-02-06 09:22:22', '北京联想集团', 30);
INSERT INTO goods VALUES(103, '海尔洗衣者', 1, 1899.00, '2020-12-17 09:33:33', '青岛海尔集团', 50);
INSERT INTO goods VALUES(104, '海尔空调者', 1, 2399.00, '2020-12-03 09:44:44', '珠江海尔集团', 30);
INSERT INTO goods VALUES(105, '黑道冰箱者', 1, 1888.00, '2021-01-05 09:55:55', '琉球海尔集团', 20);
INSERT INTO goods VALUES(106, '格力电器者', 1, 2888.00, '2021-01-07 09:66:66', '广东格力集团', 50);
INSERT INTO goodstype VALUES (1, '家电', '家用大型家电');
INSERT INTO goodstype VALUES (2, '办公', '华为联想啥商品都有');
INSERT INTO goodstype VALUES (3, '食品', '各种美食');
INSERT INTO goodstype VALUES (4, '厨房', '厨房中使用的小型家电');
INSERT INTO user VALUES (1001, 'userVip3', '123', 1000);
INSERT INTO user VALUES (1002, 'QQVIP8', '123', 10000);
INSERT INTO user VALUES (1003, 'XinYue20', '123', 200000);
分析准备
数据库驱动准备:
- 数据库准备完毕,需要能够运行数据库的驱动(jar)了
本人使用的mysql为8版本,所以官方下载的mysql-connector-java-8.0.23.jar驱动 - 在eclipse中创建好的文件夹下新建文件夹命名为lib
- 将jar文件粘贴复制到该文夹下
- 右键文件,选择build path 下的奶瓶,会动家里出来相关的libraries架包
分析商场功能
- 用户,商品,商品类型都要有自己的增删查改的功能
- 建立这三个的对象类
- 用户有登录,注册
- 选择购买的商品,展示选择购买的商品
- 原商品减少。计算总价,和用户余额比较
- 不够尽兴充值
- 不同的方法类用包来区分
- 将大量重复的代码用方法来进行包装
代码书写
建立bean 包来存放三个类:
User类:
public class User{
private Integer uid;
private String name;
private String password;
private Integer money;
public Integer getUid(){
return uid;
}
public void setUid(Integer uid){
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getMoney() {
return money;
}
public void setMoney(Integer money) {
this.money = money;
}
}
GoodType类
public class GoodsType {
private Integer tid;
private String tname;
private String remark;
public Integer getTid() {
return tid;
}
public void setTid(Integer tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
Goods类:
public class Goods {
private Integer gid;
private String gname;
private GoodsType gt;
private double price;
private Date outdate; //出产日期
private String sup; //商品供应商
private int num; //商品库存
public Integer getGid() {
return gid;
}
public void setGid(Integer gid) {
this.gid = gid;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
public GoodsType getGt() {
return gt;
}
public void setGt(GoodsType gt) {
this.gt = gt;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Date getOutdate() {
return outdate;
}
public void setOutdate(Date outdate) {
this.outdate = outdate;
}
public String getSup() {
return sup;
}
public void setSup(String sup) {
this.sup = sup;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
建立utile工具包
DBUtil类:
public abstract class DBUtil<T> {
//所有的数据库操作,都需要通道和连接java接口
/*
1.加载连接数据库的驱动程序
2.获取连接对象
3.执行sql语句的对象
4.通过对象操作数据库并解析结果
5.关闭连接
Class.forName("com.mysql.cj.jdbc.Driver"); 获取驱动包下的Driver接口,这个接口实现了java.sql包下的Driver接口。通过多态的方法调用这个接口
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/studentdb?useSSL=false&characterEncoding=utf-8", "root", "123");第一个参数时确立链接的语句,根据连接的数据库的不同会有所改变(jdbc:数据库类型://连接的地址(如.120.0.0.138):接口号(数据库一般为3306)/你创建的表名?解析模式,用户名,密码)
Connection 就是Driver下的一个接口,能够起到连接数据库的作用
PreparedStatement pst = conn.prepareStatement(String sql); PreparedStatement是继承Statement的接口,Statement是继承Connection的接口,又因为Statement 直接放入sql语句进行拼接等操作出现SQL注入(较为复杂,有问题请自行查找)
pst.setInt(int xx,String xx); 这里是填写前面的sql中填写的占位符的内容(使用?来标记占位符)。set类型(确定要填入占位符的数据类型)。int xx 是选择第几个占位符。String xx 是要填入占位符中的内容
.....
int i =pst.executeUpdate()或者ResultSet rs =pst.exectueQuery() 前者返回更新的行数,后者返回查询出的对象的集合,ResultSet来接收集
若为查询 可以通过ResultSet 中的 .getxxx(int x) 来获取查询出来的表的具体数据。xxx为查看数据的类型,x 为在查询出来的表的那一列的数据
都需要进行关闭用finally ,关闭时有异常需要抛出,可以建立一个通用的方法
*/
private Connection conn = null;
private PreparebStatement pst= null;
private ResultSet rs = null;
//连接的通用方法(sql前代码都一样,进行抽取出来)
public Connection getConn(){
try{
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/studentdb?useSSL=false&characterEncoding=utf-8", "root", "123");
return conn;
}catch(Exception e){
e.printStackTrace();
}
}
//结束的通用方法
public void getclose(Connection conn,PreparedStatement pst,ResultSet rs){
try {
if(rs!=null)
rs.close();
if(pst!=null)
pst.close();
if(conn!=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//修改更新的通用方法 Object...obj 可变长度的数组 obj中的参数一定要与占位符的位置一一对应
public boolean update(String sql,Object...obj){
try{
pst = getConn().prepareStatement(sql);
for(int i = 0;i<obj.length;i++){
//采用setObject,为占位符赋值,自动适应为所有类型赋值
pst.setObject(i+1,obj[i]);
}
int row = pst.executeUpdate();
if(row>0)
return true;
}catch(Exception e){
e.printStackTrace();
}finally{
getClose(rs,pst,conn);
}
return false;
}
//通用的查询方法
//查询模板,查询的结果为集合,但是集合中的元素无法确定,用<T>泛指
public List<T> query(String sql,Object...obj){
List<T> list = new ArratyList<>();
try{
pst = getConn().prepareStatement(sql);
for(int i =0;i<obj.length;i++){
pst.setObject(i+1,obj[i]);
}
rs = pst.executeQuery();
while(rs.next()){
//获取rs中的对象
T t = getEntity(rs);
list.add(t);
}
}catch(Exceotion e){
e.printStatckTrace();
}finally{
getClose(rs,pst,conn);
}
}
//该方法设置为抽象方法,在子类中必须重写该方法,重写后的方法返回调用对象 的内容
public abstract T getEntity(ResulSet rs) throws Exception;
}
建立Dao类
根据数据库表建立Dao类,包括GoodsDao,,GoodsTypeDao,,UserDao
GoodsDao
public interface GoodsDao{
public List<Goods> findAll();
public boolean updateGoods(Goods goods);
public boolean save(Goods goods);
public Goods findById(int gid);
}
GoodsTypeDao
public interface GoodsTypeDao{
public List<GoodsType> findAll();
public GoodsType findById(int tid);
}
UserDao
public interface UserDao{
//账号密码登录查询
public User login(String name,String password);
//通过ID查询账户
public User findById(int id);
public boolean save(User user);
public boolean update(User user);
public boolean delete(int id);
//通过账号查询,用来判断是否存在相同名称
public boolean findByName(String name);
}
Dao 的实现类
每一个实现类都实现自身的dao方法,并且都继承通用方法DBUtil
GoodsDaoImpl
public class GoodsDaoImpl extends DBUtil<Goods> implements GoodsDao{
GoodsTypeDao gtd = new GoodsTypeDaoImpl();
@Override
public List<Goods> findAll(){
return query("select * from goods");
}
@Override
public List<Goods> findByTid(int tid){
return query("select *from goods where tid=?",tid);
}
@Override
public boolean save(Goods goods){
return update("insert into goods values(null,?,?,?,?,?,?)",goods.getGid(),goods.getGname(),goods.getGt().getTid(),goods.getPrice(),goods.getOutdate(),goods.getSup(),goods.getNum())
}
@Override
public Goods findById(int gid){
//List<Goods> list = query("select * from goods where gid=?",gid);
//if(list.size()>0)
// return list.get(0);
//return null;
return query("select * from goods where gid=?",gid).get(0);
}
@Override
public Goods getEntity(ResultSet rs) throws Exception{
Goods goods = new Goods();
goods.setGid(rs.getInt(1));
goods.setGname(rs.getString(2));
goods.setGt(gtd.findById(rs.getInt(3)));
goods.setPrice(rs.getDouble(4));
goods.setOutdate(rs.getDate(5));
goods.setSup(rs.getString(6));
goods.setNum(rs.getInt(7));
return goods;
}
}
GoodsTypeDaoImpl
public class GoodsTypeDaoImpl extends DBUtil<GoodsType> implement GoodsTypeDao{
@Override
public List<GoodsType> findAll(){
return query("select * from goodstype");
}
@Override
public GoodsType findById(int tid){
return query("select * from goodstype where tid=?",tid).get(0);
}
@Override
public GoodsType getEntity(ResultSet rs) throws Exception{
GoodsType gt = new GoodsType();
gt.setTid(rs.getInt(1));
gt.setTname(rs.getString(2));
gt.setRemark(rs.getString(3));
return gt;
}
}
UserDaoImpl
public class UserDaoImpl extends DBUtil<User> implements UserDao{
@Override
public User login(String name,String password){
List<User> list = query("select * from user where name=? and password=?",name,password);
if(list.size()>0)
return list.get(0);
return null;
}
@Override
public User findById(int id){
List<user> list = query("select * from user where uid=?",id);
if(list.size()>0)
return list.get(0);
return null;
}
@Override
public boolean save(User user){
return update("insert into user values(null,?,?,?)",user.getName(),user.getPassword(),user.getMoney());
}
@Override
public boolean delete(int id){
return update("delete from user where uid=?",id);
}
@Override
public boolean findByName(String name){
Liste<User> list = update("select * from user where name=?",name);
if(list.size()>0)
return false;
return true;
}
@Override
public User getEntity(ResultSet rs) throws SQLException{
User user= new User();
user.setUid(rs.getInt(1));
user.setName(rs.getString(2));
user.setPassword(rs.getString(3));
user.setMoney(rs.getInt(4));
return user;
}
}
功能服务类service
实现功能,测试功能
GoodsTypeMenu
public class GoodTypeMenu{
GoodsTypeDao gtd = new GoodsTypeDaoImpl();
Scanner in = new Scanner(System.in);
UserMenu um = new UserMenu();
public void showGoodsType(){
List<GoodsType> list = gtd.findAll();
for(GoodsType gt = list){
System.out.println("\t"+gt.getTid()+"."+gt.getTname());
}
}
}
GoodsMenu
public class GoodsMenu{
GoodsDao gd = new GoodsDaoImpl();
Scanner in = new Scanner(System.in);
UerMenu um= new UserMenu();
//展示以及查询商品的功能
public boolean showGoods(int tid){
List<Goods> list = gd.fingByTid(tid);
System.out.println("================商品展示==============");
System.out.println("商品编号\t商品名称\t\t商品价格\t商品库存\t出厂日期\t所在地址");
if(list.size()>0){
for(Goods goods:list){
System.out.println(goods.getGid()+"\t"+goods.getGname()+"\t"+goods.getPrice()+"\t"+goods.getNum()+"\t"+goods.getOutdate()+"\t"+goods.getSup());
}
}else{
System.out.println("对不起,该商品类型已卖完...");
return false;
}
return true;
}
public Goods findById(int gid){
return gd.findById(gid);
}
public void jianNum(Goods goods){
gd.updateGoods(goods);
}
}
UserMenu
public class UserMenu{
UserDao ud= new UserDaoImpl();
Scanner in = new Scanner(System.in);
//用户登录的功能:有登录三次的机会
public User login(){
User user = null;
System.out.println("==========用户登录=============");
int i= 3; //3次登录机会
do{
user = new User();
System.out.print("请输入用户名:");
String name = in.next();
System.out.print("请输入密码:");
String password = in.next();
//进行登录
user= ud.login(name,password);
if(user!=null){
System.out.println("欢迎来到大利嘉商城...");
return user;
}else{
i--;
if(i==0){
System.out.println("对不起,您的登录机会已用完,请下次再来.");
break;
}else
System.out.println("对不起,账户或密码错误,请重新登录,您还有"+i+"次机会.");
}
}while(true);
return null;
}
//用户注册的功能:需要验证用户名是否存在,并且两次确认密码正确才可注册
//注册成功后返回注册成功用户信息,以待使用
public User register(){
User user=new User();
do{
System.out.print("请输入用户名");
String name = in.next();
if(ud.findByName(name)){//返回的结果是一个boolean 值,存在返回false
user.setName(name);
break;
}else{
System.out.println("用户名已存在,请重新输入:");
}
}while(true);
do{
System.out.print("请输入密码:");
String pwd = in.next();
if(pwd.length() >= 5){//设置密码长度不低于5位
System.out.println("请输入确认密码:");
String pwd1 = in.next();
if(pwd.equals(pwd1)){
user.setPassword(pwd);
break;
}else{
System.out.println("两次密码不一致,请重新输入");
}
}else{
System.out.println("对不起,密码长度至少6位!");
}
}while(true);
System.out.println("请输入充值金额:");
user.setMoney(in.nextInt());
ud.save(user);
System.out.println("恭喜你,注册成功!");
return user;
}
public void update(User user){
ud.update(user);
}
}
进行主要测试 TestShop
public class TestShop{
Scanner in = new Scanner(System.in);
User user = null;
UserMenu um = new UserMenu();
GoodsMenu gm = new GoodsMenu();
GoodsTypeMenu gtm = new GoodsTypeMenu();
List<Goods> gwc = new ArrayList<>();
Goods goods = null; //保存临时购买的商品
double total = 0; //购物总价
@Test //测试方法
public void mian(){
umenu();
}
//主菜单
public void gtmenu(){
stop:do{
System.out.println("==============商城===============");
gtm.showGoodsType();
System.out.println("===================\n请选择:");
int num = in.nextInt();
boolean flag = false;
do{
flag = false;
boolean gflag = gm.showGoods(num);
if(gflag){
System.out.println("请选择需要购买的商品ID:");
int gcheck = in.nextInt();
goods = gm.findById(gcheck);
//user为空,则没有登录
if(user == null){
System.out.pritln("您还没有登录系统,请登录");
umenu();
return;
}else{
pay:do{
System.out.print("您购买的商品是"+goods.getGname()+",请输入购买的数量:");
int payNum = in.nextInt();
if(payNum>goods.getNum()){
System.out.println("购买商品数量不得大于库存,请重新输入");
}else{
goods.setNum(goods.getNum()-payNum);//选择购买后减去库存中商品数量
gm.jianNum(goods);
for(Goods g:gwc){
if(g.getGid()==goods.getGid()){
g.setNum(g.getNum()+payNum);
break pay;
}
}
goods.setNum(payNum);//购物车对象为购买对象,数量为购买数量
gwc.add(goods);
break;
}
}while(true);
System.out.println("1.继续购买商品,2.结束购买商品,其他任意键自动返回上一层");
int go = in.nextInt();
if(go == 1){
flag = true;
}else if (go == 2){
break stop;
}else{
break;
}
}
}else
break;
}while(true);
}while(true);
System.out.println("您的购买清单:");
System.out.println("================商品展示==============");
System.out.println("商品编号\t商品名称\t\t商品价格\t购买数量\t所在地址");
for(Goods goods : gwc){
System.out.println(goods.getGid()+"\t"+goods.getGname()+"\t"+goods.getPrice()+"\t"+goods.getNum()+"\t"+goods.getSup());
total += goods.getPrice()*goods.getNum();
}
do{
System.out.println("本次购物您共消费:¥"+total+",请问你要现在支付吗?y");
String zf = in.next();
if(zf.equals("y")){
if(user.getMoney()>=total){
user.setMoney(user.getMoney()-(int)total);
um.update(user);
break;
}else{
System.out.println("你的余额宝余额不足,请问你要充值吗?y");
String cz = in.next();
if(cz.equals("y")){
System.out.print("请输入充值金额:");
int money=in.nextInt();
user.setMoney(user.getMoney()+money);
um.update(user);
}else
break;
}
}else
break;
}while(true);
System.out.println("欢迎下次光临.......");
}
public void umenu(){
System.out.println("==================商城===================");
System.out.println("\t1.登录");
System.out.println("\t2.注册");
System.out.println("\t3.退出");
System.out.println("======================\n请选择:");
if (num.equals("1")) {
user = um.login();
if (user == null)
return;
gtmenu();
} else if (num.equals("2")) {
user = um.register();
gtmenu();
} else {
System.out.println("退出系统!");
}
}
}
总结
学习过程中的一个项目,还不是很完善,有一些缺漏的部分,功能也不完善,目前的程度会保留一段时间。。可能会后续跟进改进,也可能会搁置,,,,,,
手打的,可能会有错误,欢迎大佬指正,看到后会第一时间进行改进,,,谢谢