综合案例_账务管理系统
一、项目介绍
1.1 项目目标
本项目为JAVAEE基础和数据库的综合项目,包含了若干个知识点,达到将从基础班到现在所学的知识综合使用,提高了我们对项目的理解与知识点的运用。
熟练View层、Service层、Dao层之间的方法相互调用操作
熟练使用工具类操作数据库表完成增删改查以及登录的功能
通过本项目,让我们了解公司项目开发的流程,充分的掌握项目需求分析、设计与功能的代码实现。提高同学们独立分析需求与功能实现的能力。
项目需求:
用户和账务操作;
单用户操作;
暂时没有表关联关系;
技术框架:
no
模式:
MVC模式
不是设计模式,设计模式指的是面向对象的设计原则,总共有23种设计模式,供程序员来参考如何编写更为规范的面向的对象的代码(JAVA、C#、C++)。
编程的时候,一个参考的模型:
1.2项目演示
1.3 项目功能介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D8cuomzm-1688729463963)(assets/image-20210120185620073.png)]
* 登录功能
* 查询账务
* 多条件组合查询账务
* 添加账务
* 编辑账务
* 删除账务
二、项目环境搭建
2.1 数据准备
/*
创建账务管理的数据库
*/
CREATE DATABASE account CHARACTER SET utf8;
USE account;
/*
用户表
字段:
用户id
用户名 username
密码 password
*/
CREATE TABLE ac_user(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20),
pwd VARCHAR(20),
isManager int -- 1管理员;0:普通用户;
);
insert ac_user(username,pwd,isManager) values('admin','admin',1),('user','user',0)
/*
创建数据表,表名账务
字段,列
主键
分类名称 可变字符
金额 double
支付方式 可变字符 (支付,收入方法)
创建日期 date
账务描述 可变字符
*/
CREATE TABLE ac_account(
id INT PRIMARY KEY AUTO_INCREMENT, -- 主键
sortname VARCHAR(200), -- 分类名称
money DOUBLE, -- 金额
type VARCHAR(100), -- 支付方式
createtime DATE, -- 创建日期
desp VARCHAR(1000) -- 账务描述
);
SELECT * FROM ac_account;
-- 写入测试的数据
INSERT INTO ac_account(id,sortname,money,type,createtime,desp) VALUES (1,'吃饭支出',247,'交通银行','2016-03-02','家庭聚餐');
INSERT INTO ac_account(id,sortname,money,type,createtime,desp) VALUES (2,'工资收入',12345,'现金','2016-03-15','开工资了');
INSERT INTO ac_account(id,sortname,money,type,createtime,desp) VALUES (3,'服装支出',1998,'现金','2016-04-02','买衣服');
INSERT INTO ac_account(id,sortname,money,type,createtime,desp) VALUES (4,'吃饭支出',325,'现金','2016-06-18','朋友聚餐');
INSERT INTO ac_account(id,sortname,money,type,createtime,desp) VALUES (5,'股票收入',8000,'工商银行','2016-10-28','股票大涨');
INSERT INTO ac_account(id,sortname,money,type,createtime,desp) VALUES (6,'股票收入',5000,'工商银行','2016-10-28','股票又大涨');
2.2 技术选型
每个项目都要使用一些已经成熟的技术,它们通常是由一些专业组织或团队所提供的开源免费技术。在今后的学习过程中,我们会逐渐对这些专业组织有所了解。本项目中使用的技术如下:
2.3 JDBC工具类
每个项目都会用到一些工具类,本项目也不例外。JDBC工具类之前也讲过,在这里就不在详细描述!
package cn.yunhe.demo.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
// 数据库连接工具类 ————使用连接池
public class JDBCUtils {
private static DataSource ds;
static {
//加载配置文件信息
InputStream is= JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties pro = new Properties();
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
try {
//获得连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//获得连接
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//释放资源
//释放资源 ===适用于 增删改
public static void close(PreparedStatement pstmt,Connection conn) {
//7.释放资源
try {
if(pstmt!=null) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//释放资源 ===适用于 查询
public static void close(ResultSet rs,PreparedStatement pstmt,Connection conn) {
//7.释放资源
try {
if(rs!=null) {
rs.close();//关闭结果集
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(pstmt!=null) {
pstmt.close();//关闭statement
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();//归还连接
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
2.4 项目分层(分包)
项目分层,分包好处是方便管理,各自负责各自的功能,也方便我们找错改问题!
-
view
层作用: 视图层,即项目中的界面 -
controller
层作用: 控制层, 获取界面上的数据,为界面设置数据; 将要实现的功能交给业务层处理 -
service
层作用: 业务层, 功能的实现, 与controller控制层和数据访问层DAO交互, 将对数据库的操作交给DAO数据访问层来处理 -
dao
层作用: 数据访问层, 用来操作数据库表的数据 -
entity
实体包: 存放JavaBean -
util
工具包:存放项目中使用到的工具类 -
test
测试包: 存放项目功能测试的代码
2.5 工程创建
-
使用eclipse创建account项目
-
创建工程包
cn.yunhe.demo.test: 存放main方法类;
cn.yunhe.demo.entity: 存放JavaBean;
cn.yunhe.demo.service: 存放业务层类;
cn.yunhe.demo.dao: 存放数据访问层类;
cn.yunhe.demo.util:存放工具类
-
创建lib文件夹,用来存储使用的jar包
4.创建resources文件夹作为项目资源目录,存放项目中使用到的配置文件
三、相关类编写
3.1 相关类创建
-
复制JDBCUtils.java
工具类到
util`包下 -
复制jar包,到
lib
目录下 -
在test包下,创建
MainTest.java
编写main方法,用来启动本项目
-
在
entity
包下,创建Account.java和
User.java`用来存储账务信息和用户信息
-
在
dao
包下,创建AccountDao.java和
UserDao.java` -
在service包下,创建AccountService.java
和
UserService.java` -
在
test
包下,创建MainView.java
在MainView类添加两个成员变量:AccountService和UserService成员变量,因为本项目中view依赖service
3.2 编写相关类
3.2.1 MainApp.java
用于启动本项目
/**
* 主方法类
*/
public class MainApp {
public static void main(String[] args) {
}
}
3.2.2 ac_account和User
在entity包下,创建User和Account
-
Account
package com.itfxp.zw.domain; package cn.yunhe.demo.entity; // ac_account public class Account { private int id;// id private String sortname;// 分类名称 private String type;// 账户名称 private double money;// 金额 private String createtime;// 创建时间 private String desp;// 说明 public Account() { } public Account(int id, String sortname, String type, double money, String createtime, String description) { super(); this.id = id; this.sortname = sortname; this.type = type; this.money = money; this.createtime = createtime; this.description = description; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getSortname() { return sortname; } public void setSortname(String sortname) { this.sortname = sortname; } public String getType() { return type; } public void setType(String type) { this.type = type; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } 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; } @Override public String toString() { return "Account [id=" + id + ", sortname=" + sortname + ", type=" + type + ", money=" + money + ", createtime=" + createtime + ", description=" + description + "]"; } }
-
User
package cn.yunhe.demo.entity; // ac_user public class User { private int id; private String username; private String passweord; public User() { } public User(int id, String username, String passweord) { super(); this.id = id; this.username = username; this.passweord = passweord; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassweord() { return passweord; } public void setPassweord(String passweord) { this.passweord = passweord; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", passweord=" + passweord + "]"; } }
3.3.3 ac_accountDao和UserDao
在dao包下创建ac_accountDao和UserDao
-
UserDao
/** * 用户数据dao层类 */ public class UserDao{ }
-
AccountDao
/** * 账务数据dao层类 */ public class AccountDao{ }
3.3.4 ac_accountService和UserService
在service包下创建ac_accountService和UserService
-
AccountService
/** * 账务业务层类 */ public class AccountService { //service都依赖dao private AccountDao accountDao = new AccountDao(); }
-
UserService
/** * 用户业务层类 */ public class AccountService { //service都依赖dao private UserDao userDao = new UserDao(); }
3.3.5 MainView
在view层创建MainView.java.在该中,我们定义三个方法
run() , loginView() , zwManagerView()
public class MainView {
//本项目中view依赖service
private AccountService accountService = new AccountService();
private UserService userService = new UserService();
// 运行loginView和zwManagerView界面
public void run() {
}
// 用户登录界面
private boolean loginView(){
}
// 账务管理界面
private void zwManagerView(){
}
}
四、功能模块
4.1 用户登录
4.1.1 流程分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cHmr8e9u-1688729463965)(assets/image-20210121171345903.png)]
4.1.2 代码实现
编写MainView
public class MainView {
public void login() {
System.out.println("==========请先登录====================");
Scanner sc =new Scanner(System.in);
//提示用户输入登录用户名及密码
System.out.println("请输入用户名:");
String name = sc.next();
System.out.println("请输入密码:");
String pass = sc.next();
// 调用service层代码 判断用户名 ----->Service调用Dao
UserService us = new UserServiceImpl();
User u= us.login(name, pass);
//如果登录成功 调用下面 menu()
if(u!=null) {
menu();
}else {
System.out.println("登录失败");
}
}
}
编写UserService
public class UserService {
@Override
public User login(String username, String password) {
//调用Dao层登录查询的方法
UserDao udao = new UserDaoImpl();
return udao.queryUser(username, password);
}
}
编写UserDao
public class UserDao{
@Override
public User queryUser(String name, String pass) {
Connection conn= JDBCUtils.getConnection();
String sql = "select id,username,password from ac_user where username=? and password =?";
//生成PreparedStatement
PreparedStatement pstmt=null;
ResultSet rs =null;
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setString(2, pass);
//发送sql
rs= pstmt.executeQuery();
while(rs.next()) {
//能登录成功时,
User u =new User();
u.setId(rs.getInt("id"));
u.setUsername(rs.getString("username"));
u.setPassweord(rs.getString("password"));
return u;//返回 User类的对象
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//释放资源
JDBCUtils.close(rs, pstmt, conn);
}
return null;
}
}
编写MainApp
public class MainApp {
public static void main(String[] args) {
new MainView().run();
}
}
4.2 编写账务管理界面
MainView.java中添加以下方法(显示菜单信息)
public void menu() {
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 operator = sc.nextInt();
switch (operator) {
case 1:
// 调用添加账务
System.out.println("添加账务");
break;
case 2:
// 编辑账务
System.out.println("编辑账务");
break;
case 3:
// 删除账务
System.out.println("删除账务");
break;
case 4:
// 查询账务
System.out.println("查询账务");
//查询所有账务信息
queryall();
break;
case 5:
// 退出系统
default:
System.out.println("Bye~~Bye~");
System.exit(0);
}
}
}
4.3 查询所有账务
4.3.1 代码实现
编写MainView类中的queryall()方法
// 查询方法
private void query() {
System.out.println("1:查询所有 2:按条件查询");
int chose = sc.nextInt();
switch (chose) {
case 1:
queryAll();
break;
case 2:
queryByParam();
}
}
编写MainView类中queryAll方法
// 查询所有
private void queryAll() {
List<ac_account> list = ac_accountService.findAll();
print(list);
}
编写MainView类中print方法
public void print(List<ac_account> list){
System.out.println("ID\t类别\t\t\t账户\t\t\t金额\t\t\t时间\t\t\t说明");
for (ac_account zw : list) {
System.out.println(zw.getid() + "\t" + zw.getsortname() + "\t\t"
+ zw.gettype() + "\t\t" + zw.getMoney() + "\t\t"
+ zw.getCreatetime() + "\t" + zw.getDescription());
}
}
编写ac_accountDao类中findAll方法
public class ac_accountDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtil.getDataSource());
// 查询所有
public List<ac_account> findAll(){
String sql = "select * from ac_account";
List<ac_account> list = template.query(sql, new BeanPropertyRowMapper<>(ac_account.class));
return list;
}
}
编写ac_accountService类中findAll方法
public class ac_accountService {
private ac_accountDao ac_accountDao = new ac_accountDao();
public List<ac_account> findAll(){
return ac_accountDao.findAll();
}
}
4.4 账务条件查询
条件按照日期进行查询。
4.4.2 代码实现
编写MainView类中queryByParam()方法
// 按条件查询
private void queryByParam() {
System.out.println("选择条件查询,日期格式为:yyyy-MM-dd");
Scanner in = new Scanner(System.in);
System.out.print("请输入查询起始时间:");
String start = in.next();
System.out.print("请输入查询结束时间:");
String end = in.next();
List<ac_account> list = ac_accountService.queryByDate(start,end);
print(list);
}
编写ac_accountService类中queryByDate方法
public class ac_accountService {
private ac_accountDao ac_accountDao = new ac_accountDao();
public List<ac_account> queryByDate(String start, String end) {
return ac_accountDao.queryByDate( start, end);
}
}
编写ac_accountDao类中queryByDate方法
/*
按照日期条件查询
*/
public List<ac_account> queryByDate(String start, String end) {
String sql = "select * from ac_account where createtime between ? and ?";
List<ac_account> list = template.query(sql, new BeanPropertyRowMapper<>(ac_account.class),start,end);
return list;
}
4.5 添加账务
4.6 编辑账务
询结束时间:");
String end = in.next();
List<ac_account> list = ac_accountService.queryByDate(start,end);
print(list);
}
==编写ac_accountService类中queryByDate方法==
```java
public class ac_accountService {
private ac_accountDao ac_accountDao = new ac_accountDao();
public List<ac_account> queryByDate(String start, String end) {
return ac_accountDao.queryByDate( start, end);
}
}
编写ac_accountDao类中queryByDate方法
/*
按照日期条件查询
*/
public List<ac_account> queryByDate(String start, String end) {
String sql = "select * from ac_account where createtime between ? and ?";
List<ac_account> list = template.query(sql, new BeanPropertyRowMapper<>(ac_account.class),start,end);
return list;
}