soso移动营业大厅(纯后端+MySQL数据库+JDBC)

news2024/11/16 7:32:04

一、项目需求

中国移动,中国联通,中国电信是国内3大通信运营商,每个运营商都提供了不同的品牌套餐来应对不同的用户群,比如北京移动主要有全球通,神州行,动感地带等3大品牌套餐,每种套餐的内容和费用不同,嗖嗖移动是一个假定的通信运营商,提供了话痨套餐,网虫套餐,超人套餐,各种套餐所包含的服务内容及费用如下表:

品牌套餐话痨套餐网虫套餐超人套餐
通话时长(分钟)6000300
上网流量02010
短信条数(条)100050
费用(元/月)586878

如实际使用中超出套餐内包含的通话时长,短信条数和上网流量,则按一下规则计费:

  • 超出的通话: 0.2元/分

  • 超出的短信:0.1元/条

  • 超出的上网流量:0.1元/MB

本任务实现的"嗖嗖移动业务大厅"提供了嗖嗖移动用户的常用功能,包括新用户注册,本月账单查询,套餐余量查询,打印消费详情,套餐变更,办理退网,话费充值,查看消费记录,查看话费说明等功能.另外,还可以模拟用户通话,上网,发送短信的场景进行相应的扣费并记录消费信息.各功能介绍如下表:

菜单级别功能描述
主菜单用户登录输入正确的手机号码和密码进入二级菜单列表
主菜单用户注册录入信息并开卡,用户输入的信息包括:选择卡号,选择套餐类型,输入用户名和密码,预存话费金额(预存话费金额必须满足以支付所选套餐的一个月的费用)
主菜单使用嗖嗖输入正确的手机号码和密码之后,随机进入本号码所属套餐可以支持的一个场景,消费套餐余量或者话费余额,并记录消费信息.当话费余额不足时,抛出异常提醒用户充值
主菜单话费充值输入正确的用户名和密码之后,可为该卡号充值
主菜单资费说明提供各品牌套餐所包含的通话时长,上网流量,短信条数,月费用等
主菜单退出系统提出本系统
二级菜单本月账单查询可查询该卡号的套餐费用,实际消费金额,账户余额
二级菜单套餐余量查询可查询该卡号的套餐余量
二级菜单打印消费详情输入正确的卡号和密码后,可打印当前卡号用户的消费详单, 使用输出流把用户信息输出到文件
二级菜单套餐变更可变更为其他套餐类型,变更后话费余额需减去变更后的套餐费用,余额不足时需要给出信息提示,套餐变更后重新统计卡中实际消费数据以及当月消费金额
二级菜单办理退网输入正确的卡号和密码后,可以从已注册的号码列表中删除本号码,并退出系统

二、项目需求分析

2.1 登陆

  1. 让用户输入手机号码, 密码,

  2. 根据手机号码,密码到数据库: tb_mobole_card查询

  3. 如果没有记录: 登录失败, 错误提示: 手机号码或者密码错误

  4. 如果有记录,但是状态是1(冻结): 登录失败, 错误提示: 该手机号码已冻结,请联系工作人员

  5. 登录成功, 进入到二级菜单

2.2 注册

  1. 查询所有可用卡 tb_card

  2. 查询所有的套餐类型, 用户选择套餐类型,

  3. 根据用户选择的套餐类型, 查询套餐信息

  4. 用户输入用户,密码. 输入充值金额

  5. 根据输入金额与用户选择套餐的月租比较, 输入金额小于月租, 错误提示, 用户再重新输入

  6. 如果大于等于, 往用户卡表(tb_mobole_card)插入一条记录

  7. 修改tb_card表,用户选择该手机号码的卡状态设置为不可用

  8. 往充值记录表中添加一条充值记录

  9. 显示办卡成功, 输出用户卡相关信息,以及套餐信息

  10. 跳转到一级菜单

​​​​2.3 使用soso

  1. 输入手机号码   查询到用户卡信息   查询套餐 2. 如果卡冻结状态, 无法使用嗖嗖 显示错误信息 3. 查询所有的场景, 随机一个场景进行模拟   得到场景类型,  数据

  2. 假设随机第一个场景, 通话场景, 打90分钟电话,

    剩余免费余量 = 套餐最大免费量 - 月消费当月消费量(查询月消费)

  3. 如果用户的卡的剩余免费余量 > =场景的数量, 不需要扣钱, 在月消费记录表, 当月增加使用量的值

  4. 如果用户的卡的剩余免费余量 < 场景的数量, 需要扣钱, 在月消费记录表, 当月增加使用量的值,超出的部分进行扣费, 修改的用户卡的余额

  5. 往消费记录表进行记录本次消费 消费记录表

2.4 套餐变更

  1. 查询所有的套餐类型

  2. 根据当前登录的手机号码, 查询当前用户卡信息

  3. 用户选择套餐类型,根据用户现在的套餐明细得到套餐类型

  4. 判断用户选择的套餐是否是用户卡现在套餐,如果是,提示,

  5. 如果不是,根据用户选择的套餐类型,查询对应的套餐明细

  6. 判断用户卡的余额是否满足该套餐的月租, 如果不满足, 提示

  7. 如果满足, 更换套餐, 修改用户卡信息(套餐,余额)

  8. 打印用户新套餐的明细

三、代码展示

1.系统大体结构

2.使用的jar包

commons-dbutils-1.7.jarmysql-connector-java-5.1.47.jar
提供了简化数据库操作的工具连接 MySQL 数据库的 JDBC 驱动程序

这两个 JAR 包通常用于 Java 应用程序中与数据库进行交互的过程中

hamcrest- 2.1jarjunit-4.12.jar 
提供更加灵活和可读性强的测试断言方式用于编写和运行单元测试

这两个库通常会一起被用于编写高质量的测试代码,以确保代码的正确性和稳定性。

3.完整代码

1、常量类(constant包)
package com.lx.soso.constant;


public interface SystemConstant {

     /**
      * 用户正常状态
      */
     int MOBOLE_STATUS_NORMAL=0;
     /**
      * 用户冻结状态
      */
     int MOBOLE_STATUS_FREEZE=1;

     /**
      * 手机卡的正常状态
      */
     int CARD_STATUS_NORMAL = 0;

     /**
      * 手机卡卡号的禁用状态
      * 已被使用
      */
     int CARD_STATUS_FREEZE = 1;

     /**
      * 一级管理员
      */
     int FIRST_LEVEL_ADMINISTRATOR = 1;

     /**
      * 二级管理员
      */
     int SECONDARY_LEVEL_ADMINISTRATOR = 2;

     /**
      * 已回复
      */
     int REPLIED = 0;

     /**
      * 未回复
      */
     int NOT_REPLIED = 1;
}
2、功能实现类(service包)
package com.lx.soso.service;

import com.lx.soso.constant.SystemConstant;
import com.lx.soso.dao.*;
import com.lx.soso.dao.impl.*;
import com.lx.soso.entity.*;
import com.lx.soso.ui.SosoApp;
import com.lx.soso.util.DateUtil;
import com.lx.soso.util.JDBCUtil;

