《Java从入门到放弃》JavaSE入门篇:练习——单身狗租赁系统

今天,我们要玩个大的!!!

我们把之前使用数组做的这个单身狗系统改版成数据库版本,并且使用面向对象里面的一些简单思想。如果有不知道这个系统的看官,请跳转到目录页,然后再选择单身狗系统(数组版)先围观五分钟吧。里面的功能很简单。。。。。。。。。

五分钟之后···

好了,五分钟到了,我们继续吧·



要完成的功能还是如上图所示,只不过实现的代码有翻天覆地的变化而已。。。



第一步:分析

一般做一个项目,根据侧重点不同,会把整个项目分成三大部分:界面、功能业务实现、数据库操作。具体三层架构的内容,等后面JSP的时候再来细讲哈。

所以首先要有三个不同的包来保存这三大部分的内容。

com.test:包含main方法的程序入口类放在这个包下。

com.dog.ui:界面相关的类文件放在这个包下。

com.dog.service:功能中的业务逻辑的处理放在这个包下。

com.dog.dao:和数据库打交道的类放在这个包下。

包分好了,我们再来分析要创建哪些类,根据引用顺序,ui要调用service,service要调用dao,而类与类之间的方法如何进行数据传递呢?一般使用实体类。所以我们还要再创建一个entity包存放所有的实体类。项目结构如下图:

昨天文章讲到了JDBC的常用操作分为两类,增、删、改是一样的操作,查询是一样的操作,所以我们可以再写一个通用操作类(DBManager),类中包含两个方法,分别用来操作数据和查询数据。最终的项目结构图如下:

分析过程就到这儿吧,下面进入编码环节。



二、编码

按照调用的先后顺序,我们先编写entity包中的实体类。

2.1 Dog类

public class Dog {
	private int did;		//编号
	private String nickname;	//昵称
	private int gender;		//性别
	private String outDate;		//租出日期
	private int state;		//状态
	public int getDid() {
		return did;
	}
	public void setDid(int did) {
		this.did = did;
	}
	public String getNickname() {
		return nickname;
	}
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}
	public int getGender() {
		return gender;
	}
	public void setGender(int gender) {
		if(gender==1 || gender==0){
			this.gender = gender;
		}
		else{
			this.gender = 1;
		}
	}
	public String getOutDate() {
		return outDate;
	}
	public void setOutDate(String outDate) {
		this.outDate = outDate;
	}
	public int getState() {
		return state;
	}
	public void setState(int state) {
		if(state==1 || state==0){
			this.state = state;
		}
		else{
			this.state = 0;
		}
	}
}

再编写dao包下面的类。

2.2 DBManager类是一个通用操作类,代码如下:

public class DBManage {
	static Connection con = null;
	static PreparedStatement ps = null;
	static ResultSet rs = null;
	//连接MySQL
	static String driver = "com.mysql.jdbc.Driver";
	static String url = "jdbc:mysql://127.0.0.1:3306/singledogdb";

