一、项目介绍
1.1 项目目标
本项目为JAVAEE基础和数据库的综合项目,包含了若干个知识点,达到将从基础班到现在所学的知识综合使用,提高了我们对项目的理解与知识点的运用。
熟练View层、Service层、Dao层之间的方法相互调用操作
熟练使用工具类操作数据库表完成增删改查以及登录的功能
通过本项目,让我们了解公司项目开发的流程,充分的掌握项目需求分析、设计与功能的代码实现。提高同学们独立分析需求与功能实现的能力。
二、项目环境搭建
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),
password VARCHAR(20),
isManager int -- 1.管理员;0:普通用户;
);
INSERT ac_user(username,password,isManager)
values('admin','admin',1),
('user','user',0)
/*
创建数据表,表名账务
字段,列
主键
分类名称 可变字符
金额 double
支付方式 可变字符 (支付,收入方法)
创建日期 date
账务描述 可变字符
*/
CREATE TABLE ac_account(
id INT PRIMARY KEY AUTO_INCREMENT, -- 主键
sortname VARCHAR(200),-- 分类名称
money decimal(10,2),-- 金额
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','股票大涨');
2.2 技术选型
每个项目都要使用一些已经成熟的技术,它们通常是由一些专业组织或团队所提供的开源免费技术。在今后的学习过程中,我们会逐渐对这些专业组织有所了解。本项目中使用的技术如下:
package cn.yh.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* druid的通用类;
* 1.导入jar和配置文件;
* 2.创建一个通用类,static,读取文件;
* 3.工厂来获取?连接池--->连接;
*/
public class DruidUtil {
//成员变量
static DataSource ds=null;
static Connection conn=null;
static PreparedStatement pst=null;
static ResultSet rs=null;
static {
try {
InputStream fis = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
//FileInputStream fis=new FileInputStream("src/db.properties");
Properties prop=new Properties();
prop.load(fis);
//通过工厂,来获取连接池对象ds
ds= DruidDataSourceFactory.createDataSource(prop);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接:DriverManager
public static Connection getConnection(){
try {
conn= ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return conn;
}
//3.通用的增删改,easy;注意理解思想:可变参;由于也不清楚,具体的类型,所以,写Object; ... :可变参;
//可变参:本质是数组;注意:当没有参数的时候,可以直接写update(sql,null),update(sql);
public static int update(String sql,Object ... params){
int result=0;
//3.2 获取预编译语句对象;
try {
conn=getConnection(); //从本类来调用一下;
System.out.println(conn);
pst = conn.prepareStatement(sql);
//针对?赋值;
if(params!=null){
for (int i = 0; i < params.length; i++) {
pst.setObject(i+1,params[i]);
}
}
result=pst.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
close(null,pst,conn);
}
return result;
}
//4.通用封装查询
//5.通用封装等;
//6.
public static void close(ResultSet r, Statement s, Connection c){
if (c!=null){
try {
c.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (r!=null){
try {
r.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (s!=null){
try {
s.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.4 项目分层(分包)
项目分层,分包好处是方便管理,各自负责各自的功能,也方便我们找错改问题!
3.1 相关类创建
主界面类:
public class TestUtil {
@Test
public void test01(){
MainView mv=new MainView();
mv.login();
}
}
MainView类
package cn.yh.test;
import cn.yh.dao.AccountDao;
import cn.yh.dao.AccountDaoImpl;
import cn.yh.dao.UserDao;
import cn.yh.dao.UserDaoImpl;
import cn.yh.entity.Account;
import cn.yh.entity.User;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
/*
* 4.主界面的类;这里实现类,是其成员变量;
* */
public class MainView {
UserDao userDao=new UserDaoImpl();
AccountDao accountDao=new AccountDaoImpl();
Scanner sc=new Scanner(System.in); //为了后续,有很多的输入,直接在外面设计sc控制台输入为成员变量;
//接下来是界面的设计;简单的界面;操作:登录;其他查询?
//4.1构建第一个界面;
public void login(){
System.out.println("----------------金算盘账务管理系统----------------");
int i=3;
while(i>0) {
System.out.println("请输入账户:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
i--;
//调用实现类:
User user = userDao.selectUser(username, password);
if (user != null) { //登录
menu();
} else {
if(i==0)break;
System.out.println("账户名和密码不对!,还剩机会"+(i)+"机会"); //如果不对,则继续输入,升级改进,加循环;!
}
}
}
//4.2 构建第二个界面;针对账户,做选择操作;汇总sum(money) ;其他人;当前账户的信息,sum(money)
public void menu(){
while(true){
System.out.println("*******************账务管理系统*******************");
System.out.println("请选择您的操作:1.查看余额 2.存款 3.取款 4.转账 5.查看明细 6.修改密码 7.退出");
int choice=sc.nextInt(); //获取方式,和nextLine() 以回车换行读取 ;nextInt();
switch (choice){
case 1:
selectBalance();break;
case 2:
saveMoney();break;
case 3:
drawMoney();break;
case 4:
transferMoney();break;
case 5:
selectDetails();break;
case 6:
editPwd();break;
case 7:
System.exit(0);
default:
break;
}
}
}
/**
* 修改自己的密码;由于这里是针对用户的操作,需要userDao增加方法;
*/
private void editPwd() {
}
/**
* 4.7 查看明细界面;一个是查看所有详情信息;另外一个是按时间查询(开始和结束时间);
*/
private void selectDetails() {
System.out.println("---------------账务管理系统---------------------");
System.out.println("请选择您的操作:1.查看所有信息 2.按时间查询 ");
int choice=sc.nextInt();
switch (choice){
case 1:
selectAll();break;
case 2:
selectByDate();break;
}
}
//4.7.2条件查询;升级:
// 4.7.3 根据所有收入%模糊查询; 所有奖金;
// 4.7.4查询收入一共有多少前;支出一共有多少钱;group by分组; mysql
// 4.7.5 排序;查询今年支出排序;order by
// 子业务: 需要输入一个开始时间,一个结束时间;
//输入值,由selectByDate()来接收值;
private void selectByDate() {
sc.nextLine();
System.out.println("请输入开始时间:");
String startTime=sc.nextLine();
System.out.println("请输入结束时间:");
String endTime=sc.nextLine();
//去调用根据时间的查询;
List<Account> accountList = accountDao.selectByDate(startTime, endTime);
accountList.forEach(a->{
System.out.println(a.getId()+"\t"+a.getSortname()+"\t"+a.getMoney()+"\t"+a.getType());
});
}
//4.7.1查看所有信息;查看所有账户account的信息,需要去调用accountDao信息;
private void selectAll() {
List<Account> accountList = accountDao.selectAll();
// for (Account a : accountList) {
// System.out.println(a.getId()+"\t"+a.getTypeName()+"\t"+a.getMoney()+"\t"+a.getType());
// }
//stream forEach 兰布达;
accountList.forEach(a->{
System.out.println(a.getId()+"\t"+a.getSortname()+"\t"+a.getMoney()+"\t"+a.getType());
});
}
//4.6转账界面
private void transferMoney() {
}
//4.5取款界面
private void drawMoney() {
}
//4.4 存款界面;去对账户做处理;
private void saveMoney() {
System.out.println("---------------账务管理系统---------------------");
sc.nextLine();
System.out.println("请输入存款的类型:");
String typeName=sc.nextLine();
System.out.println("请输入存款金额:");
int money=sc.nextInt();
sc.nextLine();
System.out.println("请输入存款方式:(银行、支付宝、微信、现金)"); //1.xx银行;2.支付宝;3.微信;4.现金
String type=sc.nextLine();
System.out.println("请输入备注信息:");
String desc=sc.nextLine();
//去调用实体类的存款方法;
//去对对象做一个封装;a:是一个账户对象;
//这里需要重点来理解一下,我用的当前时间:是java系统的时间;java.util包;
long nowTime = new Date().getTime();
//存到数据库的时候,java.sql.Date
Account a=new Account(typeName,type,money,new java.sql.Date(nowTime),desc);
int result=accountDao.saveMoney(a); //将a作为参数传递过去;
if(result>0){
System.out.println("存款成功!");
//去哪里?
}
}
//4.3 第三个界面;查看余额;
private void selectBalance() {
double v = accountDao.selectBalance();
System.out.println("您的余额是:"+v);
}
}
实体类:
package cn.yh.entity;
//2.实体类User
public class User {
private int id;
private String userName;
private String password;
public User() {
}
public User(int id, String userName, String password) {
this.id = id;
this.userName = userName;
this.password = password;
}
public User(String userName, String password) {
this.userName = userName;
this.password = password;
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
'}';
}
}
Account类
package cn.yh.entity;
import java.sql.Date; //后续要存到数据库;sql.Date
//2.2实体类Account
public class Account {
private int id;
private String sortname;
private String type;
private double money;
private Date createTime;
private String description;
public Account() {
}
public Account(String sortname, String type, double money, Date createTime, String description) {
this.sortname = sortname;
this.type = type;
this.money = money;
this.createTime = createTime;
this.description = description;
}
public Account(int id, String sortname, String type, double money, Date createTime, String description) {
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 Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date 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 +
", typeName='" + sortname + '\'' +
", type='" + type + '\'' +
", money=" + money +
", createTime=" + createTime +
", description='" + description + '\'' +
'}';
}
}
数据层:
package cn.yh.dao;
import cn.yh.entity.Account;
import java.util.List;
//3.3 接口;Account的CRUD;
public interface AccountDao {
//完善存款方法;
public int saveMoney(Account a);
//增加一个查看所有账户信息的方法;
public List<Account> selectAll();
//增加一个方法,根据时间来查询信息的方法;
public List<Account> selectByDate(String startTime,String endTime);
//里面增加一个查询余额的方法;
public double selectBalance();
//根据cardid来查询的方法即可;
}
实现类:
package cn.yh.dao;
import cn.yh.entity.Account;
import cn.yh.util.DruidUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//3.4创建 接口的实现类;
public class AccountDaoImpl implements AccountDao {
//类的成员变量;初始的时候,设置为null,在方法调用的时候去赋值,可以节省内存空间 ;
Connection conn=null;
PreparedStatement pst=null;
ResultSet rs=null;
//传递的参数在Account对象a里面;
@Override
public int saveMoney(Account a) {
String sql="insert ac_account(sortname,type,money,createtime,description)values(?,?,?,?,?)";
Object[]params={a.getSortname(),a.getType(),a.getMoney(),a.getCreateTime(),a.getDescription()};
return DruidUtil.update(sql,params);
}
//实现这个查看所有信息的方法;
@Override
public List<Account> selectAll() {
//获取链接;
conn= DruidUtil.getConnection();
List<Account>accountList=null;
//语句对象;
try {
pst=conn.prepareStatement("select * from ac_account");
rs=pst.executeQuery();
accountList=new ArrayList<>(); //创建实例;
//list:里面存放的是Account的集合;每个Account对象
while(rs.next()){
Account a=new Account(); //创建对象 ,下面几行是赋值;
a.setId(rs.getInt("id"));
a.setSortname(rs.getString("typeName"));
a.setType(rs.getString("type"));
a.setMoney(rs.getDouble("money"));
a.setCreateTime(rs.getDate("createTime"));
a.setDescription(rs.getString("description"));
accountList.add(a);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DruidUtil.close(rs,pst,conn);
}
return accountList;
}
@Override
public List<Account> selectByDate(String startTime, String endTime) {
conn=DruidUtil.getConnection();
List<Account> accountList=null;
try {
pst=conn.prepareStatement("select * from ac_account where createTime between ? and ?"); //复习sql
//需要赋值给?
pst.setString(1,startTime);
pst.setString(2,endTime);
rs=pst.executeQuery(); //结果集对象获取;
accountList=new ArrayList<>(); //作用域,在try{}有效; 100万亿津巴布韦币;
Account a=null;
while(rs.next()){
a=new Account();
a.setId(rs.getInt("id"));
a.setSortname(rs.getString("typeName"));
a.setType(rs.getString("type"));
a.setMoney(rs.getDouble("money"));
a.setCreateTime(rs.getDate("createTime"));
a.setDescription(rs.getString("description"));
//添加到集合;
accountList.add(a);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DruidUtil.close(rs,pst,conn);
}
return accountList;
}
/*
后续如果要扩充,根据cardid,来余额
selectBalance(String cardid){}
select sum(money) from ac_account group by cardid
*/
@Override
public double selectBalance() {
String sql="select sum(money) from ac_account";
conn=DruidUtil.getConnection();
double result=0.0;
try {
pst=conn.prepareStatement(sql);
rs = pst.executeQuery();
//只查询一条数据;单行单列;
if(rs.next()){
result =rs.getDouble(1);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DruidUtil.close(rs,pst,conn);
}
return result;
}
}
UserDao接口
package cn.yh.dao;
import cn.yh.entity.User;
//3.创建接口:针对User表的操作;CRUD
public interface UserDao {
//3.3.1第一个方法,是查询;User user;参数就是刚才的用户名和密码;
public User selectUser(String username,String password);
}
实现类:
package cn.yh.dao;
import cn.yh.entity.User;
import cn.yh.util.DruidUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//3.2 UserDao的实现类;这里暂时不考虑,用户名和密码,重复;
public class UserDaoImpl implements UserDao{
//让三个接口对象为成员变量,可以在finally访问;
Connection conn=null;
PreparedStatement pst=null;
ResultSet rs=null;
@Override
public User selectUser(String username, String password) {
User user=null;
String sql="select * from ac_user where username=? and password=?";
try {
conn= DruidUtil.getConnection(); //
pst= conn.prepareStatement(sql);
pst.setString(1,username);
pst.setString(2,password);
rs= pst.executeQuery();
if(rs.next()){
user=new User();
user.setId(rs.getInt("id"));
user.setUserName(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DruidUtil.close(rs,pst,conn);
}
return user;
}
}
618,清华社 IT BOOK 多得图书活动开始啦!活动时间为 2023 年 6 月 7 日至 6 月 18 日,清华
社为您精选多款高分好书,涵盖了 C++、Java、Python、前端、后端、数据库、算法与机器学习等多
个 IT 开发领域,适合不同层次的读者。全场 5 折,扫码领券更有优惠哦!快来京东点击链接 IT BOOK
多得(或扫描京东二维码)查看详情吧!