import java.util.*;


public class SoSoService {
    Scanner input = new Scanner(System.in);
    //private String number = null;

    /**
     * 登陆
     *
     * @return
     */
    public MoboleCard login() {
        System.out.print("请输入手机卡号:");
        String number = input.next();
        System.out.print("请输入密码:");
        String password = input.next();

        //实例化赋给接口
        //2.调用dao层类的方法
        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        MoboleCard moboleCard = moboleCardDao.queryByNumber(number);

        if (moboleCard == null) {//没有找到该手机号
            System.out.println("【友情提示:】卡号或者密码错误!");
        } else {//有该手机号 ,但可能状态异常和密码错误
            if (!moboleCard.getPassword().equals(password)) {//密码错误
                System.out.println("【友情提示:】卡号或者密码错误!");
            } else if (moboleCard.getStatus().intValue() == SystemConstant.MOBOLE_STATUS_FREEZE) {//状态异常(为1)
                System.out.println("【友情提示:】该手机号码已冻结,请联系工作人员!");
            } else {
                System.out.println("【友情提示:】登陆成功!");
                return moboleCard;
            }

        }

        return null;
    }

    /**
     * 注册
     */
    public void register() {
        System.out.println("*********可选的卡号*********");
        CardDao cardDao = new CardDaoImpl();
        //查询所以可以注册的卡号
        List<Card> cards = cardDao.queryByStatus(SystemConstant.CARD_STATUS_NORMAL);
        if (cards == null) {//没有可用卡号时不可注册
            System.out.println("【友情提示:】暂时没有可用卡号,请稍后再试!");
            return;
        }
        for (int i = 0; i < cards.size(); i++) {
            System.out.print(i + 1 + "." + cards.get(i).getCardNumber() + "\t");
            if ((i + 1) % 3 == 0) {
                System.out.println();
            }
        }
        System.out.println();

        int cardsId = 0;
        do {
            System.out.print("请选择您需要办理的卡号序号:");
            cardsId = input.nextInt();
            if (cardsId <= 0 || cardsId >= cards.size()){
                System.out.println("【友情提示:】输入有误,请重新输入!");
            }

        } while (cardsId <= 0 || cardsId >= cards.size());
        String number = cards.get(cardsId - 1).getCardNumber();

        //查询所以套餐类型
        SerpackageTypeDao serpackageTypeDao = new SerpackageTypeDaoImpl();
        List<SerpackageType> serpackageTypes = serpackageTypeDao.queruAll();
        if (serpackageTypes == null) {//没有可用卡号时不可注册
            System.out.println("【友情提示:】没有套餐信息,更多套餐还在制作中。。。");
            return;
        }

        for (int i = 0; i < serpackageTypes.size(); i++) {
            System.out.print((i + 1) + "." + serpackageTypes.get(i).getName() + "\t");
        }
        System.out.println();
        System.out.print("请选择套餐:");
        int serpackageId = input.nextInt();
        SerpackageType serpackageType = serpackageTypes.get(serpackageId - 1);

        //根据选择的套餐获取详信息
        SerpackageDao serpackageDao = new SerpackageDaoImpl();
        Serpackage serpackage = serpackageDao.queryByType(serpackageId);


        //输入用户密码和姓名,还有充值金额
        System.out.print("请输入姓名:");
        String name = input.next();

        System.out.print("请输入密码:");
        String password = input.next();

        int money = 0;

        do {
            System.out.print("请输入预存话费金额:");
            money = input.nextInt();
            if (money < serpackage.getPrice()) {
                System.out.println("您预存的话费不足以支付您所选的套餐的本月资费,请重新输入!");
            }
        } while (money < serpackage.getPrice());//费用小于预存话费一种循环

        //费用大于所选套餐资费
        //修改选择的卡状态
        Card card = new Card();
        card.setCardNumber(number);
        card.setStatus(SystemConstant.CARD_STATUS_FREEZE);
        cardDao.update(card);

        //费用大于所选套餐资费
        //添加一个用户
        MoboleCard moboleCard = new MoboleCard();
        moboleCard.setCardNumber(number);
        moboleCard.setUsername(name);
        moboleCard.setPassword(password);
        moboleCard.setSerPackage(serpackageId);
        moboleCard.setMoney(money - serpackage.getPrice());
        moboleCard.setStatus(SystemConstant.MOBOLE_STATUS_NORMAL);

        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        moboleCardDao.insert(moboleCard);


        //费用大于所选套餐资费
        //添加一条充值记录
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setCardNumber(number);
        rechargeRecord.setAmount((double) money);
        rechargeRecord.setRechargeDate(new Date());

        RechargeRecordDao rechargeRecordDao = new RechargeRecordDaoImpl();
        rechargeRecordDao.rechargeByNumber(rechargeRecord);

        //

        System.out.println("您的个人信息:");
        System.out.println("用户名:" + moboleCard.getUsername() + "\t用户当前余额:" + moboleCard.getMoney());
        System.out.println("您所办理的套餐信息:");
        System.out.println("套餐名称 \t通话时长(分/月)\t短信条数(条/月)\t套餐月资费(元/月)\t上网流量(GB/月)");
        System.out.println(serpackageType.getName() + "\t\t" + serpackage.getTalkTime() + "\t\t\t\t" + serpackage.getSmsCount()
                + "\t\t\t\t" + serpackage.getPrice() + "\t\t\t" + serpackage.getFlow());

    }


