管家婆家庭记账软件

一、项目介绍

1.1 项目目标

      熟练View层、Service层、Dao层之间的方法相互调用操作、熟练dbutils操作数据库表完成增删改查

      通过本项目,了解公司项目开发的流程,充分的掌握项目需求分析、设计与功能的代码实现。提高独立分析需求与功能实现的能力。

 

1.2 项目功能介绍

查询账务、多条件组合查询账务、添加账务、编辑账务、删除账务

 

二、项目环境搭建

2.1 技术选型和jar包介绍

       每个项目都要使用一些已经成熟的技术,它们通常是由一些专业组织或团队所提供的开源免费技术。本项目中使用的技术如下:

①apache的commons组件:

  • commons-dbutils-1.4.jar:封装并简化了JDBC;
  • commons-dbcp-1.4.jar:apache commons提供的数据库连接池组件,命名为DBCP;
  • commons.pool-1.3.jar:DBCP连接池依赖该jar包;

 

②mysql-connector-java-5.1.28-bin.jar:MySQL的JDBC驱动包,用JDBC连接MySQL数据库必须使用该JAR包。

 

2.2 工具类介绍

       每个项目都会用到一些工具类,本项目也不例外。我们不用关心如何实现这些类,只要知道在项目我们如何使用这些工具类,下面是本项目中所使用的工具类以及介绍:

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 = "root";

   

    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;

    }

}

 

2.3 数据表创建

       对一个项目而言,表设计是非常重要的,因为应用程序中所有的操作都是基于数据库表而进行的,所以我们第一步就是创建数据库表。

       管家婆项目的数据库设计很简单,下面是创建库及表的SQL语句:

 

2.3.1 创建数据库

创建管家婆数据库 gjp

CREATE DATABASE gjp;

 

2.3.2 创建数据库表

创建账务表gjp_zhangwu

CREATE TABLE gjp_zhangwu (

  zwid INT PRIMARY KEY AUTO_INCREMENT,

  flname VARCHAR(200),

  money DOUBLE,

  zhangHu VARCHAR(100),

  createtime DATE,

  description VARCHAR(1000)

);

 

2.3.3 添加表数据

添加账务表数据

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','又开资');

 

 

2.4 项目分层(分包)的作用

程序为什么要分包分层?

以顾客去饭店吃饭案例分析一下:

小饭店: 一个服务员搞定(接待顾客\点菜\炒菜)

大饭店:

  1. 迎宾员(是否有预定\ 询问吃中餐还是西餐或者烧烤等\ 几位用餐 \ 领路到指定的包间\ 找点菜员为顾客点菜 )
  2. 点菜员(记录顾客点餐内容\ 记录是否有忌口等问题\ 找厨师为顾客炒菜)
  3. 厨师(按照顾客菜肴清单,进行炒菜)

     通过案例发现,当程序规模小的时候,可以一个人全部完成;但程序规模大的时候,一个人难以完成,这时,要采用多人合作的方式来完成程序开发。

        多人合作方式将会碰到工作任务分配问题,这时我们会想,每个人负责完成项目的一块内容就可以了。那么,这一块块内容的划分,就需要我们采用分层(分包)的方式完成了。

        通过下图(用户注册功能)来讲解下,项目中常见的分层(分包)。

  1. view层作用: 视图层,即项目中的界面
  2. controller层作用: 控制层, 获取界面上的数据,为界面设置数据; 将要实现的功能交给业务层处理
  3. service层作用: 业务层, 功能的实现, 与controller控制层和数据访问层DAO交互, 将对数据库的操作交给DAO数据访问层来处理
  4. dao层作用: 数据访问层, 用来操作数据库表的数据
  5. db数据库: 这里指MySQL
  6. domain 实体包: 存放JavaBean
  7. tools工具包:存放项目中使用到的工具类
  8. test 测试包: 存放项目功能测试的代码

 

 

2.5 工程创建及包管理

  1. 使用Eclipse创建Java工程,命名为gjp
  2. 创建工程包
    • cn.gjp.app: 存放main方法类;
    • cn.gjp.domain: 存放JavaBean;
    • cn.gjp.view: 存放界面,及表现层类;
    • cn.gjp.service: 存放业务层类;
    • cn.gjp.dao: 存放数据访问层类;
    • cn.gjp.tools:存放工具类
  3. 创建lib文件夹,用来存储使用的jar包

 

