Java学习——JDBC练习(商城系统)

数据库准备

--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);

分析准备

数据库驱动准备:
  1. 数据库准备完毕,需要能够运行数据库的驱动(jar)了
    本人使用的mysql为8版本,所以官方下载的mysql-connector-java-8.0.23.jar驱动
  2. 在eclipse中创建好的文件夹下新建文件夹命名为lib
  3. 将jar文件粘贴复制到该文夹下
  4. 右键文件,选择build path 下的奶瓶,会动家里出来相关的libraries架包
分析商场功能
  1. 用户,商品,商品类型都要有自己的增删查改的功能
  2. 建立这三个的对象类
  3. 用户有登录,注册
  4. 选择购买的商品,展示选择购买的商品
  5. 原商品减少。计算总价,和用户余额比较
  6. 不够尽兴充值

  • 不同的方法类用包来区分
  • 将大量重复的代码用方法来进行包装
代码书写

建立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("退出系统!");
		}
	}
}

总结

学习过程中的一个项目,还不是很完善,有一些缺漏的部分,功能也不完善,目前的程度会保留一段时间。。可能会后续跟进改进,也可能会搁置,,,,,,
手打的,可能会有错误,欢迎大佬指正,看到后会第一时间进行改进,,,谢谢

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值