    /**
     * 使用嗖嗖
     */
    public void useSoso() {
        System.out.print("请输入手机号码:");
        String number = input.next();

        //根据手机号码查用户信息
        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        MoboleCard moboleCard = moboleCardDao.queryByNumber(number);
        if (moboleCard == null) {
            System.out.println("【友情提示:】该手机号码为空号无法使用,请您注册后再使用!");
        } else if (moboleCard.getStatus() == SystemConstant.MOBOLE_STATUS_FREEZE) {
            System.out.println("【友情提示:】该手机号码已冻结,请联系工作人员!");
        } else {
            //获取随机场景信息
            SceneDao sceneDao = new SceneDaoImpl();
            List<Scene> scenes = sceneDao.queruAll();
            Random random = new Random();
            int i = random.nextInt(scenes.size());

            String type = scenes.get(i).getType();//获取随机的套餐类型
            Integer data = scenes.get(i).getData();//获取随机场景的消费数量
            String description = scenes.get(i).getDescription();//获取随机数据场景的内容

            //获取办理的套餐信息
            Integer id = moboleCard.getSerPackage();//获取当前号码办理的套餐编号
            SerpackageDao serpackageDao = new SerpackageDaoImpl();
            Serpackage serpackage = serpackageDao.queryByType(id);//所办理套餐信息


            //获取当月实际消费
            MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();
            //List<MonthlyConsumptionRecords> monthlyConsumptionRecordsList = monthlyConsumptionRecordsDao.queryByNumber(number);
            Date firstDay = DateUtil.getMonthFirst(new Date());//获取当月一号日期

            MonthlyConsumptionRecords monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(number, firstDay);//存储当月消费信息对象

            if (monthlyConsumptionRecords == null) {
                monthlyConsumptionRecords = new MonthlyConsumptionRecords();
                monthlyConsumptionRecords.setCardNumber(number);
                monthlyConsumptionRecords.setRealFlow(0);
                monthlyConsumptionRecords.setConsumAmount(0.0);
                monthlyConsumptionRecords.setRealTalkTime(0);
                monthlyConsumptionRecords.setRealSmsCount(0);
                monthlyConsumptionRecords.setConsumeDate(firstDay);
                //添加这条数据
                monthlyConsumptionRecordsDao.insert(monthlyConsumptionRecords);
                //让这条数据有id
                monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(number, firstDay);
            }

            //计算剩余随机到的消费类型免费余量
            int remainingFreeQuantity = 0;

            if (type.equals("通话")) {
                //计算的通话的余量
                remainingFreeQuantity = serpackage.getTalkTime() - monthlyConsumptionRecords.getRealTalkTime();
                monthlyConsumptionRecords.setRealTalkTime(monthlyConsumptionRecords.getRealTalkTime() + data);
            }else if (type.equals("短信")) {
                //计算的短信的余量
                remainingFreeQuantity = serpackage.getSmsCount() - monthlyConsumptionRecords.getRealSmsCount();
                monthlyConsumptionRecords.setRealSmsCount(monthlyConsumptionRecords.getRealSmsCount() + data);
            }else if (type.equals("上网")) {
                //计算的上网的余量
                remainingFreeQuantity = serpackage.getFlow() - monthlyConsumptionRecords.getRealFlow();
                monthlyConsumptionRecords.setRealFlow(monthlyConsumptionRecords.getRealFlow() + data);
            }

            //计算随机到的场景消费
            double consumption = 0.0;
            if (remainingFreeQuantity <= 0) {//没有免费余量,全额扣费
                consumption = costComputational(data, type);
            } else {
                if (remainingFreeQuantity < data) { //有费用,但费用不足超出部分扣费
                    consumption = costComputational(data - remainingFreeQuantity, type);
                }
            }

            //修改用户余额
            moboleCard.setMoney(moboleCard.getMoney() - consumption);
            moboleCardDao.update(moboleCard);

            //添加一次消费记录
            ConsuminfoDao consuminfoDao = new ConsuminfoDaoImpl();
            Consuminfo consuminfo = new Consuminfo();
            consuminfo.setCardNumber(number);
            consuminfo.setType(type);
            consuminfo.setConsumData(data);
            consuminfo.setConsumeDate(new Date());

            consuminfoDao.insert(consuminfo);


            //根据随机到的场景类型
            // 修改当月消费类型数据
            monthlyConsumptionRecordsDao.updateType(monthlyConsumptionRecords, type);
            //修改实际消费金额


            System.out.println(description);


        }

    }



    /**
     * @param number
     * @param type
     * @return 计算费用
     */
    private double costComputational(int number, String type) {
        double cost = 0;
        if (type.equals("通话")) {
            cost = number * 0.2;
        } else if (type.equals("短信")) {
            cost = number * 0.1;
        } else if (type.equals("上网")) {
            cost = number * 0.1;
        }
        return cost;
    }

    /**
     * 查询套餐信息
     * 资费说明
     *
     * @return
     */
    public boolean printSerpackage() {
        SerpackagesDao serpackageDao = new SerpackagesDaosImpl();
        Map<SerpackageType, Serpackage> serpackages = serpackageDao.querySerpackage();
        if (serpackages != null) {
            System.out.println("序号 \t套餐名称 \t通话时长(分/月)\t短信条数(条/月)\t套餐月资费(元/月)\t上网流量(GB/月)");
            serpackages.forEach((key, value) -> {
                System.out.println(key.getId() + "\t\t" + key.getName() + "\t\t" + value.getTalkTime() + "\t\t\t\t" + value.getSmsCount() + "\t\t\t\t" + value.getPrice() + "\t\t\t" + value.getFlow());
            });
            System.out.println("【友情提示:】查询成功!");
            return true;
        } else {
            System.out.println("【友情提示:】没有套餐信息,更多套餐还在制作中。。。");
            return false;
        }

    }

    /**
     * 话费充值
     * @return 添加成功
     */
    public boolean Recharge() {
        System.out.println("******话费充值******");
        System.out.print("请输入要充值的卡号:");
        String number = input.next();
        System.out.print("请输入充值金额:");
        String amount = input.next();

        //根据号码获取用户信息
        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        MoboleCard moboleCard = moboleCardDao.queryByNumber(number);
        if (moboleCard == null){
            System.out.println("【友情提示:】没有该卡号!");
            return false;
        }else if (moboleCard.getStatus().intValue() ==SystemConstant.MOBOLE_STATUS_FREEZE){
            System.out.println("【友情提示:】该手机号码已冻结无法充值,请联系工作人员!");
            return false;
        }else {

            moboleCard.setMoney(moboleCard.getMoney()+Integer.parseInt(amount));
            int i = moboleCardDao.updateByMoney(moboleCard);

            if (i == 1) {//充值成功在进行添加充值记录操作
                //创建RechargeRecord(充值记录)对象
                RechargeRecord rechargeRecord = new RechargeRecord();
                rechargeRecord.setAmount(Double.valueOf(amount));//将传入的string转为double
                rechargeRecord.setRechargeDate(new Date());
                rechargeRecord.setCardNumber(number);

                //创建dao进行添加操作
                RechargeRecordDao rechargeRecordDao = new RechargeRecordDaoImpl();
                rechargeRecordDao.rechargeByNumber(rechargeRecord);

                Double money = moboleCardDao.queryByNumber(number).getMoney();//查询修改后的余额值

                System.out.println("【友情提示:】充值成功,卡上余额:" + money + "元");
                return true;
            } else {
                System.out.println("【友情提示:】充值失败!");
                return false;
            }
        }

    }

