1、概述
本章通过JDBC三层架构实现"简易版移动业务大厅",提供了移动用户的常用功能,包括新用户注册、本月账单查询、打印消费详情、套餐变更、办理退网、话费充值、查看消费记录、查看套餐说明等功能。另外,还可以模拟用户通话、上网、发送短信的场景进行相应的扣费并记录消费信息。各功能介绍如下表:
菜单级别 | 功能 | 描述 |
---|---|---|
主菜单 | 用户登录 | 输入正确的手机号码和密码进入二级菜单列表 |
主菜单 | 用户注册 | 录入信息并开卡,用户输入的信息包括:选择卡号,选择套餐类型,输入用户名和密码,预存话费金额(预存话费金额必须满足以支付所选套餐的一个月的费用) |
主菜单 | 使用嗖嗖 | 输入正确的手机号码和密码之后,随机进入本号码所属套餐可以支持的一个场景,消费套餐余量或者话费余额,并记录消费信息.当话费余额不足时,抛出异常提醒用户充值 |
主菜单 | 话费充值 | 输入正确的用户名和密码之后,可为该卡号充值 |
主菜单 | 资费说明 | 提供各品牌套餐所包含的通话时长,上网流量,短信条数,月费用等 |
主菜单 | 退出系统 | 提出本系统 |
二级菜单 | 本月账单查询 | 可查询该卡号的套餐费用,实际消费金额,账户余额 |
二级菜单 | 套餐余量查询 | 可查询该卡号的套餐余量 |
二级菜单 | 打印消费详情 | 输入正确的卡号和密码后,可打印当前卡号用户的消费详单, 使用输出流把用户信息输出到文件 |
二级菜单 | 套餐变更 | 可变更为其他套餐类型,变更后话费余额需减去变更后的套餐费用,余额不足时需要给出信息提示,套餐变更后重新统计卡中实际消费数据以及当月消费金额 |
二级菜单 | 办理退网 | 输入正确的卡号和密码后,可以从已注册的号码列表中删除本号码,并退出系统 |
2、使用的技术
-
面向对象的思想
-
封装,继承,多态,接口的使用
-
异常处理的合理使用
-
集合框架的使用
-
I/O 操作实现对文件的写
-
MySQL数据
-
JDBC操作数据库
3、关键功能代码以及效果图
1、一级菜单
/** * 显示一级菜单 */ public void showFirstMenu() { System.out.println("==========欢迎使用嗖嗖移动业务大厅=========="); System.out.print("1.用户登录 "); System.out.print("2.用户注册 "); System.out.print("3.使用嗖嗖 "); System.out.print("4.话费充值 "); System.out.print("5.资费说明 "); System.out.println("6.退出系统 "); System.out.println("请选择:"); int choose = input.nextInt(); switch (choose) { case 1: Login();//用户登录 break; case 2: Register();//用户注册 break; case 3: useSoSo();//使用嗖嗖 break; case 4: topUp();//话费充值 break; case 5: costInfo();//资费说明 break; case 6: quit();//退出系统 break; default: System.out.println("输入有误!请重新输入!"); showFirstMenu(); break; } }
效果图:
2、登录功能
/** * 登录 */ private void Login() { System.out.print("请输入卡号:"); String cardNumber = input.next(); System.out.print("请输入密码:"); String password = input.next(); MoboleCardDao moboleCardDao = new MoboleCardDaoImpl(); try { currentLoginCard = moboleCardDao.login(cardNumber, password); CardDao cardDao = new CardDaoImpl(); // 根据卡号查询 Card 信息 currentLoginCard2 = cardDao.queryBycardNumber(cardNumber); System.out.println("登录成功!"); //登录成功,进入到二级菜单 showSecondMenu(); } catch (CardOrPasswordNotExitException | StatusDisableException e) { //登录失败 System.out.println("【友情提示:】" + e.getMessage()); //返回一级菜单 showFirstMenu(); } }
3、注册功能
/** * 注册 */ private void Register() { //查询所有可选的卡号 CardDao cardDao = new CardDaoImpl(); List<Card> cards = cardDao.queryAll(); System.out.println("=======可选的卡号======="); 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(); } } //2. 用户选择卡号 System.out.print("\n请选择卡号(输入序号):"); int cardIndex = input.nextInt(); //已选的卡号 String cardNumber = cards.get(cardIndex - 1).getCardNumber(); //套餐查询 System.out.println("套餐说明: 通话时长\t短信条数\t上网流量\t套餐月资费"); SerpackageDao serpackageDao=new SerpackageDaoImpl(); List<Serpackage> serpackages=serpackageDao.queryAll(); for (Serpackage serpackage:serpackages){ System.out.println(serpackage); } //3. 查询所有的套餐类型,并展示,用户选择套餐 SerpackageTypeDao serpackageTypeDao = new SerpackageTypeDaoImpl(); List<SerpackageType> serpackageTypes = serpackageTypeDao.queryAll(); for (int i = 0; i < serpackageTypes.size(); i++) { System.out.print((i + 1) + "." + serpackageTypes.get(i).getName() + "\t"); } System.out.print(",请选择套餐(输入序号):"); int typeIndex = input.nextInt(); //4. 用户输入姓名,密码, 以及预存的金额 System.out.println("请输入姓名:"); String name = input.next(); System.out.println("请输入密码:"); String password = input.next(); System.out.println("请输入预存话费金额:"); double money = input.nextDouble(); //5. 根据套餐类型查询对应用户选择的套餐, 并判断用户预存金额是否满足支付 // SerpackageDao serpackageDao = new SerpackageDaoImpl(); //根据套餐类型查询套餐 typeIndex序号 从1开始 //所选的套餐类型id int type = serpackageTypes.get(typeIndex - 1).getId(); Serpackage serpackage = serpackageDao.queryByType(type); do { //余额 double cost = money - serpackage.getPrice(); if (cost >= 0) { //满足 //8. 往tb_mobole_card表添加一条记录 MoboleCardDao moboleCardDao = new MoboleCardDaoImpl(); MoboleCard moboleCard = new MoboleCard(); moboleCard.setCardNumber(cardNumber); moboleCard.setUsername(name); moboleCard.setPassword(password); moboleCard.setSerPackage(type); moboleCard.setMoney(cost); moboleCardDao.insert(moboleCard); //9. 往tb_recharge_record表添加一条充值记录 RechargeRecordDao rechargeRecordDao = new RechargeRecordDaoImpl(); RechargeRecord rechargeRecord = new RechargeRecord(); rechargeRecord.setCardNumber(cardNumber); rechargeRecord.setAmount(money); rechargeRecord.setRechargeDate(new Date()); rechargeRecordDao.insert(rechargeRecord); //10. 修改tb_card对应cardNumber的卡的状态 Card card = cards.get(cardIndex - 1); card.setStatus(1); cardDao.update(card); //11. 办理成功,打印卡信息以及套餐信息 System.out.println("注册成功!卡号:" + cardNumber + ",用户名:" + name + "当前余额:" + cost); System.out.println(serpackageTypes.get(typeIndex - 1).getName() + ":" + "通话时长:" + serpackage.getTalkTime() + "分钟/月,短信条数为" + serpackage.getSmsCount() + "条/月" + "上网流量:" + serpackage.getFlow() + "MB/月。" ); break; } else {//不满足: System.out.println("您预存的话费不足以支付本月套餐资费,请重新充值:"); money = input.nextDouble(); } } while (true); //返回到一级菜单 showFirstMenu(); }
效果图:
4、话费充值
/** * 话费充值 */ private void topUp() { System.out.println("请输入需要充值的电话号码"); String cardNumber=input.next(); MoboleCardDao moboleCardDao=new MoboleCardDaoImpl(); MoboleCard moboleCard = moboleCardDao.queryByCardNumber(cardNumber); if (moboleCard == null) { //卡不存在 System.out.println("【友情提示】:该卡号" + cardNumber + "不存在"); showFirstMenu(); } else if (moboleCard.getStatus() == 1) {//被禁用 System.out.println("【友情提示】:该卡号" + cardNumber + "已被禁用"); showFirstMenu(); } else { System.out.println("请输入充值的金额:"); Double money=input.nextDouble(); moboleCard.setMoney(moboleCard.getMoney()+money); moboleCardDao.update2(moboleCard); System.out.println("充值完成!"); showFirstMenu(); } }
5、资费说明
/** * 费用说明 */ private void costInfo() { System.out.println("套餐说明: 通话时长\t短信条数\t上网流量\t套餐月资费"); SerpackageDao serpackageDao=new SerpackageDaoImpl(); List<Serpackage> serpackages=serpackageDao.queryAll(); for (Serpackage serpackage:serpackages){ System.out.println(serpackage); } showFirstMenu(); }
6、退出系统
/** * 退出系统 */ private void quit() { System.out.println("确认退出营业厅吗?是/否"); String exit=input.next(); if (exit.equals("是")){ System.out.println("您已退出系统,欢迎下次使用!"); }else if (exit.equals("否")){ showFirstMenu(); }else { System.out.println("输入有误,请重新输入"); quit(); } }
4、Dao层主要代码
public interface CardDao extends BaseDao<Card> { public Card queryBycardNumber(String cardNumber); } import com.fs.soso.dao.CardDao; import com.fs.soso.module.Card; import com.fs.soso.util.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class CardDaoImpl implements CardDao { @Override public Card queryBycardNumber(String cardNumber) { Connection connection = null; PreparedStatement pstm = null; ResultSet resultSet = null; Card card = null; List<Card> empList = new ArrayList<>(); try { connection = JDBCUtil.getConnection(); String sql = "select * from tb_card where cardNumber=?"; pstm = connection.prepareStatement(sql); pstm.setString(1, cardNumber); resultSet = pstm.executeQuery(); while (resultSet.next()) { card = new Card( resultSet.getInt("id"), resultSet.getString("cardNumber"), resultSet.getInt("status")); } empList.add(card); } catch (SQLException e) { e.printStackTrace(); } finally { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } JDBCUtil.close(null, pstm, connection); } return card; } @Override public Card queryById(Integer id) { return null; } @Override public int insert(Card record) { return 0; } @Override public int deleteById(Integer id) { return 0; } @Override public int update(Card record) { String sql="UPDATE tb_card SET cardNumber=?,STATUS=? WHERE id = ? "; return JDBCUtil.executeUpdate(sql,record.getCardNumber(),record.getStatus() ,record.getId()); } public int update2(Card record){ String sql="UPDATE tb_card SET cardNumber=?,STATUS=? WHERE id = ? "; return JDBCUtil.executeUpdate(sql,record.getCardNumber(),record.getStatus() ,record.getId()); } @Override public List<Card> queryAll() { String sql ="SELECT * FROM tb_card WHERE STATUS = 0"; return JDBCUtil.executeQuery(sql,Card.class); } }
import com.fs.soso.exception.CardOrPasswordNotExitException; import com.fs.soso.exception.StatusDisableException; import com.fs.soso.module.MoboleCard; public interface MoboleCardDao extends BaseDao<MoboleCard> { /** * 登录 * @param cardNumber * @param password */ MoboleCard login(String cardNumber, String password) throws CardOrPasswordNotExitException, StatusDisableException; /** * 根据卡号查询卡的信息 * @param cardNumber * @return */ MoboleCard queryByCardNumber(String cardNumber); public int delete(String cardNumber); public int update2(MoboleCard moboleCard); }
import com.fs.soso.dao.MoboleCardDao; import com.fs.soso.exception.CardOrPasswordNotExitException; import com.fs.soso.exception.StatusDisableException; import com.fs.soso.module.MoboleCard; import com.fs.soso.util.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; public class MoboleCardDaoImpl implements MoboleCardDao { @Override public MoboleCard login(String cardNumber, String password) throws CardOrPasswordNotExitException, StatusDisableException { String sql ="select id,card_number cardNumber,username,password, ser_package serPackage,money,status from tb_mobole_card where card_number = ? and password = ?"; List<MoboleCard> moboleCards = JDBCUtil.executeQuery(sql, MoboleCard.class, cardNumber, password); //没有查询到记录 if(moboleCards == null || moboleCards.isEmpty()){ throw new CardOrPasswordNotExitException("卡号或者密码错误!"); }else{ MoboleCard moboleCard = moboleCards.get(0); if(moboleCard.getStatus() == 1){ throw new StatusDisableException("该卡已被禁用!"); } } //返回登录成功的卡号信息对象 return moboleCards.get(0); } @Override public MoboleCard queryByCardNumber(String cardNumber) { String sql ="select id,card_number cardNumber,username,password, ser_package serPackage,money,status from tb_mobole_card" + " where card_number = ?"; List<MoboleCard> moboleCards = JDBCUtil.executeQuery(sql, MoboleCard.class, cardNumber); return moboleCards == null || moboleCards.isEmpty()?null:moboleCards.get(0); } @Override public MoboleCard queryById(Integer id) { return null; } @Override public int insert(MoboleCard record) { String sql="INSERT INTO tb_mobole_card(\n" + " card_number,\n" + " username,\n" + " PASSWORD,\n" + " ser_package,\n" + " money\n" + ") \n" + "VALUES(?,?,?,?,?)"; return JDBCUtil.executeUpdate(sql,record.getCardNumber(), record.getUsername(),record.getPassword(), record.getSerPackage(),record.getMoney()); } @Override public int deleteById(Integer id) { return 0; } @Override public int delete(String cardNumber) { int count=0; Connection connection =null; PreparedStatement prep =null; try { connection = JDBCUtil.getConnection(); String sql="delete from tb_mobole_card where card_number=?"; prep = connection.prepareStatement(sql); prep.setString(1,cardNumber); count = prep.executeUpdate(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JDBCUtil.close(null, prep, connection); } return count; } //充值 @Override public int update2(MoboleCard moboleCard) { Connection connection =null; int count=0; PreparedStatement prep = null; try { connection =JDBCUtil.getConnection(); //? 占位符 String sql="update tb_mobole_card set money=? where card_number=?"; //预编译执行对象 prep = connection.prepareStatement(sql); prep.setDouble(1,moboleCard.getMoney()); prep.setString(2, moboleCard.getCardNumber()); count = prep.executeUpdate(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JDBCUtil.close(null,prep,connection); } return count; } @Override public int update(MoboleCard record) { String sql = "UPDATE tb_mobole_card SET card_number = ?, username=?,PASSWORD=?,ser_package=?,money=?,status = ? WHERE id = ?"; return JDBCUtil.executeUpdate(sql,record.getCardNumber(),record.getUsername(),record.getPassword() ,record.getSerPackage(),record.getMoney(),record.getStatus(),record.getId()); } @Override public List<MoboleCard> queryAll() { return null; } }
注意:这些只是部分代码