Java基础学习笔记二十八 管家婆综合项目
Posted 冰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础学习笔记二十八 管家婆综合项目相关的知识,希望对你有一定的参考价值。
本项目为JAVA基础综合项目,主要包括:
熟练View层、Service层、Dao层之间的方法相互调用操作、熟练dbutils操作数据库表完成增删改查。
项目功能分析
- 查询账务
- 多条件组合查询账务
- 添加账务
- 编辑账务
- 删除账务
项目环境搭建
技术选型和jar包介绍
每个项目都要使用一些已经成熟的技术,它们通常是由一些专业组织或团队所提供的开源免费技术。在今后的学习过程中,我们会逐渐对这些专业组织有所了解。本项目中使用的技术如下:
apache的commons组件:
- commons-dbutils-1.6.jar:封装并简化了JDBC;
- commons-dbcp-1.4.jar:apache commons提供的数据库连接池组件,命名为DBCP;
- commons.pool-1.5.6.jar:DBCP连接池依赖该jar包;
mysql-connector-java-5.1.7-bin.jar:MySQL的JDBC驱动包,用JDBC连接MySQL数据库必须使用该JAR包。
工具类介绍
每个项目都会用到一些工具类,本项目也不例外。我们不会教大家如何实现这些类,而是让大家知道在项目我们如何使用这些工具类,下面是本项目中所使用的工具类以及介绍:
JDBCUtils:用来创建数据库连接池对象;不懂请移步这里
JDBCUtils.java
public class JDBCUtils { public static final String DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver"; public static final String URL = "jdbc:mysql://localhost:3306/gjp"; public static final String USERNAME = "root"; public static final String PASSWORD = "123456"; private static BasicDataSource dataSource = new BasicDataSource(); static { dataSource.setDriverClassName(DRIVER_CLASS_NAME); dataSource.setUrl(URL); dataSource.setUsername(USERNAME); dataSource.setPassword(PASSWORD); } public static DataSource getDataSource() { return dataSource; } }
数据表创建
对一个项目而言,表设计是非常重要的,因为应用程序中所有的操作都是基于数据库表而进行的,所以我们第一步就是创建数据库表。管家婆项目的数据库设计很简单,下面是创建库及表的SQL语句:
/* 创建管家婆的数据库 名字 gjp */ CREATE DATABASE gjp; USE gjp; /* 创建数据表,表名账务 字段,列 主键 分类名称 可变字符 金额 double 账户 可变字符 (支付,收入方法) 创建日期 date 账务描述 可变字符 */ CREATE TABLE gjp_zhangwu( -- 主键 zwid INT PRIMARY KEY AUTO_INCREMENT, -- 分类名称 flname VARCHAR(200), -- 金额 money DOUBLE, -- 账户 zhanghu VARCHAR(100), -- 创建日期 createtime DATE, -- 账务描述 description VARCHAR(1000) ); SELECT * FROM gjp_zhangwu -- 写入测试的数据 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (1,\'吃饭支出\',247,\'交通银行\',\'2016-03-02\',\'家庭聚餐\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (2,\'工资收入\',12345,\'现金\',\'2016-03-15\',\'开工资了\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (3,\'服装支出\',1998,\'现金\',\'2016-04-02\',\'买衣服\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (4,\'吃饭支出\',325,\'现金\',\'2016-06-18\',\'朋友聚餐\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (5,\'股票收入\',8000,\'工商银行\',\'2016-10-28\',\'股票大涨\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (6,\'股票收入\',5000,\'工商银行\',\'2016-10-28\',\'股票又大涨\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (7,\'工资收入\',5000,\'交通银行\',\'2016-10-28\',\'又开工资了\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (8,\'礼金支出\',5000,\'现金\',\'2016-10-28\',\'朋友结婚\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (9,\'其他支出\',1560,\'现金\',\'2016-10-29\',\'丢钱了\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (10,\'交通支出\',2300,\'交通银行\',\'2016-10-29\',\'油价还在涨啊\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (11,\'吃饭支出\',1000,\'工商银行\',\'2016-10-29\',\'又吃饭\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (12,\'工资收入\',1000,\'现金\',\'2016-10-30\',\'开资\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (13,\'交通支出\',2000,\'现金\',\'2016-10-30\',\'机票好贵\'); INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (14,\'工资收入\',5000,\'现金\',\'2016-10-30\',\'又开资\');
项目分层(分包)的作用
程序为什么要分包分层?
以顾客去饭店吃饭案例分析一下:
小饭店: 一个服务员搞定(接待顾客\\点菜\\炒菜)
大饭店:
- 迎宾员(是否有预定\\ 询问吃中餐还是西餐或者烧烤等\\ 几位用餐 \\ 领路到指定的包间\\ 找点菜员为顾客点菜 )
- 点菜员(记录顾客点餐内容\\ 记录是否有忌口等问题\\ 找厨师为顾客炒菜)
- 厨师(按照顾客菜肴清单,进行炒菜)
通过案例发现,当程序规模小的时候,可以一个人全部完成;但程序规模大的时候,一个人难以完成,这时,要采用多人合作的方式来完成程序开发。多人合作方式将会碰到工作任务分配问题,这时我们会想,每个人负责完成项目的一块内容就可以了。那么,这一块块内容的划分,就需要我们采用分层(分包)的方式完成了。
通过下图(用户注册功能)来讲解下,项目中常见的分层(分包)。
view层作用: 视图层,即项目中的界面
controller层作用: 控制层, 获取界面上的数据,为界面设置数据; 将要实现的功能交给业务层处理
service层作用: 业务层, 功能的实现, 与controller控制层和数据访问层DAO交互, 将对数据库的操作交给DAO数据访问层来处理
dao层作用: 数据访问层, 用来操作数据库表的数据
db数据库: 这里指MySQL
domain 实体包: 存放JavaBean
tools工具包:存放项目中使用到的工具类
test 测试包: 存放项目功能测试的代码
工程创建及包管理
- 使用 IntelliJ IDEA创建Java工程,命名为gjp
- 创建工程包
cn.itcast.gjp.app: 存放main方法类;
cn.itcast.gjp.domain: 存放JavaBean;
cn.itcast.gjp.view: 存放界面,及表现层类;
cn.itcast.gjp.service: 存放业务层类;
cn.itcast.gjp.dao: 存放数据访问层类;
cn.itcast.gjp.tools:存放工具类
- 创建lib文件夹,用来存储使用的jar包
把jar包拷贝到lib目录下,并
选择Dependencies——>点击+按钮——>选择JARS or dirretories...
选择jar包——>OK
Apply——>OK
功能模块
相关类创建
完成本项目中类的创建,无需在类中添加代码。
复制已编写好的工具类JDBCUtils.java 到 tools包中;
package cn.itcast.gjp.tools; /* * 使用DBCP实现数据库的连接池 * 连接池配置,自定义类, * 最基本四项完整 * 对于数据库连接池其他配置,自定义 */ import org.apache.commons.dbcp.BasicDataSource; import javax.sql.DataSource; public class JDBCUtils { //创建出BasicDataSource类对象 private static BasicDataSource datasource = new BasicDataSource(); //静态代码块,对象BasicDataSource对象中的配置,自定义 static { //数据库连接信息,必须的 datasource.setDriverClassName("com.mysql.jdbc.Driver"); datasource.setUrl("jdbc:mysql://localhost:3306/gjp"); datasource.setUsername("root"); datasource.setPassword("123456"); //对象连接池中的连接数量配置,可选的 datasource.setInitialSize(10);//初始化的连接数 datasource.setMaxActive(8);//最大连接数量 datasource.setMaxIdle(5);//最大空闲数 datasource.setMinIdle(1);//最小空闲 } //定义静态方法,返回BasicDataSource类的对象 public static DataSource getDataSource() { return datasource; } }
在app包中,创建类MainApp.java,编写main主方法,用来完成本项目的启动
package cn.itcast.gjp.app; /** * 程序入口 */ public class MainApp { public static void main(String[] args) { } }
在domain包中,创建类ZhangWu.java,它是用来封装账务信息的JavaBean。
JavaBean是指的是Java中的类,该类中的成员变量与数据库表中的字段相对应(变量名对应数据库表字段名、变量数据类型对应数据库表字段类型),并提供空参数构造方法、set、get方法。
我们现在来完成账务类的代码编写,如下:
package cn.itcast.gjp.domain; public class ZhangWu { private int zwid; private String flname; private double money; private String zhanghu; private String createtime; private String description; public ZhangWu(int zwid, String flname, double money, String zhanghu, String createtime, String description) { this.zwid = zwid; this.flname = flname; this.money = money; this.zhanghu = zhanghu; this.createtime = createtime; this.description = description; } public ZhangWu() { } @Override public String toString() { return "Zhangwu [zwid=" + zwid + ", flname=" + flname + ", money=" + money + ", zhanghu=" + zhanghu + ", createtime=" + createtime + ", description=" + description + "]"; } public int getZwid() { return zwid; } public void setZwid(int zwid) { this.zwid = zwid; } public String getFlname() { return flname; } public void setFlname(String flname) { this.flname = flname; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public String getZhanghu() { return zhanghu; } public void setZhanghu(String zhanghu) { this.zhanghu = zhanghu; } public String getCreatetime() { return createtime; } public void setCreatetime(String createtime) { this.createtime = createtime; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
在dao包中,创建类ZhangWuDao.java,给ZhangWuDao类添加一个成员变量QueryRunner对象,因为我们使用dbutils来操作数据库。
package cn.itcast.gjp.dao; import cn.itcast.gjp.tools.JDBCUtils; import org.apache.commons.dbutils.QueryRunner; /** * 实现对数据表 gjp_zhangwu 数据增删改查操作 * dbuils工具类完成,类成员创建QueryRunner对象,指定数据源 **/ public class ZhangWuDao { private QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); }
在service包中,创建类ZhangWuService.java,给ZhangWuService类添加一个类型为ZhangWuDao的成员变量,因为service依赖dao。
package cn.itcast.gjp.service; import cn.itcast.gjp.dao.ZhangWuDao; /** * 业务层类 * 接收上一层,控制层controller的数据 * 经过计算,传递给dao层,操作数据库 * 调用dao层中的类,类成员位置,创建Dao类的对象 */ public class ZhangWuService { private ZhangWuDao dao = new ZhangWuDao(); }
在view包中,创建类MainView.java,给MainView类添加一个类型为ZhangWuService的成员变量,因为本项目中view依赖service。
package cn.itcast.gjp.view; import cn.itcast.gjp.service.ZhangWuService; /* * 视图层,用户看到和操作的界面 */ public class MainView { private ZhangWuService service = new ZhangWuService(); }
功能界面菜单
界面菜单的完成,是项目编写的第一步。我们通过输出语句,完成界面菜单的输出,之后再根据输入的功能序号,进行对应功能的调用执行。
功能实现步骤
编写MainView类run方法
- 完成功能界面菜单显示
- 接收键盘输入的功能选项
- 根据选项值,调用对应的功能方法
编写MainApp类的main主方法
调用MainView类中run方法,实现将程序执行起来,显示功能界面菜单。
功能实现代码
1、在view包MainView类中编写run方法
/* * 实现界面效果 * 接收用户的输入 * 根据数据,调用不同的功能方法 */ public void run(){ //创建Scanner类对象,反复键盘输入 Scanner sc = new Scanner(System.in); while(true){ System.out.println("---------------管家婆家庭记账软件---------------"); System.out.println("1.添加账务 2.编辑账务 3.删除账务 4.查询账务 5.退出系统"); System.out.println("请输入要操作的功能序号[1-5]:"); //接收用户的菜单选择 int choose = sc.nextInt(); //对选择的菜单判断,调用不同的功能 switch(choose){ case 1: // 选择添加账务,调用添加账务的方法 addZhangWu(); break; case 2: // 选择的编辑账务,调用编辑账务方法 editZhangWu(); break; case 3: // 选择的删除账务,调用删除账务方法 deleteZhangWu(); break; case 4: // 选择的是查询账务,调用查询方法 selectZhangWu(); break; case 5: System.exit(0); break; } } }
2、app包MainApp类的main主方法中,调用MainView类中run方法
new MainView().run();
查询所有账务
功能实现步骤
1 编写MainView类中selectZhangWu方法
- 通过输出语句,显示出要查询账务的方式
- 接收键盘的输入项,调用对应的方法(1.查询所有 2.按条件查询)
/* * 定义方法 selectZhangWu() * 显示查询的方式 1 所有查询 2 条件查询 * 接收用户的选择 */ public void selectZhangWu(){ System.out.println("1. 查询所有 2. 条件查询"); Scanner sc = new Scanner(System.in); int selectChooser = sc.nextInt(); //判断根据用户的选择,调用不同的功能 switch(selectChooser){ case 1: //选择的查询所有,调用查询所有的方法 selectAll(); break; case 2: //选的条件查询,调用带有查询条件的方法 select(); break; } }
2 编写MainView类中selectAll查询所有账务方法
- 调用ZhangWuService类selectAll方法,返回包含所有账务数据的List<ZhangWu>集合
- 调用MainView类中print方法,实现控制台显示所有账务数据
- 编写MainView类中print方法,使用输出语句,打印出账务表的表头名称,遍历账务集合,将每个账务信息输出打印
/* * 定义方法,实现查询所有的账务数据 */ public void selectAll(){ //调用控制层中的方法,查询所有的账务数据 List<ZhangWu> list = service.selectAll(); if(list.size()!=0) print(list); else System.out.println("没有查询到数据"); } //输出账务数据方法,接收List集合,遍历集合,输出表格 private void print(List<ZhangWu> list) { //输出表头 System.out.println("ID\\t\\t类别\\t\\t账户\\t\\t金额\\t\\t时间\\t\\t说明"); //遍历集合,结果输出控制台 for(ZhangWu zw : list){ System.out.println(zw.getZwid()+"\\t\\t"+zw.getFlname()+"\\t\\t"+zw.getZhanghu()+"\\t\\t"+ zw.getMoney()+"\\t\\t"+zw.getCreatetime()+"\\t"+zw.getDescription()); } }
3、编写ZhangWuService类中selectAll方法
- 调用ZhangWuDao类中selectAll方法,返回包含所有账务数据的List<ZhangWu>集合
/* * 定义方法,实现查询所有的账务数据 * 此方法,由控制层调用, 去调用dao层的方法 * 返回存储ZhangWu对象的List集合 */ public List<ZhangWu> selectAll(){ return dao.selectAll(); }
4、编写ZhangWuDao类中selectAll()方法
- 通过QueryRunner对象,调用query方法查询数据库表gjp_zhangwu,返回包含所有账务数据的List<ZhangWu>集合
/* * 定义方法,查询数据库,获取所有的账务数据 * 方法,由业务层调用 * 结果集,将所有的账务数据,存储到Bean对象中,存储到集合中 */ public List<ZhangWu> selectAll(){ try{ //查询账务数据的SQL语句 String sql = "SELECT * FROM gjp_zhangwu"; //调用qr对象的方法,query方法,结果集BeanListHandler List<ZhangWu> list = qr.query(sql, new BeanListHandler<>(ZhangWu.class)); return list; }catch(SQLException ex){ System.out.println(ex); throw new RuntimeException("查询所有账务失败"); } }
多条件查询账务
1 、编写MainView类中select方法
- 通过键盘输入查询日期的范围
- 调用ZhangWuSerice类中select方法,返回查询日期范围内的账务信息集合List<ZhangWu>
- 调用MainView类中的print方法,将账务信息集合中的内容显示在控制台中
/* * 定义方法,实现条件查询账务数据 * 提供用户的输入日期,开始日期结束日期 * 就2个日期,传递到controller层 * 调用controller的方法,传递2个日期参数 * 获取到controller查询的结果集,打印出来 */ public void select(){ System.out.println("选择条件查询,输入日期格式XXXX-XX-XX"); Scanner sc = new Scanner(System.in); System.out.print("请输入开始日期:"); String startDate = sc.nextLine(); System.out.print("请输入结果日期:"); String endDate = sc.nextLine(); //调用controller层的方法,传递日期,获取查询结果集 List<ZhangWu> list = service.select(startDate, endDate); if(list.size()!=0) print(list); else System.out.println("没有查询到数据"); }
2、 编写ZhangWuService类中select方法
- 调用ZhangWuDao 类中select方法,返回查询日期范围内的账务信息集合List<ZhangWu>
/* * 定义方法,实现条件查询账务 * 方法由控制层调用,传递2个日期字符串 * 调用dao层的方法,传递2个日期字符串 * 获取到查询结果集 */ public List<ZhangWu> select(String startDate,String endDate){ return dao.select(startDate, endDate); }
3 编写ZhangWuDao类中select方法
- 通过QueryRunner对象,调用query方法查询数据库表gjp_zhangwu,返回包含查询日期范围内的账务数据List<ZhangWu>集合
/* * 定义方法,查询数据库,带有条件去查询账务表 * 由业务层调用,查询结果集存储到Bean对象,存储到List集合 * 调用者传递2个日期字符串 */ public List<ZhangWu> select(String startDate,String endDate){ try{ //拼写条件查询的SQL语句 String sql = "SELECT * FROM gjp_zhangwu WHERE createtime BETWEEN ? AND ?"; //定义对象数组,存储?占位符 Object[] params = {startDate,endDate}; //调用qr对象的方法query查询数据表,获取结果集 return qr.query(sql, new BeanListHandler<>(ZhangWu.class),params); }catch(SQLException ex){ System.out.println(ex); 以上是关于Java基础学习笔记二十八 管家婆综合项目的主要内容,如果未能解决你的问题,请参考以下文章