    /**
     * 反馈功能
     */
    public int feedback() {
        if (SosoApp.number == null) {
            System.out.print("请输入电话号码:");
            SosoApp.number = input.next();//13677478866;13666557788
        }
        System.out.println("反馈信息:");
        FeedbackDao feedbackDao = new FeedbackDaoImp();
        List<Feedback> notReplied = feedbackDao.queruReplied(SosoApp.number, SystemConstant.NOT_REPLIED);
        System.out.println("未回复("+notReplied.size()+")");
        List<Feedback> replied = feedbackDao.queruReplied(SosoApp.number, SystemConstant.REPLIED);
        System.out.println("已回复("+replied.size()+")");
        System.out.println("1.查看回复\t2.反馈\t3.返回上一级");
        System.out.print("选择操作(1~3):");
        int op = input.nextInt();
        switch (op){
            case 1:
                for (int i = 0; i < replied.size(); i++) {
                    Feedback feedback = replied.get(i);
                    System.out.println("------编号:"+(i+1)+"-----------");
                    System.out.println("反馈时间:"+feedback.getFeedbackDate()+"\t反馈号码:"+feedback.getCardNumber()+"\n反馈内容:"+feedback.getFeedbackContent());
                    System.out.println("回复信息:"+feedback.getAdministratorReply());
                    System.out.println("回复人:"+feedback.getAdministratorName());
                    System.out.println("-----------------------");
                    System.out.println("下一个(输入1,其他退出查看)");
                    int op1 = input.nextInt();
                    boolean next = true;
                    while (next){
                        if (op1 == 1){
                            if (i == replied.size()-1){
                                System.out.println("【温馨提示:】没有回复了!");
                                System.out.println("-----------------------");
                                next = false;
                            }
                        }else {
                            System.out.println("【友情提示】:输入有误,请重新输入");

                            next = false;

                        }
                    }
                }
                //todo 操作管理员
                feedback();
                break;
            case 2:
                System.out.println("请输入反馈内容:");
                String reply = input.next();

                Feedback feedback = new Feedback();//new一个 Feedback(反馈信息)对象

                feedback.setCardNumber(SosoApp.number);//电话
                feedback.setFeedbackContent(reply);//反馈内容
                feedback.setFeedbackDate(new Date());//时间

                int insert = feedbackDao.insert(feedback);//添加反馈记录
                if (insert == 1){
                    System.out.println("【温馨提示】反馈成功!");
                    return insert;
                }
                feedback();
                break;
                //todo 操作管理员

            case 3:

                //todo 操作管理员
                break;
            case 4:
                //返回上级菜单
                System.out.println("【友情提示】:返回上一级菜单成功");
                break;
            default:
                System.out.println("【友情提示】:输入有误,请重新输入");
                break;
        }



        return 0;


    }




    //-------------------------二级菜单服务-------------------------------------


    /**
     * 本月账单查询
     */
    public void queryMonthBill() {
        //number = "13677478866";
        System.out.println("你的卡号是:"+ SosoApp.number);
        System.out.println("当月账单:");

        //获取当月套餐资费
        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        Integer type = moboleCardDao.queryByNumber(SosoApp.number).getSerPackage();//套餐类型
        SerpackageDao serpackageDao = new SerpackageDaoImpl();
        Double price = serpackageDao.queryByType(type).getPrice();//办理的套餐资费
        System.out.println("套餐资费:"+price);

        //获取当月额外消费
        MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();
        MonthlyConsumptionRecords monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(SosoApp.number,DateUtil.getMonthFirst(new Date()));
        Double consumAmount = monthlyConsumptionRecords.getConsumAmount();

        //计算合计消费
        System.out.println("合计消费:"+(consumAmount+price));

        //打印账户余额
        System.out.println("账户余额:"+moboleCardDao.queryByNumber(SosoApp.number).getMoney());



    }



    /**
     * 套餐余量查询
     */
    public void queryPackageBalance() {
        //number = "13652363333";

        //获取办理套餐信息
        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        Integer type = moboleCardDao.queryByNumber(SosoApp.number).getSerPackage();//套餐类型
        SerpackageDao serpackageDao = new SerpackageDaoImpl();
        Serpackage serpackage = serpackageDao.queryByType(type);
        Integer talkTime = serpackage.getTalkTime();//通话
        Integer smsCount = serpackage.getSmsCount();//短信
        Integer flow = serpackage.getFlow();//上网

        //获取当月实际用量
        MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();
        MonthlyConsumptionRecords monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(SosoApp.number,DateUtil.getMonthFirst(new Date()));
        if (monthlyConsumptionRecords == null) {
            monthlyConsumptionRecords = new MonthlyConsumptionRecords();
            monthlyConsumptionRecords.setCardNumber(SosoApp.number);
            monthlyConsumptionRecords.setRealFlow(0);
            monthlyConsumptionRecords.setConsumAmount(0.0);
            monthlyConsumptionRecords.setRealTalkTime(0);
            monthlyConsumptionRecords.setRealSmsCount(0);
            monthlyConsumptionRecords.setConsumeDate(DateUtil.getMonthFirst(new Date()));
            //添加这条数据
            monthlyConsumptionRecordsDao.insert(monthlyConsumptionRecords);
            //让这条数据有id
            monthlyConsumptionRecords = monthlyConsumptionRecordsDao.queryByNumberAndDate(SosoApp.number, DateUtil.getMonthFirst(new Date()));
        }

        Integer realTalkTime = monthlyConsumptionRecords.getRealTalkTime();//通话
        Integer realSmsCount = monthlyConsumptionRecords.getRealSmsCount();//短信
        Integer realFlow = monthlyConsumptionRecords.getRealFlow();//上网

        Integer residueTalkTime = talkTime-realTalkTime;
        Integer residuesmsCount = smsCount-realSmsCount;
        Integer residueflow = flow - realFlow;

        if (residueTalkTime >=0){
            System.out.println("通话时间:"+realTalkTime+"分钟");
        }else {
            System.out.println("通话时间:0分钟");
        }

        if (residuesmsCount >=0){
            System.out.println("短信条数:"+residuesmsCount+"条");
        }else {
            System.out.println("短信条数:0条");
        }

        if (residueflow >=0){
            String format = String.format("%.2f",  (double)residueflow / 1024);
            System.out.println("上网流量:"+format+"G");
        }else {
            System.out.println("上网流量:0G");
        }

    }



    /**
     * 打印消费详单
     */
    public void printConsumptionDetails() {
        //String number = "13677478866";
        System.out.print("请输入本年需要查询的月份(1~12):");
        String month = input.next();

        ConsuminfoDao consuminfoDao = new ConsuminfoDaoImpl();
        List<Consuminfo> consuminfoList = consuminfoDao.queryByNumber(SosoApp.number);
        List <Consuminfo>ThisMonthConsuminfo = new ArrayList();
        //ThisMonthConsuminfo = null;
        if (consuminfoList == null){
            System.out.println("【友情提示】:对不起,您还没有使用过soso快去使用把。");
        }else {
            for (int i = 0; i < consuminfoList.size(); i++) {

                Date consumeDate = consuminfoList.get(i).getConsumeDate();
                int consumeMonth = DateUtil.getMonth(consumeDate);
                if (month.equals(String.valueOf(consumeMonth))){
                    ThisMonthConsuminfo.add(consuminfoList.get(i));
                }
            }
            if (ThisMonthConsuminfo.size() > 0){
                System.out.println("序号\t\t类型\t\t数据\t\t日期");
                for (int i = 0; i < ThisMonthConsuminfo.size(); i++) {
                    System.out.println((i+1)+"\t\t"+ThisMonthConsuminfo.get(i).getType()+"\t\t"+
                            ThisMonthConsuminfo.get(i).getConsumData()+"\t\t"+ThisMonthConsuminfo.get(i).getConsumeDate());
                }
            }else {
                System.out.println("【友情提示】:对不起,不存在本卡号"+month+"月消费记录!");
            }
        }

    }