三、 功能模块

3.1 相关类创建

完成本项目中类的创建,无需在类中添加代码。

  1. 复制已编写好的工具类JDBCUtils.java 到 tools包中;
  2. 复制jar包mysql-connector-java-5.1.28-bin.jar[、commons-dbutils-1.4.jar、commons-dbcp-1.4.jar 、commons-pool-1.3.jar ,到lib文件夹中,通过Build Path操作,添加到classPath路径中,提供给JDBCUtils使用;
  3. 在app包中,创建类MainApp.java,编写main主方法,用来完成本项目的启动
  4. 在domain包中,创建类ZhangWu.java,它是用来封装账务信息的JavaBean。
  5. 在dao包中,创建类ZhangWuDao.java,给ZhangWuDao类添加一个成员变量QueryRunner对象,因为我们使用dbutils来操作数据库。
  6. 在service包中,创建类ZhangWuService.java,给ZhangWuService类添加一个类型为ZhangWuDao的成员变量,因为service依赖dao。
  7. 在view包中,创建类MainView.java,给MainView类添加一个类型为ZhangWuService的成员变量,因为本项目中view依赖service。

编写app包中MainApp.java

/**

 * 主方法类

 */

public class MainApp {

    public static void main(String[] args) {

    }

}

编写domain包中ZhangWu.java 

/**

 * 账务类

 */

public class ZhangWu {

}

编写Dao包中ZhangWuDao.java

/**

* 账务数据层类

 */

public class ZhangWuDao{

    //获取数据库连接池,得到操作表数据的对象 QueryRunner

    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

}

编写Service包,ZhangWuService.java

/**

* 账务业务层类

 */

public class ZhangWuService {

    //service都依赖dao

    private ZhangWuDao zhangWuDao = new ZhangWuDao();

}

 编写view包,MainView.java

public class MainView {

    //本项目中view依赖service

    private ZhangWuService zhangWuService = new ZhangWuService();

}

 

3.2 账务JavaBean

       JavaBean是指的是Java中的类,该类中的成员变量与数据库表中的字段相对应(变量名对应数据库表字段名、变量数据类型对应数据库表字段类型),并提供空参数构造方法、set、get方法。

       现在来完成账务类的代码编写,如下:

/**

 * 账务类

 */

public class ZhangWu {

    private int zwid;// id

    private String flname;// 分类名称

    private String zhangHu;// 账户名称

    private double money;// 金额

    private String createtime;// 创建时间

    private String description;// 说明

 

    public String getFlname() {

         return flname;

    }

    public void setFlname(String flname) {

         this.flname = flname;

    }

    public String getZhangHu() {

         return zhangHu;

    }

    public void setZhangHu(String zhangHu) {

         this.zhangHu = zhangHu;

    }

    public int getZwid() {

         return zwid;

    }

    public void setZwid(int zwid) {

         this.zwid = zwid;

    }

    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;

    }

}

 

3.3 功能界面菜单

界面菜单的完成,是项目编写的第一步。

通过输出语句,完成界面菜单的输出,之后再根据输入的功能序号,进行对应功能的调用执行。

 

3.3.1 功能实现步骤

1. 编写MainView类run方法

       ①完成功能界面菜单显示

       ②接收键盘输入的功能选项

       ③根据选项值,调用对应的功能方法

 

2. 编写MainApp类的main主方法

       调用MainView类中run方法,实现将程序执行起来,显示功能界面菜单。

 

3.3.2 功能实现代码

1.在view包MainView类中编写run方法

/**

 * 运行方法

 */

public void run() {

    /*

     * 1. 打印菜单 2. 获取用户输入 3. 调用对应方法

     */

    boolean flag = true;

    Scanner in = new Scanner(System.in);

    while (flag) {

        System.out.println("---------------管家婆家庭记账软件---------------");

         System.out.println("1.添加账务 2.编辑账务 3.删除账务 4.查询账务 5.退出系统");

        System.out.println("请输入要操作的功能序号[1-5]:");

        int op = in.nextInt();

         switch (op) {

         case 1:

             addZhangWu();

             break;

         case 2:

             editZhangWu();

             break;

         case 3:

             deleteZhangWu();

             break;

         case 4:

             selectZhangWu();

             break;

         case 5:

             System.out.println("再见!");

             flag = false;

             break;

         default:

             System.out.println("输入错误!");

         }

    }

}

 