	//创建连接对象
	private static Connection getConnect(){
		try {
			Class.forName(driver);
			con = DriverManager.getConnection(url,"root","root");	//连接mysql
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return con;
	}
	//执行查询后返回ResultSet对象(不带参数)
	public static ResultSet getResultSet(String sql){
		con = getConnect();
		try {
			ps = con.prepareStatement(sql);
			rs = ps.executeQuery();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;
	}
	//执行查询后返回ResultSet对象(带参数)
	public static ResultSet getResultSet(String sql,Object[] params){
		con = getConnect();
		try {
			ps = con.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) 
				ps.setObject(i+1, params[i]);
			rs = ps.executeQuery();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;
	}
	//执行增、删、改操作,返回受影响的行数
	public static int modifyEntiy(String sql, Object[] params){
		int num = 0;
		con = getConnect();
		try {
			ps = con.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i+1, params[i]);
			}
			num = ps.executeUpdate();
			closeAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return num;
	}
	//关闭连接
	public static void closeAll(){
		if (ps != null){
			try {
				ps.close();
				ps = null;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(con != null){
			try {
				con.close();
				con = null;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

后面主要使用getResultSet()方法和modifyEntiy()方法。

2.3 DogDao类代码如下:

public class DogDAO {
	//查询所有单身狗
	public List<Dog> findAll(){
		List<Dog> list = new ArrayList<Dog>();
		String strSql = "select did,nickname,gender,DATE_FORMAT( outDate,‘%Y-%m-%d‘) outDate,state from dogtbl";
		try {
			ResultSet rs = DBManage.getResultSet(strSql);
			while (rs.next()) {
				Dog dog = new Dog();
				dog.setDid(rs.getInt("did"));
				dog.setNickname(rs.getString("nickname"));
				dog.setGender(rs.getInt("gender"));
				dog.setOutDate(rs.getString("outDate"));
				dog.setState(rs.getInt("state"));
				list.add(dog);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return list;
	}
	//新增
	public int insert(Dog dog){
		int result = 0;
		String strSql = "INSERT INTO dogTbl (did, nickname, gender ) VALUES (?, ?, ?)";
		Object[] params = new Object[3];
		params[0] = dog.getDid();
		params[1] = dog.getNickname();
		params[2] = dog.getGender();
		result = DBManage.modifyEntiy(strSql, params );
		return result;
	}
	//删除(result的值:-1.查无此狗 0.删除失败 1.删除成功)
	public int delete(int dogid){
		int result = 0;
		String strSql = "select state from dogTbl where did=?";
		Object[] params = new Object[1];
		params[0] = dogid;
		//1.查询是否有该记录
		ResultSet rs = DBManage.getResultSet(strSql, params);
		try {
			if(rs.next()){
				int state = rs.getInt("state");
				//2. 如果是未借出状态则可以删除
				if(state==0){
					strSql = "delete from dogTbl where did=? and state=0";
					result = DBManage.modifyEntiy(strSql, params );
				}
			}
			else{
				result = -1;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	//更新借出状态
	public int update(Dog dog){
		int result = 0;
		String strSql;
		//判断要更新的状态,同时更新借出日期
		if(dog.getState()==1){
			strSql = "update dogTbl set state=1,outdate=now() where did=?";
		}
		else{
			strSql = "update dogTbl set state=0,outdate=null where did=?";
		}
		Object[] params = new Object[1];
		params[0] = dog.getDid();
		result = DBManage.modifyEntiy(strSql, params );

		return result;
	}
}

主要包括四个操作,添加、删除、更新借出状态和日期、查询所有。等所有功能实现后,小伙伴们可以自己尝试写一写搜索功能

接下来编写service中的类。

2.4 DogService类

public class DogService {
	private DogDAO dogDAO = new DogDAO();	//数据访问对象
	//查询所有
	public List<Dog> findAll(){
		return dogDAO.findAll();
	}

	//添加
	public int add(Dog dog){
		return dogDAO.insert(dog);
	}

	//删除
	public String delete(int dogid){
		String msg = "删除成功!";
		int result = dogDAO.delete(dogid);
		if(result==-1){
			msg = "查无此狗";
		}
		else if(result==0){
			msg = "该单身狗已租出还未归还,不能删除!";
		}
		return msg;
	}

	//借出
	public int loan(Dog dog){
		int result = 0;
		result = dogDAO.update(dog);
		return result;
	}
	//归还:是不是发现和借出的代码一样,这就对了,方法名不同,方便上层的人调用
	public int repay(Dog dog){
		int result = 0;
		result = dogDAO.update(dog);
		return result;
	}
}

再接下来写UI包中的类

2.5 Face类

public class Face {
	// 因为在很多方法中都需要使用输入对象,所以定义到最外面,那么在每个方法中都可以使用了
	private Scanner input = new Scanner(System.in);
	//创建业务逻辑对象
	private DogService dogService = new DogService();

	// 显示主菜单
	public void mainMenu() {
		System.out.println("======================");
		System.out.println("  欢迎使用单身狗租赁系统");
		System.out.println("  1.查看");
		System.out.println("  2.新增");
		System.out.println("  3.删除");
		System.out.println("  4.借出");
		System.out.println("  5.归还");
		System.out.println("  6.退出");
		System.out.println("======================");
		// 注意,如果用户输入了1~6之外的数字,需要让他重新输入
		int num = 6;
		do {
			System.out.print("请选择:");
			num = input.nextInt();
			switch (num) {
			case 1:
				show();
				break;
			case 2:
				add();
				break;
			case 3:
				delete();
				break;
			case 4:
				loan();
				break;
			case 5:
				repay();
				break;
			case 6:
				System.out.println("客官,下次再来玩哟~!");
				break;
			default:
				System.out.println("输入的啥玩意啊,我只认识1,2,3,4,5,6!!!");
				break;
			}
		} while (num > 6 || num < 1);

	}
	//查看
		public void show() {
			System.out.println("======================");
			System.out.println("====>查看");
			System.out.println();
			showDog();
			goMainMenu();
		}

		//新增
		public void add(){
			System.out.println("======================");
			System.out.println("====>添加");
			System.out.println();
			Dog dog = new Dog();
			System.out.print("请输入昵称:");
			dog.setNickname(input.next());
			System.out.print("请选择性别(0.女|1.男):");
			dog.setGender(input.nextInt());
			//调用添加方法
			dogService.add(dog);
			System.out.println("添加完毕!");
			goMainMenu();
		}

		//删除
		public void delete(){
			System.out.println("======================");
			System.out.println("====>删除");
			System.out.println();
			System.out.print("请输入编号:");
			int dogid = input.nextInt();
			//调用删除方法
			System.out.println(dogService.delete(dogid));
			goMainMenu();
		}
		//借出
		public void loan(){
			System.out.println("======================");
			System.out.println("====>借出");
			System.out.println();
			showDog();		//显示所有单身狗(按道理应该在DAO包中的类编写一个find(state)方法来根据状态查询对应的记录,但我懒癌发作了,没办法···)

			System.out.print("请输入编号");
			int no = input.nextInt();
			//按道理,在这儿应该先根据ID查询出对应的记录,再判断这条记录中的借出状态之后再决定是否能借出,但···,懒癌继续发作中···
			Dog dog = new Dog();
			dog.setDid(no);
			dog.setState(1);
			if(dogService.loan(dog)>0){
				System.out.println("借出成功!");
			}
			else{
				System.out.println("借出失败!");
			}

			goMainMenu();
		}

		//归还
		public void repay(){
			System.out.println("======================");
			System.out.println("====>归还");
			System.out.println();
			showDog();		//显示所有单身狗(懒癌还在发作···)

			System.out.print("请输入编号");
			int no = input.nextInt();
			//懒癌持续发作中···
			Dog dog = new Dog();
			dog.setDid(no);
			dog.setState(0);
			if(dogService.repay(dog)>0){
				System.out.println("归还成功!");
			}
			else{
				System.out.println("归还失败!");
			}
			goMainMenu();
		}
		//返回主菜单
		public void goMainMenu(){
			System.out.print("按任意键后回车返回主菜单:");
			String in = input.next();
			mainMenu();
		}

		/**
		 * 显示所有单身狗
		 */
		private void showDog() {
			//查看时注意不要把数组中的空元素进行输出了
			System.out.println("编号\t昵称\t性别\t状态\t借出日期");
			System.out.println("===========================================");
			List<Dog> list = dogService.findAll();
			for (int i = 0; i < list.size(); i++) {
				Dog dog = list.get(i);
				System.out.println(dog.getDid()+"\t"+dog.getNickname()+"\t"+
						(dog.getGender()==0?"女":"男") + "\t"+
						(dog.getState()==0?"未借出":"已借出\t"+
						dog.getOutDate()));
			}
			System.out.println("===========================================");
		}
}

注意代码中有些方法的注释,大家如果要做完整版的,可以自行优化!!!

最后,main方法:

public static void main(String[] args) {
	// TODO Auto-generated method stub
	Face face = new Face();
	face.mainMenu();
}

到这儿,所有的代码就编写完成了,测试过程如下:

















今天有很多地方因为懒病发作,所以···,大家懂的,一个完整的流程,很多步骤都需要进行判断,看官中的小萌新们,你们就不要懒了,把该补完整的代码补上吧,之后就可以去比你更新的萌新面前得瑟了,哈哈哈!

“软件思维”博客地址:51CTO博客园,感兴趣的小伙伴可以去看相关的其它博文。

时间: 2024-11-08 19:19:53

《Java从入门到放弃》JavaSE入门篇:练习——单身狗租赁系统的相关文章

《Java从入门到放弃》JavaSE篇:综合练习——单身狗租赁系统(数组版)

因为现在只学习了基本语法,所以在综合练习之前,先补充关于方法概念. 方法的作用:把一系列的代码放在一起,然后再取个别名.之后通过这个别名的调用,就相当于执行了这一系列的代码. 方法的语法:([]中的内容表示是可选的) public 返回值类型 方法名(参数类型 参数名[,参数类型 参数2 ...]){     //代码块     //[return 数据]; } 方法的例子:     public static void main(String[] args) {         loop();

JavaScript从入门到放弃之补充篇

上回说到,基础之篇,看久必新,新久必看. 这回我们来说说除了基础篇之外的一些花里胡哨的东西. 数组 以字面量方式创建数组 //字面量方式创建 var colors = ['red','white','black'] console.log(colors) 输出结果如下: 使用构造函数创建 // 使用构造函数创建数组 var heroes = new Array(); heroes[0] = 'Marvelous'; heroes[1] = 'Riven'; heroes[2] = 'Lee Si

《Java从入门到放弃》入门篇:springMVC数据校验

昨天我们扯完了数据传递,今天我们来聊聊数据校验的问题.来,跟着我一起读:计一噢叫,一按艳. 在springMVC中校验数据也非常简单,spring3.0拥有自己独立的数据校验框架,同时支持JSR303标准的校验框架. Spring的DataBinder在进行数据绑定时,会同时调用校验框架完成数据校验工作. 具体使用步骤如下: 1)导入数据校验的JAR包 2)在springmvc的配置文件中添加校验Bean 3)修改实体类,在属性上加上校验的注解 4)修改昨天的login4方法,加上校验的相关代码

《Java从入门到放弃》入门篇:hibernate中的多表对应关系

hibernate中的对应关系其实就是数据库中表的对应关系, 就跟某些电影中的某些场景是一样一样滴. 比如可以是一男一女,还可以是一男多女, 更可以是多男一女,最后最后最后还可以是多男多女!!! 有些不纯洁的看官肯定已经开始想歪了吧···,我还是上图吧!请看下图 我说滴是这样滴一群人打群架滴场景,嘿嘿嘿··· 好吧,进入正题!!! 数据库中表与表之间的数据映射关系有一对一,一对多,多对一,多对多.例如: 一个身份证只能对应一个护照,一个护照也只能对应一个身份证,这就是一对一的关系 一个男人可以有

《Java从入门到放弃》入门篇:变量

变量是什么玩意呢? 变量,顾名思义就是能变化的量 - - 好吧,举个栗子. 图片上的各种餐具,就是变量,因为同一个盘子可以在不同的时间装不同的菜,在这一桌可以装土豆肉丝,在下一桌可以装清炒黄瓜(当然,这个盘子还是要洗洗干净滴). 那么Java当中的变量有哪些要点呢,其语法是怎么样的呢? 我们来写段代码保存上面的清炒黄瓜吧··· 1 String pan9527 = "清炒黄瓜"; 这就是标准的变量的用法,其语法格式:数据类型 变量名 = 值; 三个要点: 1.数据类型 Java中的数据

《Java从入门到放弃》入门篇:Struts2的常用验证方式(二)

前一回,我们讲完了"直接在功能方法中写验证代码"这种验证方式,接下来,我们继续搞定后续的三种方式. 二.重写validate方法(注意这个方法会验证该类中所有的方法) 使用重写验证方法的好处就是,又可以少写一句代码了!!!! 2.1)修改Action类,在其中添加valiate方法,把之前写在add方法中的验证代码剪切过来     //修改后的add方法     public String add() {         System.out.println("调用了添加的方

《Java从入门到放弃》入门篇:Struts2的基本数据传递方式

把这个和JSP的数据传递方式对比一下,你就会发现·······真的可以少写两句代码!!! struts2中常用的两种数据传递方式如下: 属性匹配方式 ModelDriven接口匹配方式(常用于自定义类型) 个人比较喜欢使用第一种,为什么呢?因为············懒~~~~~. 接下来,有请代码君登场!!! 一.属性匹配方式     属性匹配又分为两种情况,一种是Java基本数据类型,一种是自定义类型,请Look下面的Code.     1.1)自定义一个Singer类,包含3个属性(sin

《Java从入门到放弃》入门篇:Struts2的常用验证方式

感觉过了一个周末,人都懒得不要不要的,今天就来点简单的内容吧 - -,各位看官如果欲求不满的话,可以自行解决或再去宠幸其他"勃主"··· struts2的验证方式主要有四种方式: 一.直接在功能方法中写验证代码(不要扔鸡蛋,这种办法确实算一种) 二.重写validate方法(注意这个方法会验证该类中所有的方法) 三.使用ValidateXxx方法(Xxx对应要验证的方法的方法名) 四.用struts2的验证框架(也就是使用配置文件的方式来实现,这种方法个人觉得应该属于放弃篇的内容,为什

《Java从入门到放弃》入门篇:运算符

运算符分为运算和符. 运算:是一种行为,通过已知量的可能的组合,获得新的量. 符:上古时期,符是沟通人和神的秘密图案,所以符是不可以随便乱画的,故有所谓"画符不知窍,反惹鬼神笑:画符若知窍,惊得鬼神叫"的说法.画符的方法成百上千,有的要掐诀存想神灵随笔而来,有的要步罡踏斗,念动咒语-- 咳,知道运算符的来历了吧,所以程序写得好不好,就看运算符用得妙不妙! ======================我是分割线君=================== 当然,上面都是我瞎扯的,Java中的