    /**
     * 套餐变更
     */
    public void packageChanges() {

        SerpackageTypeDao serpackageTypeDao = new SerpackageTypeDaoImpl();
        List<SerpackageType> serpackageTypes = serpackageTypeDao.queruAll();
        if (serpackageTypes == null) {//没有可用卡号时不可注册
            System.out.println("【友情提示:】没有套餐信息,更多套餐还在制作中。。。");
            return;
        }

        for (int i = 0; i < serpackageTypes.size(); i++) {
            System.out.print((i + 1) + "." + serpackageTypes.get(i).getName() + "\t");
        }
        System.out.println();
        Integer serpackageId = 0;


        do {
            System.out.print("请选择套餐:");
            serpackageId = input.nextInt();
            if (serpackageId <= 0 || serpackageId >= serpackageTypes.size()){
                System.out.println("【友情提示:】输入有误,请重新输入!");
            }

        } while (serpackageId <= 0 || serpackageId >= serpackageTypes.size());

        //根据选择的套餐获取详信息
        SerpackageDao serpackageDao = new SerpackageDaoImpl();
        Serpackage serpackage = serpackageDao.queryByType(serpackageId);
        Double price = serpackage.getPrice();//套餐费用


        //查询用户信息
        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        MoboleCard moboleCard = moboleCardDao.queryByNumber(SosoApp.number);
        Double money = moboleCard.getMoney();
        Integer type = moboleCard.getSerPackage();
        //serpackageId.equals(type+"")
        if (serpackageId == type){
            System.out.println("【友情提示]】:您已经是改套餐的用户,无需更换!");
        }else {
            if (money < price){
                System.out.println("【友情提示】:对不起,您的余额不足以支付新套餐本月资费,请充值后办理变更套餐业务!");
            }else {

                moboleCard.setMoney(money - price);
                moboleCardDao.updateByMoney(moboleCard);
                moboleCardDao.updatebyNumberSerPackage(SosoApp.number, serpackageId);
                System.out.println("【友情提示】:更换"+serpackageTypes.get(serpackageId-1).getName()+"成功!");
                System.out.println("套餐信息:通话时长:"+ serpackage.getTalkTime()+"分钟/月,短信条数:"+serpackage.getSmsCount()+"条/月,上网流量:"+serpackage.getFlow()+"GB/月,月租:"+serpackage.getPrice()+"元/月");
            }
        }

    }

    /**
     * 办理退网
     */
    public void logout() {
        //根据号码删除用户信息
        MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
        moboleCardDao.deleteByNumber(SosoApp.number);

        //修改电话卡表该卡状态
        Card card = new Card();
        card.setCardNumber(SosoApp.number);
        card.setStatus(SystemConstant.CARD_STATUS_NORMAL);

        CardDao cardDao = new CardDaoImpl();
        cardDao.update(card);

        List<Card> cards = cardDao.queryByStatus(SystemConstant.CARD_STATUS_NORMAL);
        long count = cards.stream().filter(str -> str.getStatus().equals(SystemConstant.CARD_STATUS_NORMAL)&str.getCardNumber().equals(SosoApp.number)).count();
        if (count == 1){
            System.out.println("用户卡号:"+SosoApp.number+"退网办理成功");
        }

    }

    /*-------------------------------------------------管理员操作------------------------------------------*/

    /**
     * 管理员登陆
     * @return
     */
    public Administrators ALogin() {
        System.out.println("***********管理员登陆***********");
        System.out.print("请输入账号:");
        String number = input.next();
        System.out.print("请输入密码:");
        String password = input.next();

        //实例化赋给接口
        //调用dao层类的方法
        AdministratorsDao administratorsDao = new AdministratorsDaoImpl();
        Administrators administrators = administratorsDao.queruByNumber(number);

        if (administrators == null) {//没有找到该账号
            System.out.println("【友情提示:】卡号或者密码错误!");

        } else {//有但密码错误
            if (!administrators.getPassword().equals(password)) {//密码错误
                System.out.println("【友情提示:】卡号或者密码错误!");

            } else {
                System.out.println("【友情提示:】登陆成功!");
                return administrators;
            }

        }
        return null;
    }

    public void viewFeedback(){
        FeedbackDao feedbackDao = new FeedbackDaoImp();
        List<Feedback> feedbackList = feedbackDao.queruAll();
        if (feedbackList.size() == 0){
            System.out.println("【温馨提示】暂时还没有未回复的反馈");
        }
        for (int i = 0; i < feedbackList.size(); i++) {

            Feedback feedback = feedbackList.get(i);
            System.out.println("------编号:"+(i+1)+"-----------");
            System.out.println("反馈时间:"+feedback.getFeedbackDate()+"\t反馈号码:"+feedback.getCardNumber()+"\n反馈内容:"+feedback.getFeedbackContent());
            System.out.println("-----------------------");
            System.out.println("是否处理(1.处理,2.跳过)");
            System.out.print("请选择:");
            int op = input.nextInt();
            boolean next = true;
            int op2 = 0;
            while (next){
                if (op == 1){

                    MoboleCardDao moboleCardDao = new MoboleCardDaoImpl();
                    MoboleCard moboleCard = moboleCardDao.queryByNumber(feedback.getCardNumber());//账户信息
                    if (moboleCard == null){
                        System.out.println("【温馨提示】非本运营商用户!");
                    }
                    SerpackageDao serpackageDao = new SerpackageDaoImpl();
                    MonthlyConsumptionRecordsDao monthlyConsumptionRecordsDao = new MonthlyConsumptionRecordsDaoImpl();
                    System.out.println("************反馈功能************");
                    System.out.println("1.查看账户信息\t2.查看账户各项消费\t3.解除冻结\t4.回复\t5.下一个\t6.退出反馈");
                    System.out.print("请选择操作:");
                    op2 = input.nextInt();
                    switch (op2){
                        case 1:
                            System.out.println("-----账户信息-----");
                            if (moboleCard != null){
                                String status = null;
                                if (moboleCard.getStatus() == SystemConstant.MOBOLE_STATUS_FREEZE){
                                    status = "冻结";
                                }else if (moboleCard.getStatus() == SystemConstant.MOBOLE_STATUS_NORMAL){
                                    status = "正常";
                                }

                                System.out.println("账户状态:"+status);
                                //System.out.println("所属套餐:"+moboleCard.getSerPackage());
                                System.out.println("账户余额:"+moboleCard.getMoney());
                            }else {
                                System.out.println("【温馨提示】非本运营商用户,没有消息!");
                            }

                            System.out.println("----------------");
                            break;
                        case 2:
                            System.out.println("-----扣费情况-----");
                            if (moboleCard != null){
                                Serpackage serpackage = serpackageDao.queryByType(moboleCard.getSerPackage());//套餐信息
                                MonthlyConsumptionRecords monthlyConsumptionRecords =
                                        monthlyConsumptionRecordsDao.queryByNumberAndDate(moboleCard.getCardNumber(), DateUtil.getMonthFirst(feedbackList.get(i).getFeedbackDate()));//实际消费

                                if (monthlyConsumptionRecords.getRealTalkTime()>serpackage.getTalkTime()){//实际消费大于套餐
                                    if (serpackage.getTalkTime() == 0){
                                        System.out.print("套餐没有免费短信条数");
                                    }else {
                                        System.out.print("套餐使用超出,");
                                    }
                                    System.out.println("通话使用扣费");
                                }else {
                                    System.out.println("通话未造成扣费");
                                }

                                if (monthlyConsumptionRecords.getRealSmsCount()>serpackage.getSmsCount()){//实际消费大于套餐
                                    if (serpackage.getTalkTime() == 0){
                                        System.out.print("套餐没有免费短信条数");
                                    }else {
                                        System.out.print("套餐使用超出,");
                                    }
                                    System.out.println("短信使用扣费");
                                }else {
                                    System.out.println("短信未造成扣费");
                                }

                                if (monthlyConsumptionRecords.getRealFlow()>serpackage.getFlow()){//实际消费大于套餐
                                    if (serpackage.getTalkTime() == 0){
                                        System.out.print("套餐没有免费上网流量,");
                                    }else {
                                        System.out.print("套餐使用超出,");
                                    }
                                    System.out.println("上网使用扣费");
                                }else {
                                    System.out.println("流量未造成扣费");
                                }
                            }else {
                                System.out.println("【温馨提示】非本运营商用户,没有信息!");
                            }
                            System.out.println("------------------");
                            break;
                        case 3:
                            if (moboleCard != null){
                                moboleCardDao.updateByNumberStatus(moboleCard.getCardNumber());//解除冻结
                            }else {
                                System.out.println("【温馨提示】非本运营商用户,无法进行该项服务!");
                            }

                            break;
                        case 4:
                            System.out.println("请输入回复内容:");
                            String reply = input.next();

                            AdministratorsDao administratorsDao = new AdministratorsDaoImpl();
                            Administrators administrators = administratorsDao.queruByNumber(SosoApp.accountName);//SosoApp.accountNumber
                            String administratorName = administrators.getName();

                            feedbackList.get(i).setAdministratorReply(reply);//讲回复内容添加到 处理的 feedback对象
                            feedbackList.get(i).setAdministratorName(administratorName);//处理管理员姓名
                            feedbackList.get(i).setState(SystemConstant.REPLIED);//回复后将反馈状态改为已回复
                            //将回复修改
                            int update = feedbackDao.update(feedbackList.get(i));
                            if (update == 1){
                                System.out.println("【温馨提示】回复成功");
                            }


                            break;
                        case 5:
                            if (i == feedbackList.size()-1){
                                System.out.println("【温馨提示:】用户反馈查看完毕");
                            }
                            next = false;
                            break;
                        case 6:
                            return;
                        default:
                            System.out.println("【友情提示】:输入有误,请重新输入");
                            break;
                    }
                }else if (op == 2){
                    if (i == feedbackList.size()-1){//最后一条
                        System.out.println("【温馨提示:】用户反馈查看完毕");
                    }
                    next = false;
                }else {
                    System.out.println("【友情提示】:输入有误,请重新输入");
                }
            }


        }
    }