2.app包MainApp类的main主方法中,调用MainView类中run方法

public static void main(String[] args) {

    new MainView().run();

}

 

3.4 查询所有账务

 

3.4.1 功能实现步骤

1. 编写MainView类中selectZhangWu方法

        ①通过输出语句,显示出要查询账务的方式

        ②接收键盘的输入项,调用对应的方法(1.查询所有 2.按条件查询

 

2. 编写MainView类中selectAll查询所有账务方法

        ①调用ZhangWuService类selectAll方法,返回包含所有账务数据的List<ZhangWu>集合

        ②调用MainView类中print方法,实现控制台显示所有账务数据

 

3. 编写MainView类中print方法

        ①使用输出语句,打印出账务表的表头名称

        ②遍历账务集合,将每个账务信息输出打印

 

4. 编写ZhangWuService类中selectAll方法

        ①调用ZhangWuDao类中selectAll方法,返回包含所有账务数据的List<ZhangWu>集合

 

5 . 编写ZhangWuDao类中selectAll()方法

        ①通过QueryRunner对象,调用query方法查询数据库表gjp_zhangwu,返回包含所有账务数据的List<ZhangWu>集合

 

3.4.2 功能实现代码

1. 编写MainView类中selectZhangWu方法

/**

 * 查询账务方法

 */

public void selectZhangWu() {

    System.out.println("1.查询所有 2.按条件查询");

    Scanner in = new Scanner(System.in);

    int op = in.nextInt();

    switch (op) {

    case 1:

         selectAll();

         break;

    case 2:

         select();

         break;

    default:

         System.out.println("输入错误!");

    }

}

 

2. 编写MainView类中selectAll方法

/**

 * 查询所有账务方法

 */

public void selectAll() {

    List<ZhangWu> zhangWuList = zhangWuService.selectAll();

    print(zhangWuList);

}

 

3. 编写MainView类中print方法

/*

 * 输出账务方法

 */

private void print(List<ZhangWu> zhangWuList) {

    System.out.println("ID\t类别\t\t账户\t\t金额\t\t时间\t\t说明");

    for (ZhangWu zw : zhangWuList) {

         System.out.println(zw.getZwid() + "\t" + zw.getFlname() + "\t\t"

                  + zw.getZhangHu() + "\t\t" + zw.getMoney() + "\t\t"

                  + zw.getCreatetime() + "\t" + zw.getDescription());

    }

}

 

4. 编写ZhangWuService类中selectAll方法

/**

 * 查询所有

*/

public List<ZhangWu> selectAll() {

    return zhangWuDao.selectAll();

}

 

5. 编写ZhangWuDao类中selectAll()方法

/**

 * 查询所有账务

 */

public List<ZhangWu> selectAll() {

    String sql = "select * from gjp_zhangwu";

    try {

         return qr.query(sql, new BeanListHandler<ZhangWu>(ZhangWu.class));

    } catch (SQLException e) {

         throw new RuntimeException(e);

    }

}

 

3.5 多条件查询账务

 

 

3.5.1 功能分析

1. 编写MainView类中select方法

    ①通过键盘输入查询日期的范围

    ②调用ZhangWuSerice类中select方法,返回查询日期范围内的账务信息集合List<ZhangWu>

    ③调用MainView类中的print方法,将账务信息集合中的内容显示在控制台中

 

2. 编写ZhangWuService类中select方法

    ①调用ZhangWuDao 类中select方法,返回查询日期范围内的账务信息集合List<ZhangWu>

 

3. 编写ZhangWuDao类中select方法

    ①通过QueryRunner对象,调用query方法查询数据库表gjp_zhangwu,返回包含查询日期范围内的账务数据List<ZhangWu>集合

 

3.5.2 功能实现步骤

1. 编写MainView类中select方法

/**

 * 按条件查询账务方法

 */

public void select() {

    /*

     * 1. 获取用户输入查询日期范围。

     * 2. 调用serviceselect()方法完成条件查询功能

     */

    Scanner in = new Scanner(System.in);

    System.out.print("请输入查询起始时间:");

    String start = in.next();

    System.out.print("请输入查询结束时间:");

    String end = in.next();

    List<ZhangWu> zhangWuList = zhangWuService.select(start, end);

    print(zhangWuList);

}

 

2. 编写ZhangWuService类中select方法

/**

 * 按条件查询账务方法

 * @param start

 * @param end

 * @return

 */

public List<ZhangWu> select(String start, String end) {

    return zhangWuDao.select(start, end);

}

 

3. 编写ZhangWuDao类中select方法

/**

 * 按条件查询账务方法

 * @param start

 * @param end

 * @return

 */

public List<ZhangWu> select(String start, String end) {

    String sql = "select * from gjp_zhangwu where createtime between ? and ?";

    Object[] params = {start, end};

    try {

         return qr.query(sql, new BeanListHandler<ZhangWu>(ZhangWu.class), params);

    } catch (SQLException e) {

         throw new RuntimeException(e);

    }

}

 

3.6 添加账务

 

 

3.6.1 功能分析

1. 编写MainView类中addZhangWu方法

    ①键盘输入新添加的账务信息

    ②调用ZhangWuService类中addZhangWu方法,用来指定账务的添加

    ③添加完毕后,使用输出语句,提示“添加账务成功!”

 

2.编写ZhangWuService类中addZhangWu方法

    ①调用ZhangWuDao类中addZhangWu方法,用来指定账务的添加

 

3. 编写ZhangWuDao类中addZhangWu方法

     ①通过QueryRunner对象,调用update方法更新数据库表gjp_zhangwu,完成指定账务添加到数据库表中

 

3.6.2 功能实现步骤

1. 编写MainView类中addZhangWu方法

/**

 * 添加账务方法

 */

public void addZhangWu() {

    /*

     * 1. 获取用户输入,封装到bean中。

     * 2. 调用serviceaddZhangWu()方法完成添加功能

     */

    Scanner in = new Scanner(System.in);

    ZhangWu zw = new ZhangWu();

    System.out.print("请输入类别:");

    zw.setFlname(in.next());

    System.out.print("请输入账户:");

    zw.setZhangHu(in.next());

    System.out.print("请输入金额:");

    zw.setMoney(in.nextDouble());

    System.out.print("请输入时间:");

    zw.setCreatetime(in.next());

    System.out.print("请输入说明:");

    zw.setDescription(in.next());

   

    zhangWuService.addZhangWu(zw);

    System.out.println("添加账务成功!"); 

}

 

2. 编写ZhangWuService类中addZhangWu方法

/**

 * 添加账务

 * @param zw

 */

public void addZhangWu(ZhangWu zw) {

    zhangWuDao.addZhangWu(zw);

}

 

3. 编写ZhangWuDao类中addZhangWu方法

/**

 * 添加账务

 * @param zw

 */

public void addZhangWu(ZhangWu zw) {

    String sql = "insert into gjp_zhangwu(flname,money,zhanghu,createtime,description) values(?,?,?,?,?)";

    try {

         Object[] params = {zw.getFlname(),zw.getMoney(),zw.getZhangHu(),zw.getCreatetime(),zw.getDescription()};

         qr.update(sql, params);

    } catch (SQLException e) {

         throw new RuntimeException(e);

    }  

}

 

3.7 编辑账务

 

 

3.7.1 功能分析

1. 编写MainView类中editZhangWu方法

      ①键盘输入要编辑的账务信息ID号

      ②键盘输入要修改的账务信息内容

      ③调用ZhangWuService类中editZhangWu方法,用来将指定的账务信息进行更新

      ④更新完毕后,使用输出语句,提示 “编辑账务成功!”

 

2. 编写ZhangWuService类中editZhangWu方法

       ①调用ZhangWuDao类中editZhangWu方法,用来将指定的账务信息进行更新

 

3. 编写ZhangWuDao类中editZhangWu方法

      ①通过QueryRunner对象,调用update方法更新数据库表gjp_zhangwu,完成数据库表中指定账务更新操作

 

3.7.2 功能实现步骤

1. 编写MainView类中editZhangWu方法

/**

 * 编辑账务方法

 */

public void editZhangWu() {

    /*

     * 1. 获取用户输入,封装到bean中。

     * 2. 调用serviceeditZhangWu()方法完成添加功能

     */

    Scanner in = new Scanner(System.in);

    ZhangWu zw = new ZhangWu();

    System.out.print("请输入ID");

    zw.setZwid(in.nextInt());

    System.out.print("请输入新类别:");

    zw.setFlname(in.next());

    System.out.print("请输入新账户:");

    zw.setZhangHu(in.next());

System.out.print("请输入新金额:");

    zw.setMoney(in.nextDouble());

    System.out.print("请输入新时间:");

    zw.setCreatetime(in.next());

    System.out.print("请输入新说明:");

    zw.setDescription(in.next());

   

    zhangWuService.editZhangWu(zw);

    System.out.println("编辑账务成功!");

}

 

2. 编写ZhangWuService类中editZhangWu方法

/**

 * 编辑账务

 * @param zw

 */

    public void editZhangWu(ZhangWu zw) {

    zhangWuDao.editZhangWu(zw);

}

 

3. 编写ZhangWuDao类中editZhangWu方法

/**

 * 编辑账务

 * @param zw

 */

public void editZhangWu(ZhangWu zw) {

    String sql = "update gjp_zhangwu set flname=?, money=?,zhanghu=?,createtime=?,description=? where zwid=?";

    try {

         Object[] params = {zw.getFlname(),zw.getMoney(),zw.getZhangHu(),zw.getCreatetime(),zw.getDescription(),zw.getZwid()};

         qr.update(sql, params);

    } catch (SQLException e) {

         throw new RuntimeException(e);

    }  

}

 

3.8 删除账务

 

 

3.8.1 功能分析

1. 编写MainView类中deleteZhangWu方法

     ①键盘输入要删除的账务信息ID号

     ②调用ZhangWuService类中deleteZhangWu方法,用来将指定的账务信息删除

     ③删除完毕后,使用输出语句,提示 “删除账务成功!”

 

2. 编写ZhangWuService类中deleteZhangWu方法

      ①调用ZhangWuDao类中deleteZhangWu方法,用来将指定的账务信息删除

 

3. 编写ZhangWuDao类中deleteZhangWu方法

      ①通过QueryRunner对象,调用update方法更新数据库表gjp_zhangwu,完成数据库表中指定账务删除操作

 

3.8.2 功能实现步骤

1. 编写MainView类中deleteZhangWu方法

/**

 * 删除账务方法

 */

public void deleteZhangWu() {

    /*

     * 1. 获取用户输入,封装到bean中。

     * 2. 调用servicedeleteZhangWu()方法完成添加功能

     */

    Scanner in = new Scanner(System.in);

    System.out.print("请输入ID");

   

    zhangWuService.deleteZhangWu(in.nextInt());

    System.out.println("删除账务成功!");

}

 

2. 编写ZhangWuService类中deleteZhangWu方法

/**

 * 删除账务

 * @param zwid

 */

public void deleteZhangWu(int zwid) {

    zhangWuDao.deleteZhangWu(zwid);

}

 

3. 编写ZhangWuDao类中deleteZhangWu方法

/**

 * 删除账务

 * @param zwid

 */

public void deleteZhangWu(int zwid) {

    String sql = "delete from gjp_zhangwu where zwid=?";

    try {

         qr.update(sql, zwid);

    } catch (SQLException e) {

         throw new RuntimeException(e);

    }

}

 

3.9 功能模块总结

       view层的作用是“界面”,用来完成数据显示给用户。当前项目view层中,包含了Controller层代码。

       Controller层的作用是“调度”,调度的是表现层view和业务层Service,主要功能分为:一是把表现层的数据交给业务层处理;二是把业务层返回的数据交给表现层显示。

       Service层的作用是“业务”,我们也可以把“业务”当成是“功能”。那为什么Service层代码量少呢?原因是现在写的项目很小,没有什么复杂的业务,而大型项目代码量最大的就是Service层。

       DAO层是操作数据库,现在我们使用的是commons-dbutils工具来简化JDBC,所以我们发现代码不多,比较简单。以后还会学习其他DAO层的工具,例如:hibernate和mybatis,他们都是JDBC的封装,用来简化JDBC。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值