目录
项目要求
开发环境搭建
工具类JDBCUtils
创建管家婆数据表
项目分层
MainApp层
MainView层
ZhangWuController层
ZhangWuService层
ZhangWuDao层
ZhangWu bean层
注:一个小技巧,写注释要空一格,要不然不容易导包进去
项目要求
![](https://i-blog.csdnimg.cn/blog_migrate/160c88ab8b4218d85759004a2c8ac0bf.png)
开发环境搭建
mysql-connector-java-5.1.37----MySQL的JDBC驱动包,用于JDBC连接数据库。
commons-dbutils-1.6---封装并简化了JDBC的数据库操作语言
commons-dbcp-1.4------提供数据库连接池组件。
commons-pool-1.5.6-----DBCP连接池依赖该包。
工具类JDBCUtils
使用在Java数据库练习01中自己创建的JDBCUtils,一般来说对于第三方的工具类只要会使用即可。
创建管家婆数据表
gjp.sql文件:
1 /*
2 创建管家婆的数据库
3 名字 gjp
4 */
5 CREATE DATABASE gjp;
6
7 USE gjp;
8
9 /*
10 创建数据表,表名账务
11 字段,列
12 主键
13 分类名称 可变字符
14 金额 double
15 账户 可变字符 (支付,收入方法)
16 创建日期 date
17 账务描述 可变字符
18 */
19
20 CREATE TABLE gjp_zhangwu(
21 -- 主键
22 zwid INT PRIMARY KEY AUTO_INCREMENT,
23 -- 分类名称
24 flname VARCHAR(200),
25 -- 金额
26 money DOUBLE,
27 -- 账户
28 zhanghu VARCHAR(100),
29 -- 创建日期
30 createtime DATE,
31 -- 账务描述
32 description VARCHAR(1000)
33 );
34 SELECT * FROM gjp_zhangwu
35
36 -- 写入测试的数据
37 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (1,'吃饭支出',247,'交通银行','2016-03-02','家庭聚餐');
38 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (2,'工资收入',12345,'现金','2016-03-15','开工资了');
39 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (3,'服装支出',1998,'现金','2016-04-02','买衣服');
40 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (4,'吃饭支出',325,'现金','2016-06-18','朋友聚餐');
41 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (5,'股票收入',8000,'工商银行','2016-10-28','股票大涨');
42 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (6,'股票收入',5000,'工商银行','2016-10-28','股票又大涨');
43 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (7,'工资收入',5000,'交通银行','2016-10-28','又开工资了');
44 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (8,'礼金支出',5000,'现金','2016-10-28','朋友结婚');
45 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (9,'其他支出',1560,'现金','2016-10-29','丢钱了');
46 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (10,'交通支出',2300,'交通银行','2016-10-29','油价还在涨啊');
47 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (11,'吃饭支出',1000,'工商银行','2016-10-29','又吃饭');
48 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (12,'工资收入',1000,'现金','2016-10-30','开资');
49 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (13,'交通支出',2000,'现金','2016-10-30','机票好贵');
50 INSERT INTO gjp_zhangwu(zwid,flname,money,zhangHu,createtime,description) VALUES (14,'工资收入',5000,'现金','2016-10-30','又开资');
![](https://i-blog.csdnimg.cn/blog_migrate/de096bc45cc75232adef44170cedcb50.png)
项目分层
不允许跨层调用
![](https://i-blog.csdnimg.cn/blog_migrate/222cb87992574be3459f36849f2f63a9.png)
MainApp层
1 package gjp.app;
2
3 import gjp.view.MainView;
4
5 /*
6 * 主程序类用来启动结束程序
7 */
8 public class MainApp {
9 public static void main(String[] args) {
10 new MainView().run();//启动run方法
11 }
12 }
MainView层
1 package gjp.view;
2
3 import java.util.List;
4 import java.util.Scanner;
5
6 import gjp.controller.ZhangWuController;
7 import gjp.domain.ZhangWu;
8
9 /*
10 * 视图层,用户操作的界面将数据传递给controller层实现
11 *功能实现:完成功能界面菜单显示
12 * 接收键盘输入的功能选项
13 * 根据选项值,调用对应的功能方法
14 */
15 public class MainView {
16 private ZhangWuController controller =new ZhangWuController();
17 Scanner sc=new Scanner(System.in);
18 public void run(){
19 //Scanner sc=new Scanner(System.in);
20 boolean flag = true;
21 while(true){
22 System.out.println("---------------管家婆家庭记账软件---------------");
23 System.out.println("1.添加账务 2.编辑账务 3.删除账务 4.查询账务 5.退出系统");
24 System.out.println("请输入要操作的功能序号[1-5]:");
25 int choose=sc.nextInt();
26 switch(choose){
27 case 1:
28 addZhangWu();
29 break;
30 case 2:
31 editZhangWu();
32 break;
33 case 3:
34 deleteZhangWu();
35 break;
36 case 4:
37 selectZhangWu();
38 break;
39 case 5:
40 System.out.println("再见!");
41 flag = false;
42 break;
43 default:
44 System.out.println("输入错误!");
45 }
46 }
47 }
48
49 //添加账务方法
50 public void addZhangWu(){
51 //Scanner sc=new Scanner(System.in);
52 System.out.println("选择的是添加账务功能,请输入以下内容:");
53 System.out.println("输入分类名称:");
54 String flname=sc.next();//不要使用sc.nextLine()因为输入数据时会有空格就被下一个接收到了
55 System.out.println("输入金额:");
56 double money=sc.nextDouble();
57 System.out.println("输入账户:");
58 String zhanghu =sc.next();
59 System.out.println("请输入日期格式为:YYYY-MM-DD");
60 String createtime=sc.next();
61 System.out.println("输入具体描述:");
62 String description=sc.next();
63 //将用户输入的数据封装成一个对象,id是没有输入的,也不能修改可以写成0,其实在构造函数时也可以把id这一项删去
64 ZhangWu zw=new ZhangWu(0, flname, money, zhanghu, createtime, description);
65 //调用comtroller层的添加方法
66 controller.addZhangWu(zw);
67 System.out.println("添加成功!");
68 }
69
70
71 /*
72 * 查询方法实现--1 所有查询 2 条件查询
73 */
74 public void selectZhangWu() {
75 System.out.println("1.查询所有 2.按条件查询");
76 Scanner in = new Scanner(System.in);
77 int choose = in.nextInt();
78 switch (choose) {
79 case 1:
80 selectAll();
81 break;
82 case 2:
83 select();
84 break;
85 default:
86 System.out.println("输入错误!");
87 }
88 }
89 //全部查询
90 public void selectAll() {
91 //调用控制层的方法查询所有的账务数据
92 List<ZhangWu> list =controller.selectAll();
93 print(list);
94 }
95 /*
96 * 实现条件查询,用户输入开始日期和结束日期
97 * 将两个参数传递到controller层,并获取结果集打印出来
98 */
99 public void select(){
100 Scanner sc=new Scanner(System.in);
101 System.out.println("选择的为条件查询,请输入日期格式为:YYYY-MM-DD");
102 System.out.println("请输入开始日期:");
103 String startDate=sc.nextLine();
104 System.out.println("请输入结束日期:");
105 String endDate=sc.nextLine();
106 List<ZhangWu> list =controller.select(startDate,endDate);
107 //不写在ptrint里面是因为避免浪费
108 if(list.size()!=0)
109 print(list);
110 else
111 System.out.println("没有查询到数据");
112 }
113
114 //使用快捷键alt+shift+m抽取方法
115 private void print(List<ZhangWu> list) {
116 //输出表头
117 System.out.println("ID\t\t类别\t\t账户\t\t金额\t\t时间\t\t说明");
118 for(ZhangWu zw:list){
119 System.out.println(zw.getZwid()+"\t\t"+zw.getFlname()+"\t\t"+zw.getZhanghu() + "\t\t"
120 + zw.getMoney() + "\t\t" + zw.getCreatetime() + "\t" + zw.getDescription());
121 }
122 }
123
124 private void editZhangWu(){
125
126 //先把所有的信息显示出来
127 selectAll();
128 System.out.println("选择是编辑功能,请输入数据");
129 System.out.println("输入ID");
130 int zwid=sc.nextInt();
131 System.out.println("输入分类名称:");
132 String flname=sc.next();
133 System.out.println("输入金额:");
134 double money=sc.nextDouble();
135 System.out.println("输入账户:");
136 String zhanghu =sc.next();
137 System.out.println("请输入日期格式为:YYYY-MM-DD");
138 String createtime=sc.next();
139 System.out.println("输入具体描述:");
140 String description=sc.next();
141 //将用户输入的数据封装成一个对象,输入的有id必须要封装
142 ZhangWu zw=new ZhangWu(zwid, flname, money, zhanghu, createtime, description);
143 //调用comtroller层的添加方法
144 controller.editZhangWu(zw);
145 System.out.println("添加成功!");
146 }
147
148 //删除账务
149 public void deleteZhangWu(){
150 selectAll();
151 System.out.println("选择的删除功能,请输入需要删除的ID:");
152 int zwid=sc.nextInt();
153 //调用comtroller层的删除方法
154 controller.deletehangWu(zwid);
155 System.out.println("删除成功!");
156 }
157 }
ZhangWuController层
1 package gjp.controller;
2
3 import java.util.List;
4
5 import gjp.domain.ZhangWu;
6 import gjp.service.ZhangWuService;
7
8 /*
9 * 控制器层,接收视图层数据传递给service层
10 */
11 public class ZhangWuController {
12 private static ZhangWuService service=new ZhangWuService();
13 /*
14 * 定义查询所有账务数据的方法由视图层调用
15 * 去调用service层的方法
16 */
17 public List<ZhangWu> selectAll(){
18 return service.selectAll();
19 }
20 //定义条件查询
21 public List<ZhangWu> select(String startDate,String endDate){
22 return service.select(startDate,endDate);
23 }
24
25 //添加账务,由视图层调用,传递过来的不是5个参数而是一个zhangwu对象
26 public void addZhangWu(ZhangWu zw) {
27 service.addZhangWu(zw);
28 }
29
30 //修改账务
31 public void editZhangWu(ZhangWu zw){
32 service.editZhangWu(zw);
33 }
34 //删除账务
35 public void deletehangWu(int zwid) {
36 // TODO Auto-generated method stub
37 service.deletehangWu(zwid);
38 }
39 }
ZhangWuService层
1 package gjp.service;
2
3 import java.util.List;
4
5 import gjp.dao.ZhangWuDao;
6 import gjp.domain.ZhangWu;
7
8 /*
9 * 业务层类,接收上一层controller的数据,经过计算传递给dao层
10 */
11 public class ZhangWuService {
12 private static ZhangWuDao dao=new ZhangWuDao();
13 /*
14 * 定义方法查询所有数据,此方法由控制层调用
15 * 去调用dao层的方法
16 * 返回存储ZhangWu对象的List集合
17 */
18 public List<ZhangWu> selectAll(){
19 return dao.selectAll();
20 }
21 //定义条件查询
22 public List<ZhangWu> select(String startDate,String endDate){
23 return dao.select(startDate,endDate);
24 }
25
26 //添加账务
27 public static void addZhangWu(ZhangWu zw) {
28 dao.addZhangWu(zw);
29 }
30 //编辑账务
31 public void editZhangWu(ZhangWu zw) {
32 // TODO Auto-generated method stub
33 dao.editZhangWu(zw);
34 }
35 //删除账务
36 public void deletehangWu(int zwid) {
37 // TODO Auto-generated method stub
38 dao.deletehangWu(zwid);
39 }
40 }
ZhangWuDao层
1 package gjp.dao;
2
3 import java.sql.SQLException;
4 import java.util.List;
5
6 import org.apache.commons.dbutils.QueryRunner;
7 import org.apache.commons.dbutils.handlers.BeanListHandler;
8
9 import gjp.domain.ZhangWu;
10 import gjp.tools.JDBCUtils;
11
12 /*
13 * 用来实现对数据表数据的增删该查操作
14 * 使用工具类完成QueryRunnerd对象的创建,指定数据源
15 */
16
17 public class ZhangWuDao {
18 private QueryRunner qr= new QueryRunner(JDBCUtils.getDataSource());
19 /*
20 * 定义方法查询数据库,获取所有账务的数据
21 * 由业务层调用
22 * 查询到的是一个结果集将所有的账务数据存储到Bean对象的及集合中。
23 */
24 public List<ZhangWu> selectAll(){
25 try{
26 //查询账务数据的SQL语句
27 String sql="select * from gjp_zhangwu";
28 //调用qr对象的query方法,使用结果集BeanListHandler
29 List<ZhangWu> list =qr.query(sql,new BeanListHandler<>(ZhangWu.class));
30 return list;
31 }catch(SQLException ex){
32 System.out.println(ex);
33 throw new RuntimeException("查询所有账务失败!");
34 }
35 }
36 //条件查询
37 public List<ZhangWu> select(String startDate,String endDate){
38 try{
39 //查询账务数据的SQL语句
40 String sql = "SELECT * FROM gjp_zhangwu WHERE createtime BETWEEN ? AND ?";
41 //定义数组对象存储问号占位符
42 Object[] params ={startDate,endDate};
43 //调用qr对象的query方法,使用结果集BeanListHandler
44 List<ZhangWu> list =qr.query(sql,new BeanListHandler<>(ZhangWu.class),params);
45 return list;
46 }catch(SQLException ex){
47 System.out.println(ex);
48 throw new RuntimeException("条件查询账务失败!");
49 }
50 }
51
52 //添加账务方法
53 public void addZhangWu(ZhangWu zw) {
54 try{
55 //获取sql语句
56 String sql = "INSERT INTO gjp_zhangwu (flname,money,zhanghu,createtime,description) VALUES(?,?,?,?,?)";
57 //保存占位符参数
58 Object[] params = {zw.getFlname(),zw.getMoney(),zw.getZhanghu(),zw.getCreatetime(),zw.getDescription()};
59 //更新数据
60 qr.update(sql, params);
61 }catch(SQLException ex) {
62 System.out.println(ex);
63 throw new RuntimeException("添加账务失败!");
64 }
65 }
66 //编辑账务
67 public void editZhangWu(ZhangWu zw) {
68 // TODO Auto-generated method stub
69 try {
70 // 修改sql语句
71 String sql = "UPDATE gjp_zhangwu SET flname=?,money=?,zhanghu=?,createtime=?,description=? WHERE zwid=?";
72 // 存储占位符
73 Object[] params = { zw.getFlname(), zw.getMoney(), zw.getZhanghu(), zw.getCreatetime(), zw.getDescription(),zw.getZwid() };
74 qr.update(sql, params);
75 } catch (SQLException ex) {
76 System.out.println(ex);
77 throw new RuntimeException("编辑账务失败");
78 }
79 }
80
81 public void deletehangWu(int zwid) {
82 // TODO Auto-generated method stub
83 try {
84 //删除语句
85 String sql = "DELETE FROM gjp_zhangwu WHERE zwid=?";
86 qr.update(sql, zwid);
87 } catch (SQLException ex) {
88 System.out.println(ex);
89 throw new RuntimeException("数据删除失败!");
90 }
91 }
92 }
ZhangWu bean层
1 package gjp.domain;
2
3 /*
4 * 用来封装信息的JavaBean,复用代码
5 */
6 public class ZhangWu {
7 private int zwid;
8 private String flname;
9 private double money;
10 private String zhanghu;
11 private String createtime;//把日期用字符串类型存储方便转换
12 private String description;
13
14 //无参构造
15 public ZhangWu(){}
16 public ZhangWu(int zwid, String flname, double money, String zhanghu, String createtime, String description) {
17 this.zwid = zwid;
18 this.flname = flname;
19 this.money = money;
20 this.zhanghu = zhanghu;
21 this.createtime = createtime;
22 this.description = description;
23 }
24
25 //生成get set方法
26 public int getZwid() {
27 return zwid;
28 }
29 public void setZwid(int zwid) {
30 this.zwid = zwid;
31 }
32 public String getFlname() {
33 return flname;
34 }
35 public void setFlname(String flname) {
36 this.flname = flname;
37 }
38 public double getMoney() {
39 return money;
40 }
41 public void setMoney(double money) {
42 this.money = money;
43 }
44 public String getZhanghu() {
45 return zhanghu;
46 }
47 public void setZhanghu(String zhanghu) {
48 this.zhanghu = zhanghu;
49 }
50 public String getCreatetime() {
51 return createtime;
52 }
53 public void setCreatetime(String createtime) {
54 this.createtime = createtime;
55 }
56 public String getDescription() {
57 return description;
58 }
59 public void setDescription(String description) {
60 this.description = description;
61 }
62
63 }
0