    /**
     * 修改级别
     */
    public void aa(){

        AdministratorsDao administratorsDao = new AdministratorsDaoImpl();

        Administrators administrators1 = new Administrators();
        List<Administrators> administratorsList = administratorsDao.queruAll();
        int sum = 0;
        for (int i = 0; i < administratorsList.size(); i++) {
            /*if (administratorsList.get(i).getLevels() == SystemConstant.FIRST_LEVEL_ADMINISTRATOR){
                continue;
            }*/
            //System.out.println(administratorsList.get(i));
            System.out.println((++sum)+"."+administratorsList.get(i).getName()+" 等级:"+administratorsList.get(i).getLevels());
        }

        System.out.print("请选择需要修改的人:");
        int  name= input.nextInt();
        System.out.print("请选择需要的等级:");
        int  levels= input.nextInt();
        sum = 0;
        for (int i = 0; i < administratorsList.size(); i++) {
            sum++;
            if (sum == name){//确定修改的人的名字
                administrators1.setName(administratorsList.get(i).getName());
                administrators1.setLevels(levels);
            }
        }
        administratorsDao.update(administrators1);
        System.out.println("【温馨提示】修改成功!");

    }


    /**
     * 添加管理员
     */
    public void bb(){
        AdministratorsDao administratorsDao = new AdministratorsDaoImpl();
        System.out.println("请输入名字:");
        String name = input.next();
        System.out.println("请输入账号:");
        String accountNumber = input.next();
        System.out.println("请输入密码:");
        String password = input.next();
        System.out.println("请输入等级:");
        int level = input.nextInt();

        Administrators administrators = new Administrators();
        administrators.setName(name);
        administrators.setAccountNumber(accountNumber);
        administrators.setPassword(password);
        administrators.setLevels(level);

        int insert = administratorsDao.insert(administrators);
        System.out.println("【温馨提示】添加成功!");
    }

    /**
     * 删除管理员
     */
    public void cc(){
        AdministratorsDao administratorsDao = new AdministratorsDaoImpl();
        List<Administrators> administrators = administratorsDao.queruAll();
        int sum = 1;
        for (int i = 0; i < administrators.size(); i++) {
            if (administrators.get(i).getLevels().equals(SystemConstant.FIRST_LEVEL_ADMINISTRATOR)){
                continue;
            }

            System.out.println((sum++)+"."+administrators.get(i).getName());
        }
        System.out.print("请选择需要删除的人:");
        int i = input.nextInt();
        //int update = administratorsDao.deleteById(sum);

        System.out.println("【温馨提示】删除成功!");

    }



}
3、菜单类(ui包)
package com.lx.soso.ui;

import com.lx.soso.constant.SystemConstant;
import com.lx.soso.entity.Administrators;
import com.lx.soso.entity.MoboleCard;
import com.lx.soso.service.SoSoService;

import java.util.Scanner;


public class SosoApp {
    Scanner input = new Scanner(System.in);
    //号码
    public static String number = null;
    //管理员账号
    public static String accountName = null;
    //
    public static String name = null;
    //管理员等级
    Integer levels = 2;

    private SoSoService soSoService = new SoSoService();

    public static void main(String[] args) {

        new SosoApp().showFirstMenu();
    }

    /**
     * 显示一级菜单
     */
    public void showFirstMenu(){
        System.out.println("****************************欢迎使用嗖嗖移动业务大厅****************************");
        System.out.println("1.用户登录\t2.用户注册\t3.使用嗖嗖\t4.话费充值\t5.资费说明\t6.反馈\t7.退出系统\t8.管理员登陆");
        System.out.print("请选择(1~8)功能:");
        String  choose = input.next();

        switch (choose){
            case "1":
                MoboleCard moboleCard = soSoService.login();
                if (moboleCard == null){
                    showFirstMenu();
                }
                number = moboleCard.getCardNumber();
                showSecondMenu();

                break;
            case "2":
                soSoService.register();//用户注册
                showFirstMenu();
                break;
            case "3":
                soSoService.useSoso();//使用嗖嗖
                showFirstMenu();
                break;
            case "4":
                soSoService.Recharge();//话费充值
                showFirstMenu();
                break;
            case "5":
                soSoService.printSerpackage();//资费说明
                showFirstMenu();
                break;
            case "6":
                soSoService.feedback();//反馈
                showFirstMenu();
                break;
            case "7":
                System.out.println("欢迎使用本系统~~~");
                System.out.println("系统正在退出....");
                System.exit(0);
                break;
            case "8":
                Administrators administrators = soSoService.ALogin();//管理员登陆
                if (administrators == null){
                    showFirstMenu();
                }
                accountName = administrators.getAccountNumber();
                levels = administrators.getLevels();
                name = administrators.getName();
                administratorsMenu();
                break;
            default:
                System.out.println("【友情提示】:输入有误,请重新输入");
                showFirstMenu();
                break;
        }
    }


    /**
     * 显示二级菜单
     */
    public void showSecondMenu(){
        System.out.println("****************************嗖嗖移动用户菜单****************************");
        System.out.println("1.本月账单查询\t2.套餐余量查询\t3.打印消费详单\t4.套餐变更\t5.反馈\t6.办理退网\t7.返回上一级");
        System.out.print("请选择(1~6)功能:");
        String  choose = input.next();
        switch (choose){
            case "1":
                soSoService.queryMonthBill();//本月账单查询
                showSecondMenu();
                break;
            case "2":
                soSoService.queryPackageBalance();//套餐余量查询
                showSecondMenu();
                break;
            case "3":
                soSoService.printConsumptionDetails();//打印消费详单
                showSecondMenu();
                break;
            case "4":
                soSoService.packageChanges();//套餐变更
                showSecondMenu();
                break;
            case "5":
                soSoService.feedback();
                showSecondMenu();
                // 反馈 反馈表:反馈号码、反馈内容、回复
                break;
            case "6":
                soSoService.logout();// 办理退网
                showFirstMenu();
                break;
            case "7":
                //返回上级菜单
                showFirstMenu();
                System.out.println("【友情提示】:返回上一级菜单成功");
                break;
            default:
                System.out.println("【友情提示】:输入有误,请重新输入");
                showSecondMenu();
                break;
        }
    }


    /**
     * 一级管理员菜单
     */
    public void administratorsMenu(){
        String levelStr = null;
        String op = null;
        int ops = 2;
        if (levels == SystemConstant.FIRST_LEVEL_ADMINISTRATOR){
            levelStr = "一级";
            op = "\n3.操作管理员";
            ops+=1;
        }else {
            levelStr = "二级";
        }
        System.out.println("****************************"+levelStr+"管理员:"+name+"****************************");
        System.out.println("1.查看反馈\n2.返回上一级"+op);
        System.out.print("请选择(1~"+ops+")功能:");
        String  choose = input.next();
        switch (choose){
            case "1":
                soSoService.viewFeedback();
                administratorsMenu();
                break;

            case "2":
                //返回上级菜单
                showFirstMenu();
                System.out.println("【友情提示】:返回上一级菜单成功");
                break;
            case "3":

                if (levels == SystemConstant.FIRST_LEVEL_ADMINISTRATOR){
                    fist();
                }else {
                    System.out.println("【友情提示】:输入有误,请重新输入");
                    administratorsMenu();
                }
                break;
            default:
                System.out.println("【友情提示】:输入有误,请重新输入");
                administratorsMenu();
                break;
        }
    }

    public void fist(){
        System.out.println("*******************************************************");
        System.out.println("1.修改级别\t2.添加管理员\t3.删除管理员\t4.返回上一级");
        System.out.print("选择操作:");
        int op3 = input.nextInt();
        switch (op3){
            case 1:
                soSoService.aa();
                //todo 操作管理员
                fist();
                break;
            case 2:
                soSoService.bb();
                fist();
                //todo 操作管理员
                break;
            case 3:
                soSoService.cc();
                fist();
                //todo 操作管理员
                break;
            case 4:
                //返回上级菜单
                System.out.println("【友情提示】:返回上一级菜单成功");
                administratorsMenu();

                break;
            default:
                System.out.println("【友情提示】:输入有误,请重新输入");
                fist();
                break;
        }
    }
}
4、工具类(util包)
        4.1JDBC连接数据库
package com.lx.soso.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


public class DateUtil {

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy-MM-dd");
    //Date date = new Date(System.currentTimeMillis());//获取当前时间戳

    /**
     * 将时间转化为规定的格式(yyyy-MM-dd HH:mm:ss格式字符串)
     * @param date
     * @return
     */
    public static String  formatDate(Date date){
        return sdf.format(date);

    }

    public static String  yearFormatDate(Date date){
        return yearSdf.format(date);

    }
    //根据时间获取这个时间的当月1号日期
    public static Date getMonthFirst(Date date){
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.set(Calendar.DATE,1);
        Date time = ca.getTime();
        return time;

    }

    public static int getMonth(Date date){
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        int i = ca.get(Calendar.MONTH);
        return i+1;
    }





}
        4.2时间格式化
package com.lx.soso.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * @author lx
 * @version 1.0
 * @title JDBCUtil
 * @description
 * @create 2024/1/8 9:48
 */

public class JDBCUtil {
    static Properties props = new Properties();
    static{
        // 包裹选中的代码, ctrl + alt + T
        try {
            InputStream in = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
            props.load(in);
            Class.forName(props.getProperty("jdbc.driver"));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     * @return
     */
    public static Connection getConnection() throws SQLException {
        return  DriverManager.getConnection(props.getProperty("jdbc.url"),props.getProperty("jdbc.username"),props.getProperty("jdbc.password"));
    }


    public static void close(Connection conn, Statement statement, ResultSet resultSet){
        //6.关闭资源 倒序关  先开的后关, 后开的先关
        try {
            if(resultSet!=null){
                resultSet.close();
            }
            if(statement!=null){
                statement.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

四、部分功能展示

登陆

注册

使用soso

 

话费充值   资费说明

 

本月账单查询 套餐余量查询

 

打印消费详单

 

用户反馈

 

查看回复

 

管理员回复

 

五、分析总结

1、Java基础

项目中用到了java中的属性,方法,集合,接口,随机数,if语句,switch语句,while循环等,涉及到的知识面相当广泛巩固了之前的Java基础。

2、数据库

其中涉及到了数据库的知识,包括基础的增删查改sql语句的编写。还有JDBC操作数据库。这其实是这个项目的重点

3、项目结构

Java Dao模式的运用(将数据库操作封装):一个实体类对应一个Dao接口和Dao实现类

共同属性、方法进行封装:实体类的idDao接口的增删改查方法

工具类的编写:JDBCUtilDateUtil

4、IDEA Debug使用

由于项目代码量比较多功能模块较多,在程序编码中容易出bug,尤其NullPointerException

出现颇多,这时Debug可以帮我们节省大量时间,当然在日常编写也应该注意防止bug的出现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1390901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch入门篇

目录 一、 ElasticSearch的定位 二、 什么是倒排索引 三、 什么是全文检索 四、 ElasticSearch的数据存储原理 4.1 ElasticSearch与关系型数据库的数据结构对比 4.2 ElasticSearch的倒排索引原理 一、 ElasticSearch的定位 ElasticSearch是一款开源的分布式 搜索和…

【Linux终端工具】Tmux的使用教程,如何正确使用Tmux

文章目录 入门tmux什么是tmux&#xff1f;安装tmux快速启动tmux基本操作入门1. 分离与退出2. 帮助信息3. 新建会话4. 重新接入会话5. 窗格操作 进阶操作1. 会话管理2. 切换窗口3. 窗格间切换 总结 入门tmux 什么是tmux&#xff1f; tmux是一款终端复用器&#xff0c;它允许你…

一、ArcGIS Pro SDK for Microsoft .NET 开发环境配置

ArcGIS Pro二次开发需要的工具&#xff1a; 1.Visual Studio 2.ArcGIS Pro SDK 一、Visual Studio安装 经过查阅资料&#xff0c;ArcGIS Pro3.0版本需要安装Visual Studio2022版&#xff0c;因为只有22版的才会有有ArcGIS Pro3.0以上版对应ArcGIS Pro SDK&#xff0c;因此&…

MySQL核心SQL

一.结构化查询语言 SQL是结构化查询语言&#xff08;Structure Query Language&#xff09;&#xff0c;它是关系型数据库的通用语言。 SQL 主要可以划分为以下 3 个类别&#xff1a; DDL&#xff08;Data Definition Languages&#xff09;语句 数据定义语言&#xff0c;这…

通过Canal实现缓存同步

文章目录 1.数据同步策略2.初始Canal3.安装Canal4.监听Canal 1.数据同步策略 2.初始Canal 3.安装Canal 见文章安装Canal详情 4.监听Canal

【Web】websocket应用的是哪个协议

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Web ⛳️ 功不唐捐&#xff0c;玉汝于成 前言 在当今互联网时代&#xff0c;实时性和即时通讯成为网络应用日益重要的一部分。WebSocket 协议作为一种创新性的通信协议&#xff0c;极大地改善了…

网页设计(八)HTML5基础与CSS3应用

一、当当网企业用户注册页面设计 当当网企业用户注册页面 改版后当当网企业用户注册页面 <!-- prj_8_1.html --> <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>当当网企业用户注册页面设计</title><s…

圈小猫游戏HTML源码

源码介绍 圈小猫游戏html源码&#xff0c;HTMLCSSJS,记事本可以打开修改内容&#xff0c;电脑本地双击index.html即可运行&#xff0c;也可以上传到服务器上面运行&#xff0c;喜欢的同学可以拿去使用 下载地址 蓝奏云&#xff1a;https://wfr.lanzout.com/iFkVc1lb5akj CS…

【MATLAB源码-第113期】基于matlab的孔雀优化算法(POA)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 POA&#xff08;孔雀优化算法&#xff09;是一种基于孔雀羽毛开屏行为启发的优化算法。这种算法模仿孔雀通过展开其色彩斑斓的尾羽来吸引雌性的自然行为。在算法中&#xff0c;每个孔雀代表一个潜在的解决方案&#xff0c;而…

NFS(Network File System 网络文件服务)

一&#xff0c;nfs 简介 1&#xff0c;nfs 性质 NFS&#xff08;Network File System 网络文件服务&#xff09; 文件系统&#xff08;软件&#xff09;文件的权限 NFS 是一种基于 TCP/IP 传输的网络文件系统协议 通过使用 NFS 协议&#xff0c;客户机可以像访问本地目录一样…

找不到msvcr100.dll怎么办?msvcr100.dll丢失的解决方法

在面对计算机系统中“msvcr100.dll”文件缺失这一常见问题时&#xff0c;用户可能会遇到应用程序无法正常启动或运行的情况。为了解决这一困扰广大用户的难题&#xff0c;本文将详细介绍并解析找不到“msvcr100.dll”文件的5种有效解决方法。 一、了解一下msvcr100.dll是什么&a…

[论文精读]Few-shot domain-adaptive anomaly detection for cross-site brain images

论文网址&#xff1a;Few-shot domain-adaptive anomaly detection for cross-site brain images | IEEE Journals & Magazine | IEEE Xplore 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有…

怎么修改或移除WordPress后台仪表盘概览底部的版权信息和主题信息?

前面跟大家分享『WordPress怎么把后台左上角的logo和评论图标移除&#xff1f;』和『WordPress后台底部版权信息“感谢使用 WordPress 进行创作”和版本号怎么修改或删除&#xff1f;』&#xff0c;其实在WordPress后台仪表盘的“概览”底部还有一个WordPress版权信息和所使用的…

鸿蒙入门实战-ArkTS开发

声明式UI基本概念 应用界面是由一个个页面组成&#xff0c;ArkTS是由ArkUI框架提供&#xff0c;用于以声明式开发范式开发界面的语言。 声明式UI构建页面的过程&#xff0c;其实是组合组件的过程&#xff0c;声明式UI的思想&#xff0c;主要体现在两个方面&#xff1a; 描述…

Simulink简介

Simulink 是一个模块图环境&#xff0c;用于多域仿真以及基于模型的设计。它支持系统级设计、仿真、自动代码生成以及嵌入式系统的连续测试和验证。Simulink 提供图形编辑器、可自定义的模块库以及求解器&#xff0c;能够进行动态系统建模和仿真。Simulink 与 MATLAB 相集成&am…

EChars

1.引入 Apache ECharts <!DOCTYPE html> <html><head><meta charset"utf-8" /><!-- 引入刚刚下载的 ECharts 文件 --><script src"echarts.js"></script></head> </html> 2. <!-- 为 ECharts 准…

浅谈电动汽车充电站箱变电气安全物联监测系统设计与应用

摘 要:基于物联网技术架构提出了一种适用于电动汽车充电站箱变的电气安全物联监测系统设计方案。该系统由电气安全智能感知设备、通信网关、电气安全物联网监测平台等构成&#xff0c;可支持充电站箱变充电桩出线回路电流、电缆 温度、剩余电流、故障电弧、短路电流等数据采集监…

zabbix其他配置

自动发现 zabbix server 主动的去发现所有的客户端&#xff0c;然后将客户端的信息登记在服务端上。 缺点是如果定义的网段中的主机数量多&#xff0c;zabbix server 登记耗时较久&#xff0c;且压力会较大。 systemctl disable --now firewalld setenforce 0 hostnamectl se…

C++I/O流——(4)格式化输入/输出(第一节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

搜维尔科技:SenseGlove Nova 2力反馈技术手套,虚拟培训的沉浸感达到新高度!

SenseGlove Nova 2-虚拟培训的沉浸感达到新高度&#xff01; 通过集成主动接触反馈&#xff0c;Nova 2 使用户能够在手掌中感知虚拟现实物体的感觉。虚拟训练、研究和多人互动现在感觉比以往更加自然。这项创新增强了与整个手掌接触的任何虚拟物体的真实感。使用第一款也是唯一…