本论文主要是对卡拉OK点歌系统的设计过程,后端设计,前端设计,数据库设计的分析。结合软件工程已经数据库系统概论所学知识,详细内容是系统的实现背景,设计过程,功能的实现以及部分的个人感悟。

前言:需要一定的java基础,数据库基础,如何实现图形化界面等,请自行了解整体框架结构,java如何进行数据库的连接等,仅作参考,直接抄估计是运行不了的,运行截图上传不了

其中系统界面的实现部分非常简略,部分功能重复,请酌情参考

目 录

一:绪论 1

1.1 选题介绍 1

1. 2 技术介绍                                                              1

二、需求分析 2

2.1 普通用户 2

2.2 信息需求                                                                     2

2.3 功能分析 2

三、概要分析 3

3.1 数据库设计                                                                   4

3.1.1 E-R图 5

3.2 系统设计                                                                     6

3.2.1系统项目目录 6

3.2.2 分层结构 7

3.2.3 系统功能用例图 8

四:详细设计 9

4.1 数据库设计 9

4.1.1 表格信息 9

4.1.2 表格结构 9

4.2 系统设计 10

4.2.1 MVC架构实现 10

4.2.2 图形化界面 11

五、系统的实现 15

5.1 主要开发技术 16

5.2 开发环境 16

5.3 业务核心模块实现 16

六、回顾与展望 29

致谢 30

__附. 参考文献 31

1  绪 论

1.1选题介绍

我的选题是卡拉OK点歌系统,该系统与现实生活中的KTV点歌,网络上的音乐播放器息息相关。只有拥有账号的用户才能登入系统,对数据库进行操作,和现实生活中的卡拉OK点歌机功能贴近,登入系统后,可以根据歌曲名,歌曲类型,歌手等信息进行检索,找到想要的信息,通过点歌生成账单,结账完成账单,

本系统进行了前后端分离,用户可以通过简单的图形化界面操作数据库,前端主要是图形化接麦你的设计开发以及数据传递,后端则是数据传递,业务功能实现等。

 1.2技术介绍

  1. 前端

调用包:Javax.swing.*

  1. 后端

项目构建:jdk1.8

加密:MD5

  1. 数据库

MySQL8.0.26

2 需求分析

2.1普通用户

登录系统、机器状态管理,歌曲列表管理、歌手列表管理、账单列表管理、结账功能

2.2信息需求

  1. 登录信息:登录编号,登录人名,登录账号,登录密码
  2. 歌曲信息:歌曲编号,歌曲名,歌手名,歌曲类型,单曲价格
  3. 歌手信息:歌手名
  4. 账单信息:账单编号,歌曲名,点歌数目,总金额,点歌日期,支付方式
  5. 机器信息:机器编号,机器状态,预定机器人姓名,预定人电话

2.3功能分析

1、登录系统

根据用户输入的用户名和密码,进行方法调用,判定是否为数据库中的用户

若是则可登入系统,进行后续操

2、显示机器状态

对于机器信息表的查询

3、预定机器

根据用户输入的机器编号,预订人,预定电话,对机器信息表进行更新操作

4、显示所有歌曲

对歌曲信息表进行遍历查询操作

5、显示所有歌手

对歌手信息表进行遍历查询操作

6、选择要唱的歌曲(点单)

根据用户输入的机器编号,所点曲目,所点数量,对账单表进行更新操作,添加新数据

7、查看所点歌曲(账单)

对账单进行遍历查询操作

8、结账

根据用户输入的机器编码,判断是否需要进行结账操作,更新账单表,删除对应的账单数据

9、退出系统

3 概要设计

将java程序分层分为界面层,DAO层,domain层,Service层分析并画出对应的分层结构根据需求定义合适的方法建立合理的符合要求的数据库根据建立的数据库完成ER图的编绘通过JDBCUtils方法进行数据库和java项目的连接,目的:直接通过编写java项目调用数据库语句,完成增删查改功能。

3.1数据库设计

数据表

  1. 登录表:user(id(登录编号),name(登录人名),userId(登录账号),pwd(登录密码)
  2. 歌曲表:songs(id(歌曲编号),songName(歌曲名),singerName(歌手名),ypye(歌曲类型),price(单曲价格))
  3. 歌手表:singers(singerName(歌手名),age(年龄)
  4. 账单表:bill(id(账单编号),billId(歌曲编号),nums(点歌数目),money(总金额),diningMachineNum(机器编号),billDate(点歌日期),payMode(支付方式)
  5. 机器表:diningmachine(machineNum(机器编号),machineStatus(机器状态),orderName(预定机器人姓名),orderPhone(预定人电话)

3.2系统设计

系统架构:MVC三层架构

软件模式:B/S模式

MVC,即Model模型,View模型,Controller模型

Model:承载数据,对用户提交请求进行计算的模块。分为两类,一类称为数据承载Bean,一类称为业务处理Bean。业务处理Bean指的是Service或DAO对象,用于处理用户提出的请求;

数据承载Bean指的是实体类,用于用户承载业务数据,如Student、User

View:试图,为用户提供直观的使用界面,与用户直接进行交互,如本课设中用到的javax.swing所完成的图形化界面

Controller:控制器,用于将用户的请求转发给相应的Model进行,并计算后给予用户反馈

4 详细设计

4.1数据库设计

由底层忘上层逐次编写程序

构思合理的数据库,确保属性名,属性类型等数据的准确无误

根据构思建立相关的数据库

分别有user,bill,diningmachine,songs,singers

user表包含的属性有

id(自增编号),userId(用户编号),pwd(用户密码),name(用户姓名)

bill表包含的属性有

id(自增编号),billId(订单编号),nums(歌曲数目),songId(歌曲编号),money(账单总金额)

billDate(订单时间记录),machineStatus(机器状态)

songs表包含的属性有

id(自增编号),songName(歌曲名),singerName(演唱者),type(曲目类型),price(歌曲单价)

diningmachine表包含的属性有

machineNum(机器编号),machineStatus(机器状态),orderName(预订人名字),orderPhone(预定电话)

数据表的结构

User表

数据类型

列名

字段类型

长度

是否为空

默认值

备注

int

id

int

NO

varchar(50)

userId

varchar

50

NO

char(32)

pwd

char

32

NO

varchar(50)

name

varchar

50

NO

Singer表

列名

数据类型

字段类型

长度

是否为空

默认值

备注

id

int

int

NO

singerName

varchar(50)

varchar

50

NO

age

char(5)

char

5

NO

Song表

列名

数据类型

字段类型

长度

是否为空

默认值

备注

id

int

int

NO

songName

varchar(50)

varchar

50

NO

singerName

varchar(50)

varchar

50

NO

type

varchar(50)

varchar

50

NO

price

double

double

NO

0

Bill

列名

数据类型

字段类型

长度

是否为空

默认值

备注

id

int

int

NO

billId

varchar(50)

varchar

50

NO

songId

int

int

NO

0

nums

int

int

NO

0

diningMachineNum

int

int

NO

0

money

double

double

NO

0

billDate

datetime

datetime

NO

machineStatus

varchar(50)

varchar

50

NO

Diningmachine

列名

数据类型

字段类型

长度

是否为空

默认值

备注

machineNum

int

int

NO

machineStatus

varchar(20)

varchar

20

NO

orderName

varchar(50)

varchar

50

NO

orderPhone

varchar(50)

varchar

50

NO

4.2系统设计

4.2.1MVC架构分层

根据需要完成的功能进行java方法层的设计

domain层:

Bill

DiningMachine

MultiTable

SongsMenu

User

DAO层:

BillDAO

DiningMachineDAO

MultiTableDAO

SongsMenuDAO

UserDAO

Service层:

BillService

DiningMachineService

MultiTableService

SongsMenuService

UserService

View层;

orderSongView

5 系统的实现

5.1主要开发技术

  1. Java
  2. Javax.swing.*
  3. Mysql
  4. mysql-connector-java-8.0.13

5.2开发环境

  1. 操作系统:Window10
  2. 开发工具:idea 2019.3,Navicat
  3. Jdk版本:jdk 1.8
  4. Mysql版本:8.0.3.26

5.3业务核心模块实现

DAO层

BasicDAO

package com.ljm.ordersongs.dao;import com.ljm.ordersongs.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;//泛型指定具体的类型
public class BasicDAO<T> {private QueryRunner qr = new QueryRunner();//开发通用的dml方法,针对任意表public int update(String sql, Object... parameters){Connection connection = JDBCUtils.getConnection();try {int update = qr.update(connection,sql,parameters);return update;} catch (SQLException e) {throw  new RuntimeException(e);} finally {JDBCUtils.close(null,null,null);}}//sql语句,class 传入一个类的Class对象 ,parameters 传入 ? 具体的值,可以是多个//返回多个对象(即查询结果是多行),针对任意表public List<T> queryMulti(String sql, Class<T> clazz,Object... parameters){Connection connection = JDBCUtils.getConnection();try {//BeanListHandler将result封装到Listreturn qr.query(connection,sql,new BeanListHandler<T>(clazz),parameters);} catch (SQLException e) {throw  new RuntimeException(e);} finally {JDBCUtils.close(null,null,null);}}//查询单行结果的通用方法public T querySingle(String sql,Class<T> clazz,Object... parameters){Connection connection = JDBCUtils.getConnection();try {//BeanListHandler将result封装到Listreturn qr.query(connection,sql,new BeanHandler<T>(clazz),parameters);} catch (SQLException e) {throw  new RuntimeException(e);} finally {JDBCUtils.close(null,null,null);}}//查询单行单列的方法,即返回单值的方法public Object queryScalar(String sql,Object... parameters){Connection connection = JDBCUtils.getConnection();try {//BeanListHandler将result封装到Listreturn qr.query(connection,sql,new ScalarHandler(),parameters);} catch (SQLException e) {throw  new RuntimeException(e);} finally {JDBCUtils.close(null,null,null);}}
}

BillDAO

package com.ljm.ordersongs.dao;import com.ljm.ordersongs.domain.Bill;public class BillDAO extends BasicDAO<Bill> {
}

DiningMachineDAO

package com.ljm.ordersongs.dao;import com.ljm.ordersongs.domain.DiningMachine;public class DiningMachineDAO extends BasicDAO<DiningMachine> {}

MultiTableDAO

package com.ljm.ordersongs.dao;import com.ljm.ordersongs.domain.MultiTable;public class MultiTableDAO extends BasicDAO<MultiTable>{
}

SongsMenuDAO

package com.ljm.ordersongs.dao;import com.ljm.ordersongs.domain.SongsMenu;public class SongsMenuDAO extends BasicDAO<SongsMenu> {
}

UserDAO

package com.ljm.ordersongs.dao;import com.ljm.ordersongs.domain.User;public class UserDAO extends BasicDAO<User>{}

domain层

BillService

package com.ljm.ordersongs.service;//处理和账单相关的业务逻辑import com.ljm.ordersongs.dao.BillDAO;
import com.ljm.ordersongs.dao.MultiTableDAO;
import com.ljm.ordersongs.domain.Bill;
import com.ljm.ordersongs.domain.MultiTable;import java.util.List;
import java.util.UUID;public class BillService {//定义BillDAO属性private BillDAO billDAO = new BillDAO();//定义SongsMenuService属性private SongsMenuService songsMenuService = new SongsMenuService();//定义DiningMachineService属性private DiningMachineService diningMachineService = new DiningMachineService();private MultiTableDAO multiTableDAO = new MultiTableDAO();//点歌方法//1.生成账单//2.更新对应机器的状态public boolean orderSong(int songId,int nums,int diningMachineNum){//生成一个账单号,UUID//返回一个随机字符串String billId = UUID.randomUUID().toString();//将账单生成到bill表,money直接记错填入int update = billDAO.update("insert into bill values (null,?,?,?,?,?,now(),'未支付')",billId,songId,nums,diningMachineNum,songsMenuService.getSongsMenuById(songId).getPrice() * nums);if (update<=0){return false;}//需要更新对应机器的状态return diningMachineService.updateDiningMachineStatus(diningMachineNum,"正在使用");}//返回所有账单,提供给view调用public List<Bill> list(){return billDAO.queryMulti("select * from bill ",Bill.class);}//返回所有账单,并提供所点曲目名字public List<MultiTable> list2(){return multiTableDAO.queryMulti("select bill.*,songName from bill ,songs where bill.songId = songs.id ",MultiTable.class);}//查看某台机器是否有未结账的账单public boolean hasPayBillByDiningMachineNum(int diningMachineNum){Bill bill = billDAO.querySingle("select * from bill where diningMachineNum = ? AND machineStatus = '未支付' Limit 0,1",Bill.class,diningMachineNum);return bill != null;}//完成结账【如果该机器存在,且存在未支付的账单】public boolean payBill(int diningMachineNum,String payMode){//1.修改bill表int update = billDAO.update("update bill set machineStatus = ? where diningMachineNum = ? and machineStatus = '未支付'",payMode,diningMachineNum);//防止数据出现不一致性if (update <= 0) {System.out.println("bill更新失败");return false;}//2.修改diningmachine表//通过DiningMachineService操作,完成更新if (!diningMachineService.updateDiningMachineFree(diningMachineNum,"空")){System.out.println("dinningmachine更新失败");return false;}//完成结账要求:成功将两个表都更新return true;}}

DiningMachineService

package com.ljm.ordersongs.service;import com.ljm.ordersongs.dao.DiningMachineDAO;
import com.ljm.ordersongs.domain.DiningMachine;import java.util.List;//业务层,需返回所有机器的信息/*** @author ljm*/
public class DiningMachineService{private DiningMachineDAO diningMachineDAO = new DiningMachineDAO();//一个对象代表一条记录,对应一个机器public List<DiningMachine> list(){return diningMachineDAO.queryMulti("select machineNum,machineStatus from diningMachine",DiningMachine.class);}//根据machineNum,查询对应的机器DiningMachine对象//如果返回null, 表示machineNum对应的机器不存在public DiningMachine getDiningMachineById(int machineNum) {return diningMachineDAO.querySingle("select * from diningMachine where machineNum = ?",DiningMachine.class,machineNum);}//如果机器可以预定,调用方法,对其状态进行更新,包括预定人和电话public boolean orderDiningMachine(int machineNum ,String orderName,String orderPhone){int update = diningMachineDAO.update("update diningMachine set machineStatus='已经预定',orderName=?,orderPhone=? where machineNum=?",orderName,orderPhone,machineNum);return update > 0;}//更新 机器状态方法public boolean updateDiningMachineStatus(int machineNum,String machineStatus){int update =  diningMachineDAO.update("update diningmachine set machineStatus = ? where machineNum = ?",machineStatus,machineNum);return update > 0;}//将指定的机器设置为空状态,置为初始值public boolean updateDiningMachineFree(int machineNum,String machineStatus){int update =  diningMachineDAO.update("update diningmachine set machineStatus = ?,orderName = '',orderPhone = '' where machineNum = ?",machineStatus,machineNum);return update > 0;}}

MultiTableService

package com.ljm.ordersongs.service;import com.ljm.ordersongs.dao.MultiTableDAO;
import com.ljm.ordersongs.domain.MultiTable;import java.util.List;public class MultiTableService {private MultiTableDAO multiTableDAO = new MultiTableDAO();public List<MultiTable> list2(){return multiTableDAO.queryMulti("select bill.*,songName from bill ,songs where bill.songId = songs.id ",MultiTable.class);}}

SongsMenuService

package com.ljm.ordersongs.service;import com.ljm.ordersongs.dao.SongsMenuDAO;
import com.ljm.ordersongs.domain.SongsMenu;import java.util.List;/*** @author ljm*/
public class SongsMenuService {//定义SongsMenuDAOprivate SongsMenuDAO songsMenuDAO = new SongsMenuDAO();//返回所有歌曲,返回给界面使用public List<SongsMenu> list(){return songsMenuDAO.queryMulti("select * from songs",SongsMenu.class);}public List<SongsMenu> listSinger(){return  songsMenuDAO.queryMulti("select * from songs group by singerName",SongsMenu.class);}//根据songId返回songsMenu对象public SongsMenu getSongsMenuById (int id){return songsMenuDAO.querySingle("select * from songs where id = ? ",SongsMenu.class,id);}
}

UserService

package com.ljm.ordersongs.service;import com.ljm.ordersongs.dao.UserDAO;
import com.ljm.ordersongs.domain.User;//完成对user表的各种操作,通过调用UserDAO对象完成
public class UserService {//定义一个UserDAO属性private UserDAO userDAO = new UserDAO();public User getUserByIdAndPwd(String userId,String pwd){//查询单个对象return userDAO.querySingle("select * from user where userId=? and pwd=md5(?)",User.class,userId,pwd);}}

utils层

JDBCUtils

package com.ljm.ordersongs.utils;//工具类,完成mysql的连接和关闭资源import java.sql.*;@SuppressWarnings({"all"})
public class JDBCUtils {//定义相关的属性,由于只需要一份,因此,采用static类private static String user = "root";;private static String password = "Ljm20011128";;private static String url = "jdbc:mysql://127.0.0.1:3306/ordersong?"+ "allowPublicKeyRetrieval=true"+ "& useUnicode = true & serverTimezone = GMT"+ "& characterEncoding = utf8 & useSSL = false";;private static String driver;//驱动名static {try {Class.forName("com.mysql.cj.jdbc.Driver");}catch (ClassNotFoundException e){//将编译异常转换成运行异常//调用者,可以选择捕获该异常,也可以选择默认处理该异常,比较方便throw new RuntimeException(e);
//            e.printStackTrace();}}//建立连接public static Connection getConnection(){//surround with 快捷键ctrl+alt+ttry {return DriverManager.getConnection(url,user,password);} catch (SQLException e) {throw new RuntimeException(e);}}//关闭相关资源/** 1.resultset* 2.statement* 3.connection* 4.如果需要关闭资源,就传入对象,否则传入null* */public static void close(ResultSet set, Statement statement,Connection connection){//判断是否为空try {if (set != null){set.close();}if (statement != null){statement.close();}if (connection != null){connection.close();}} catch (SQLException e) {throw new RuntimeException(e);}}
}

JDBCUtilsByDruid

package com.ljm.ordersongs.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;public class JDBCUtilsByDruid {private static DataSource ds;static {Properties properties = new Properties();try {properties.load(new FileInputStream("src\\druid.properties"));ds = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException{return ds.getConnection();}//关闭连接,close不是真的断开连接,而是把Connection对象放回连接池public static void close(ResultSet resultSet, Statement statament, Connection connection){try {if (resultSet != null){resultSet.close();}if (statament != null){statament.close();}if (connection != null){connection.close();}} catch (SQLException e) {throw new RuntimeException(e);}}
}

JDBCUtilsDruid_USE

package com.ljm.ordersongs.utils;import java.sql.*;public class JDBCUtilsByDruid_USE {@SuppressWarnings({"all"})public static void main(String[] args) throws SQLException {//1.注册驱动try {Class.forName("com.mysql.cj.jdbc.Driver");}catch (ClassNotFoundException e){e.printStackTrace();}//2.得到连接//jdbc:mysql://规定好表示协议,通过jdbc的方式连接mysql//localhost 主机 可以是ip地址//3306 表示mysql监听的端口//datebook表示连接到的数据库String url = "jdbc:mysql://127.0.0.1:3306/ordersong?"+ "allowPublicKeyRetrieval=true"+ "& useUnicode = true & serverTimezone = GMT"+ "& characterEncoding = utf8 & useSSL = false";// MySQL在高版本需要指明是否进行SSL连接//将用户名和密码放到properties对象中//        Properties properties = new Properties();
//        properties.setProperty("user","root");
//        properties.setProperty("password","Ljm20011128");
//String username = "root";String password = "Ljm20011128";Connection connect = JDBCUtilsByDruid.getConnection();//3.执行sqlString sql = "Create table singer(singer_name varchar(10) not null primary key ," +"sage int ,birthday date,country varchar(10))";//statement用于执行静态sql语句并返回其生成结果的对象PreparedStatement preparedStatement = connect.prepareStatement(sql);
//        preparedStatement.setInt(1,xxx);ResultSet resultSet = preparedStatement.executeQuery();while (resultSet.next()){//让光标向后移动,如果没有更多的行则返回false,结束while循环resultSet.getInt("id");}int rows = preparedStatement.executeUpdate();//如果是dml语句,返回的就是影响行数System.out.println(rows > 0 ? "success":"defeat");//4.关闭连接资源try {preparedStatement.close();}catch (SQLException e){}finally {preparedStatement = null;}JDBCUtilsByDruid.close(resultSet,preparedStatement,connect);resultSet.close();}}

Utility

package com.ljm.ordersongs.utils;/**工具类的作用:处理各种情况的用户输入,并且能够按照程序员的需求,得到用户的控制台输入。
*/import java.util.*;
/***/
public class Utility {//静态属性。。。private static Scanner scanner = new Scanner(System.in);/*** 功能:读取键盘输入的一个菜单选项,值:1——5的范围* @return 1——5*/public static char readMenuSelection() {char c;for (; ; ) {String str = readKeyBoard(1, false);//包含一个字符的字符串c = str.charAt(0);//将字符串转换成字符char类型if (c != '1' && c != '2' && c != '3' && c != '4' && c != '5') {System.out.print("选择错误,请重新输入:");} else break;}return c;}/*** 功能:读取键盘输入的一个字符* @return 一个字符*/public static char readChar() {String str = readKeyBoard(1, false);//就是一个字符return str.charAt(0);}/*** 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符* @param defaultValue 指定的默认值* @return 默认值或输入的字符*/public static char readChar(char defaultValue) {String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符return (str.length() == 0) ? defaultValue : str.charAt(0);}/*** 功能:读取键盘输入的整型,长度小于2位* @return 整数*/public static int readInt() {int n;for (; ; ) {String str = readKeyBoard(2, false);//一个整数,长度<=2位try {n = Integer.parseInt(str);//将字符串转换成整数break;} catch (NumberFormatException e) {System.out.print("数字输入错误,请重新输入:");}}return n;}/*** 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数* @param defaultValue 指定的默认值* @return 整数或默认值*/public static int readInt(int defaultValue) {int n;for (; ; ) {String str = readKeyBoard(10, true);if (str.equals("")) {return defaultValue;}//异常处理...try {n = Integer.parseInt(str);break;} catch (NumberFormatException e) {System.out.print("数字输入错误,请重新输入:");}}return n;}/*** 功能:读取键盘输入的指定长度的字符串* @param limit 限制的长度* @return 指定长度的字符串*/public static String readString(int limit) {return readKeyBoard(limit, false);}/*** 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串* @param limit 限制的长度* @param defaultValue 指定的默认值* @return 指定长度的字符串*/public static String readString(int limit, String defaultValue) {String str = readKeyBoard(limit, true);return str.equals("")? defaultValue : str;}/*** 功能:读取键盘输入的确认选项,Y或N* 将小的功能,封装到一个方法中.* @return Y或N*/public static char readConfirmSelection() {System.out.println("请再次确认 :(Y/N)");char c;for (; ; ) {//无限循环//在这里,将接受到字符,转成了大写字母//y => Y n=>NString str = readKeyBoard(1, false).toUpperCase();c = str.charAt(0);if (c == 'Y' || c == 'N') {break;} else {System.out.print("选择错误,请重新输入:");}}return c;}/*** 功能: 读取一个字符串* @param limit 读取的长度* @param blankReturn 如果为true ,表示 可以读空字符串。 *                     如果为false表示 不能读空字符串。*          *   如果输入为空,或者输入大于limit的长度,就会提示重新输入。* @return*/private static String readKeyBoard(int limit, boolean blankReturn) {//定义了字符串String line = "";//scanner.hasNextLine() 判断有没有下一行while (scanner.hasNextLine()) {line = scanner.nextLine();//读取这一行//如果line.length=0, 即用户没有输入任何内容,直接回车if (line.length() == 0) {if (blankReturn) return line;//如果blankReturn=true,可以返回空串else continue; //如果blankReturn=false,不接受空串,必须输入内容}//如果用户输入的内容大于了 limit,就提示重写输入  //如果用户如的内容 >0 <= limit ,我就接受if (line.length() < 1 || line.length() > limit) {System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");continue;}break;}return line;}
}

view层

errorView

package com.ljm.ordersongs.view;import javax.swing.*;public class errorView {public errorView(String text){JFrame frame = new JFrame("错误提示");frame.setSize(400,200);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);JTextArea jTextArea = new JTextArea();jTextArea.setText(text);jTextArea.setLineWrap(true);JScrollPane jPanel = new JScrollPane(jTextArea);jPanel.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);frame.setContentPane(jPanel);frame.setVisible(true);}
}

Frame

package com.ljm.ordersongs.view;import com.ljm.ordersongs.domain.User;
import com.ljm.ordersongs.service.UserService;import javax.swing.JButton;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.*;public class Frame{//让Frame类也成为一个窗体public Frame(){JFrame frame = new JFrame("卡拉OK点歌");frame.setSize(700,400);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel jPanel = new JPanel();frame.add(jPanel);setUI(jPanel,frame);frame.setVisible(true);}public void setUI(JPanel jPanel,JFrame jFrame){jPanel.setLayout(null);JLabel username = new JLabel("账号");username.setBounds(200,100,30,30);jPanel.add(username);JTextField usernameText = new JTextField();usernameText.setBounds(250,100,250,30);jPanel.add(usernameText);JLabel pwd = new JLabel("密码");pwd.setBounds(200,150,30,30);jPanel.add(pwd);JPasswordField pwdText = new JPasswordField();pwdText.setBounds(250,150,250,30);jPanel.add(pwdText);JButton loginButton = new JButton("登录");loginButton.setBounds(250,200,200,30);loginButton.addActionListener(actionEvent -> {UserService service = new UserService();User user = service.getUserByIdAndPwd(usernameText.getText(),pwdText.getText());if (user == null){new errorView("用户名或密码不正确");}else {jFrame.setVisible(false);new MenuView();}});jPanel.add(loginButton);}public static void main(String[] args) {new Frame();}}

MenuView

package com.ljm.ordersongs.view;import com.ljm.ordersongs.domain.Bill;
import com.ljm.ordersongs.domain.DiningMachine;
import com.ljm.ordersongs.domain.MultiTable;
import com.ljm.ordersongs.domain.SongsMenu;
import com.ljm.ordersongs.service.BillService;
import com.ljm.ordersongs.service.DiningMachineService;
import com.ljm.ordersongs.service.MultiTableService;
import com.ljm.ordersongs.service.SongsMenuService;import javax.swing.*;
import java.util.List;/*System.out.println("\t\t 1 显示机器状态");System.out.println("\t\t 2 预定机器");System.out.println("\t\t 3 显示所有歌曲");System.out.println("\t\t 4 显示所有歌手");System.out.println("\t\t 5 选择要唱的歌曲(点单)");System.out.println("\t\t 6 查看所点歌曲(账单)");System.out.println("\t\t 7 结账");System.out.println("\t\t 8 退出系统");
*/
public class MenuView {public static void main(String[] args) {new MenuView();}public MenuView(){JFrame frame = new JFrame("卡拉OK点歌");frame.setSize(1000,100);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel jPanel = new JPanel();frame.add(jPanel);setUI(jPanel,frame);frame.setVisible(true);}public void setUI(JPanel jPanel,JFrame jFrame) {JButton jButton1 = new JButton("显示机器状态");jButton1.addActionListener(actionEvent ->{DiningMachineService diningMachineService = new DiningMachineService();List<DiningMachine> list = diningMachineService.list();StringBuilder sb = new StringBuilder("机器状态:\n");for (DiningMachine diningMachine : list) {sb.append(diningMachine.toString());sb.append("\n");}new resultView(sb.toString());});jPanel.add(jButton1);JButton jButton2 = new JButton("预定机器");jButton2.addActionListener(actionEvent ->{DiningMachineService diningMachineService = new DiningMachineService();new orderView();});jPanel.add(jButton2);JButton jButton3 = new JButton("显示所有歌曲");jButton3.addActionListener(actionEvent ->{SongsMenuService songsMenuService = new SongsMenuService();List<SongsMenu> list = songsMenuService.list();StringBuilder sb = new StringBuilder("歌曲信息:\n");sb.append("歌曲编号\t\t歌名\t\t歌手\t\t类别\t\t价格\n");for (SongsMenu songsMenu : list) {sb.append(songsMenu.toString());sb.append("\n");}new resultView(sb.toString());});jPanel.add(jButton3);JButton jButton4 = new JButton("显示所有歌手");jButton4.addActionListener(actionEvent1 ->{SongsMenuService songsMenuService = new SongsMenuService();List<SongsMenu> listSinger = songsMenuService.listSinger();StringBuilder sb = new StringBuilder("歌手信息:\n");for (SongsMenu songsMenu : listSinger) {sb.append(songsMenu.getSingerName());sb.append("\n");}new resultView(sb.toString());});jPanel.add(jButton4);JButton jButton5 = new JButton("选择要唱的歌曲(点单)");jButton5.addActionListener(actionEvent1 ->{BillService billService = new BillService();new ordersongsView();});jPanel.add(jButton5);JButton jButton6 = new JButton("查看所点歌曲(账单)");jButton6.addActionListener(actionEvent1 ->{MultiTableService multiTableService = new MultiTableService();StringBuilder sb = new StringBuilder("账单信息\n");sb.append("\n编号\t歌曲编号\t点歌数量\t\t机器编号\t金额\t\t日期\t\t\t状态\t\t\t歌曲名\n");List<MultiTable> list = multiTableService.list2();for (MultiTable multiTable : list) {sb.append(multiTable.toString());sb.append("\n");}new resultView(sb.toString());});jPanel.add(jButton6);JButton jButton7 = new JButton("结账");jButton7.addActionListener(actionEvent1 ->{BillService billService =new BillService();new payBillView();});jPanel.add(jButton7);JButton jButton8 = new JButton("退出系统");jButton8.addActionListener(actionEvent1 ->{new Frame();jFrame.setVisible(false);});jPanel.add(jButton8);}
}

ordersongsView

package com.ljm.ordersongs.view;import javax.swing.*;import com.ljm.ordersongs.domain.Bill;
import com.ljm.ordersongs.domain.DiningMachine;
import com.ljm.ordersongs.domain.SongsMenu;
import com.ljm.ordersongs.service.BillService;
import com.ljm.ordersongs.service.DiningMachineService;
import com.ljm.ordersongs.service.SongsMenuService;import javax.swing.*;public class ordersongsView {public ordersongsView() {JFrame frame = new JFrame("选择要唱的歌曲(点单)");frame.setSize(700, 400);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);JPanel jPanel = new JPanel();frame.add(jPanel);setUI(jPanel, frame);frame.setVisible(true);}public void setUI(JPanel jPanel,JFrame jFrame){jPanel.setLayout(null);JLabel machineNum = new JLabel("机器编号");machineNum.setBounds(180,100,70,30);jPanel.add(machineNum);JTextField machineNumText = new JTextField();machineNumText.setBounds(250,100,250,30);jPanel.add(machineNumText);JLabel songId = new JLabel("歌曲编号");songId.setBounds(180,150,70,30);jPanel.add(songId);JTextField songIdText = new JTextField();songIdText.setBounds(250,150,250,30);jPanel.add(songIdText);JLabel nums = new JLabel("歌曲数量");nums.setBounds(180,200,70,30);jPanel.add(nums);JTextField numsText = new JTextField();numsText.setBounds(250,200,250,30);jPanel.add(numsText);JButton orderButton = new JButton("点歌");orderButton.setBounds(250,250,200,30);orderButton.addActionListener(e ->{BillService billService = new BillService();Bill bill = new Bill();bill.setDiningMachineNum(Integer.parseInt(machineNumText.getText()));DiningMachineService diningMachineService = new DiningMachineService();DiningMachine diningMachineServiceDiningMachineById = diningMachineService.getDiningMachineById(Integer.parseInt(machineNumText.getText()));SongsMenuService songsMenuService = new SongsMenuService();SongsMenu songsMenu = songsMenuService.getSongsMenuById(Integer.parseInt(songIdText.getText()));if (diningMachineServiceDiningMachineById == null){new errorView("不存在该机器");}else if (songsMenu == null){new errorView("不存在该歌曲");}else {boolean update = billService.orderSong(Integer.parseInt(songIdText.getText()), Integer.parseInt(numsText.getText()),Integer.parseInt(machineNumText.getText()));if (update == true) {jFrame.setVisible(false);new resultView("点歌成功");} else {new errorView("点歌失败,数据库异常");}}});jPanel.add(orderButton);}
}

ordersongView

package com.ljm.ordersongs.view;import com.ljm.ordersongs.domain.*;
import com.ljm.ordersongs.service.BillService;
import com.ljm.ordersongs.service.DiningMachineService;
import com.ljm.ordersongs.service.SongsMenuService;
import com.ljm.ordersongs.service.UserService;
import com.ljm.ordersongs.utils.Utility;import java.util.List;
import java.util.Scanner;public class ordersongView {//控制是否退出菜单private boolean loop = true;private String key = "";//定义UserService属性private UserService userService = new UserService();//定义DiningMachineService属性private DiningMachineService diningMachineService = new DiningMachineService();//定义SongsMenuService属性private SongsMenuService songsMenuService = new SongsMenuService();//定义BillService属性private BillService billService = new BillService();public static void main(String[] args) {new ordersongView().mainView();}//显示所有机器状态public void listDiningMachine(){System.out.println("显示机器状态");List<DiningMachine> list = diningMachineService.list();System.out.println("\n机器编号\t\t机器状态");for (DiningMachine diningMachine : list) {System.out.println(diningMachine);}System.out.println("=========显示完毕=========");}//完成机器预定public void orderDiningMachine(){System.out.println("=========预定机器=========");System.out.println("请选择要预定的机器号码(-1退出):");//如果输入-1 表示放弃预定int machineNum = Utility.readInt();if (machineNum == -1){System.out.println("取消预定");return;}//该方法得到的是Y/Nchar key = Utility.readConfirmSelection();if(key == 'Y'){//根据orderId返回DiningMachine对象,如果返回null,则说明对象不存在DiningMachine diningMachine = diningMachineService.getDiningMachineById(machineNum);if (diningMachine == null){System.out.println("===========预定机器不在编号范围内===========");return;}//判断该机器的状态是否为“空”if(!("空".equals(diningMachine.getMachineStatus()))){//说明该机器处于已占用状态System.out.println("===========该机器已被占用或预定===========");return;}//接收预定信息System.out.println("预定人的名字:");String orderName = Utility.readString(50);System.out.println("预定人的电话:");String orderPhone = Utility.readString(50);//更新机器状态if(diningMachineService.orderDiningMachine(machineNum,orderName,orderPhone)){System.out.println("预定成功");}else {System.out.println("预定失败");}}else {System.out.println("==========取消预定============");}}//显示所有歌曲public void ListSongs(){List<SongsMenu> list = songsMenuService.list();System.out.println("\n歌曲编号\t\t歌名\t\t歌手\t\t类别\t\t价格");for (SongsMenu songsMenu : list) {System.out.println(songsMenu);}System.out.println("==========显示完毕=========");}//显示所有歌手public void ListSingers(){List<SongsMenu> listSinger = songsMenuService.listSinger();System.out.println("歌手");for (SongsMenu songsMenu : listSinger) {System.out.println(songsMenu.getSingerName());}System.out.println("==========显示完毕=========");}//完成点歌服务public void orderSongs(){System.out.println("===============点歌服务==============");System.out.println("=======请输入点歌的机器编码(-1退出)========");int orderDiningMachineNum = Utility.readInt();if (orderDiningMachineNum == -1){System.out.println("取消点歌");return;}System.out.println("=======请输入所点歌曲的编号(-1退出)========");int songId = Utility.readInt();if (songId == -1){System.out.println("============取消点歌===========");return;}System.out.println("=======请输入所点歌曲的数量(-1退出)========");int orderNum = Utility.readInt();if (orderNum == -1){System.out.println("============取消点歌===========");return;}//验证机器编号是否存在DiningMachine diningMachine = diningMachineService.getDiningMachineById(orderDiningMachineNum);if (diningMachine == null){System.out.println("============不存在该机器==========");return;}//验证歌曲编号是否存在SongsMenu songsMenu = songsMenuService.getSongsMenuById(songId);if (songsMenu == null){System.out.println("===========不存在这首歌==========");return;}if (billService.orderSong(songId,orderNum,orderDiningMachineNum)){System.out.println("=============点歌成功============");}else {System.out.println("=============点歌失败============");}}//显示账单信息(单表)public void listBill(){List<Bill> Bills = billService.list();System.out.println("\n编号\t\t歌曲编号\t\t点歌数量\t\t机器编号\t\t金额\t\t日期\t\t\t\t\t\t\t状态");for (Bill bill : Bills) {System.out.println(bill);}System.out.println("==========显示完毕=========");}//显示账单信息(多表),添加了曲目名public void listBill2(){List<MultiTable> MultiBills = billService.list2();System.out.println("\n编号\t\t歌曲编号\t\t点歌数量\t\t机器编号\t\t金额\t\t日期\t\t\t\t\t\t\t状态\t\t歌曲名");for (MultiTable bill : MultiBills) {System.out.println(bill);}System.out.println("==========显示完毕=========");}//完成结账public void payBill(){System.out.println("==========结账服务=========");System.out.println("请选择要结账的机器编号(-1退出):");int diningMachineNum = Utility.readInt();if (diningMachineNum == -1){System.out.println("取消结账服务");return;}//验证机器是否存在DiningMachine diningMachine = diningMachineService.getDiningMachineById(diningMachineNum);if (diningMachine == null){System.out.println("结账机器不存在");return;}//验证机器是否需要结账if (!billService.hasPayBillByDiningMachineNum(diningMachineNum)){System.out.println("该机器不存在需结账账单");return;}System.out.println("结账方式(现金/微信支付/支付宝)回车表示退出:");String payMode = Utility.readString(20,"");//如果输入回车,就是返回 " ",空串if ("".equals(payMode)){System.out.println("====取消结账====");return;}char key = Utility.readConfirmSelection();if (key == 'Y'){if (billService.payBill(diningMachineNum,payMode)){System.out.println("完成结账");}else {System.out.println("结账失败");}}else {System.out.println("=====取消结账====");}}public void mainView(){while (loop){System.out.println("===========卡拉ok点歌系统===========");System.out.println("1.登录系统");System.out.println("2.退出系统");System.out.println("请输入你的选择:");key = Utility.readString(1);switch (key){case "1":System.out.print("请输入账号:");String useId = Utility.readString(50);System.out.print("请输入密码:");String pwd = Utility.readString(50);User user = userService.getUserByIdAndPwd(useId,pwd);if(user !=null){//说明存在该用户System.out.println("============登录成功==========");System.out.println("用户名:"+ user.getName());//显示二级菜单while (loop){System.out.println("===========卡拉ok系统(二级菜单)========");System.out.println("\t\t 1 显示机器状态");System.out.println("\t\t 2 预定机器");System.out.println("\t\t 3 显示所有歌曲");System.out.println("\t\t 4 显示所有歌手");System.out.println("\t\t 5 选择要唱的歌曲(点单)");System.out.println("\t\t 6 查看所点歌曲(账单)");System.out.println("\t\t 7 结账");System.out.println("\t\t 8 退出系统");System.out.println("请输入你的选择(1~8):");key = Utility.readString(1);switch (key){case "1"://System.out.println("显示机器");listDiningMachine();break;case "2"://System.out.println("预定机器");orderDiningMachine();break;case "3"://System.out.println("显示所有歌曲");ListSongs();break;case "4"://System.out.println("显示所有歌手");ListSingers();break;case "5"://System.out.println("选择要唱的歌曲(点单)");orderSongs();break;case "6"://System.out.println("查看所点歌曲(账单)");listBill2();break;case "7"://System.out.println("结账");payBill();break;case "8":System.out.println("你退出了卡拉ok点歌系统");loop = false;//退出整个系统,包括一二级菜单break;default:System.out.println("输入有误,请按照规定的数字进行选择");}}}else {System.out.println("============登录失败==========");}break;case "2":loop = false;break;default:System.out.println("输入有误,请按照规定输入1或2");}}}
}

orderView

package com.ljm.ordersongs.view;import com.ljm.ordersongs.domain.DiningMachine;
import com.ljm.ordersongs.service.DiningMachineService;import javax.swing.*;public class orderView {public orderView(){JFrame frame = new JFrame("预订机器");frame.setSize(700,400);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);JPanel jPanel = new JPanel();frame.add(jPanel);setUI(jPanel,frame);frame.setVisible(true);}public void setUI(JPanel jPanel,JFrame jFrame){jPanel.setLayout(null);JLabel machineNum = new JLabel("机器编号");machineNum.setBounds(180,100,70,30);jPanel.add(machineNum);JTextField machineNumText = new JTextField();machineNumText.setBounds(250,100,250,30);jPanel.add(machineNumText);JLabel orderName = new JLabel("预定人");orderName.setBounds(180,150,70,30);jPanel.add(orderName);JTextField orderNameText = new JTextField();orderNameText.setBounds(250,150,250,30);jPanel.add(orderNameText);JLabel orderPhone = new JLabel("预订电话");orderPhone.setBounds(180,200,70,30);jPanel.add(orderPhone);JTextField orderPhoneText = new JTextField();orderPhoneText.setBounds(250,200,250,30);jPanel.add(orderPhoneText);JButton orderButton = new JButton("预订");orderButton.setBounds(250,250,200,30);orderButton.addActionListener(e ->{DiningMachineService diningMachineService = new DiningMachineService();DiningMachine diningMachine = new DiningMachine();diningMachine.setMachineNum(Integer.parseInt(machineNumText.getText()));if (("空".equals(diningMachine.getMachineStatus()))){new errorView("已经被预订或正在使用");}else {boolean status = diningMachineService.orderDiningMachine(Integer.parseInt(machineNumText.getText()), orderNameText.getText(), orderPhoneText.getText());if (status == true) {jFrame.setVisible(false);new resultView("预订成功");} else {new errorView("预订失败,数据库异常");}}});jPanel.add(orderButton);}
}

payBillView

package com.ljm.ordersongs.view;import com.ljm.ordersongs.domain.Bill;
import com.ljm.ordersongs.domain.DiningMachine;
import com.ljm.ordersongs.domain.SongsMenu;
import com.ljm.ordersongs.service.BillService;
import com.ljm.ordersongs.service.DiningMachineService;
import com.ljm.ordersongs.service.SongsMenuService;import javax.swing.*;public class payBillView {public payBillView(){JFrame frame = new JFrame("结账服务");frame.setSize(700, 400);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);JPanel jPanel = new JPanel();frame.add(jPanel);setUI(jPanel, frame);frame.setVisible(true);}public void setUI(JPanel jPanel,JFrame jFrame){jPanel.setLayout(null);JLabel machineNum = new JLabel("机器编号");machineNum.setBounds(180,100,70,30);jPanel.add(machineNum);JTextField machineNumText = new JTextField();machineNumText.setBounds(250,100,250,30);jPanel.add(machineNumText);JLabel payMode = new JLabel("结账方式(现金/支付宝/微信支付)");payMode.setBounds(60,150,270,30);jPanel.add(payMode);JTextField payModeText = new JTextField();payModeText.setBounds(250,150,250,30);jPanel.add(payModeText);JButton orderButton = new JButton("结账");orderButton.setBounds(250,250,200,30);orderButton.addActionListener(e ->{BillService billService = new BillService();Bill bill = new Bill();bill.setDiningMachineNum(Integer.parseInt(machineNumText.getText()));DiningMachineService diningMachineService = new DiningMachineService();DiningMachine diningMachineServiceDiningMachineById = diningMachineService.getDiningMachineById(Integer.parseInt(machineNumText.getText()));if (diningMachineServiceDiningMachineById == null){new errorView("不存在该机器");}else if (!billService.hasPayBillByDiningMachineNum(Integer.parseInt(machineNumText.getText()))){new errorView("该机器不需要结账(已结清)");}else {boolean update = billService.payBill(Integer.parseInt(machineNumText.getText()),payModeText.getText());if (update == true) {jFrame.setVisible(false);new resultView("结账成功");} else {new errorView("结账失败,数据库异常");}}});jPanel.add(orderButton);}
}

resultView

package com.ljm.ordersongs.view;import javax.swing.*;public class resultView {public resultView(String text){JFrame frame = new JFrame("结果");frame.setSize(1500,500);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);JTextArea jTextArea = new JTextArea();jTextArea.setSize(300,400);jTextArea.setText(text);jTextArea.setLineWrap(true);JScrollPane jPanel = new JScrollPane(jTextArea);frame.add(jPanel);frame.setVisible(true);}
}

6 回顾与展望

通过这次数据库课程谁叫,我锻炼了Navicat,powerdisinger的使用,进一步了解了数据库的使用和意义,将课上所学知识与现实中的实际问题联系在一起,能够使问题简单化,通过图形化界面使用户能直接更改数据库的数据。我的课程设计是卡拉OK点歌系统,目的是使用户

完成曲目查看,歌手查看,预定机器,点歌等操作。开发系统的结构是MVC三层结构,对系统进行了后端和前端的区分,本报告主要是对后端业务的说明。

系统的数据库:拥有5个表,分别是user表,diningmachine表,songs表,singers表,bill表,中心表是bill表,diningmachine表和songs表均围绕bill表提供相关信息,级联更新数据库。各个表均拥有id属性,均为自增列,同时各个表的id作为主键。

系统的重点:通过MVC架构将后端设计拆分成四层,view层,dao层,service层,domain层,由低到高一步一步完善系统。例如更新bill表的订单操作,首先连接数据库,编写domian层,定义好dao层,根据需要进行的数据库操作编写service层,最后根据设计完成view层的美工和图形化实现。

通过此次课程设计,我加深了对数据库的了解,对数据库的使用也更得心应手,提高了对idea和Navicat等开发软件的使用能力。

在本次课设中依然存在不足的地方,比如用户的交互界面使用的是比较老旧的图形化界面,在以后的学习中,我希望能够学习vue框架,JavaScript等知识进一步完善前端相关的设计,致力于完成更加人性化的交互界面

参考文献

  1. JAVA(图形界面)_every step-CSDN博客_java图形界面 , 2019

https://www.baidu.com/link?url=byENqYcaRcLvF3VlrTiCOPKaKTfcmmtTWVM56pvVMm5-jwdTR1QRpt2D4yy7f1KzGzSOBQG8TztfarLSRb65Zxh5WJrgawD2cEXzHvTjnIW&wd=&eqid=b40ac075000204970000000661e0f5d2

  1. java学习教程:韩顺平零基础学java , 2021

https://www.bilibili.com/video/BV1fh411y7R8?spm_id_from=333.337.0.0

  1. Java - AWT&Swing图形化界面编程 哔哩哔哩 黑马Java, 2021

https://www.bilibili.com/video/BV1wh411d7it?from=search&seid=15380768374470915312&spm_id_from=333.337.0.0

  1. MVC框架详解(资料整理)_皓月星辰-CSDN博客_mvc框架 ,2018

https://www.baidu.com/link?url=nhkG3s90pbzTCuCokyJdj9iAT68u6ykFIfEQS5DypuamD4bRX4m9AY9ZmjSZa9qsrKMJl_V7kqHrIVVkqM5g4QqdSqoeUQdx5P2dRBCXCde&wd=&eqid=8f6bb04e000128e60000000661e0f5b9

  1. MySQL常用SQL语句大全_江南极客-CSDN博客_mysql语句大全及其用法, 2017

https://www.baidu.com/link?url=1-gpM1wYVqYPElihRnZYRyA7WJmPACZ3YlCBHDwzlqlh4ulyBJDx7k_iO1AF8PtTJsomEIb6xu7-2KLhf6cZFTh7A4G_b_38aVBmRAWkPOi&wd=&eqid=df5a00060001fac10000000661e0f5eb

  1. 王珊 数据库系统概论(第5版)高等教育出版社,2014

广东工业大学数据库课设(点歌系统)相关推荐

  1. C语言模拟电梯(广东工业大学数据结构课设)

    课 程 设 计 课程名称 数据结构 题目名称电梯模拟(难度1.4) 学生学院 专业班级 学    号 学生姓名 指导教师 2019 年 1 月 9日 需求分析 本程序是实现电梯的模拟运行,同时还包含模 ...

  2. 双非普通一本大一学生学期末课设——运动会比赛计分系统

    双非普通一本大一学生学期末课设--运动会比赛计分系统 并没有做文件系统-只能将就的看一下,也没有结构体 做的很粗糙,很烂,就是发出来纪念一下. 感觉有点像堆出来的一坨屎,但是好歹是自己儿子,为我的代码 ...

  3. 【数据库课设】图书馆借阅系统

    [数据库][keshe]图书馆借阅系统 系统+报告全家桶 代码: using System; using System.Collections.Generic; using System.Compon ...

  4. 学生机房管理服务器系统设计,广东工业大学数据库课程设计机房管理系统设计...

    <广东工业大学数据库课程设计机房管理系统设计>由会员分享,可在线阅读,更多相关<广东工业大学数据库课程设计机房管理系统设计(27页珍藏版)>请在人人文库网上搜索. 1.课程设计 ...

  5. HNUST - 数据库课设

    HNUST - Python+Mysql数据库课设 一.实验题目 人事管理系统 二.实验目的 企业人事管理系统主要用于员工个人资料的录入.职务变动的记录和管理.使用人事管理系统,便于公司领导掌握人员的 ...

  6. JAVA+MySQL 数据库课设的问题及解答的整理 以【学生管理系统】为例

    JAVA+MySQL 数据库课设的问题及解答的整理 以[学生管理系统]为例.帅气学长哦! 编写这篇博文初衷 MySQL的一些问题 Eclipse导入项目的一些问题 数据库的建立和连接 最后一步 编写这 ...

  7. 数据库课设(足球联赛管理系统)

    一:前言 如果有关注博主的粉丝,可能会发现贴心杰又缺更好几天了,但是我是宠粉杰啊,怎么可能会忘了我的宝贝粉丝呢,只不过是临近期末,各种大作业课设如期而至,这几天我在写数据库课设,对于一个没有写过任何项 ...

  8. 数据库课设记录 Day 3

    Day 3 经过各种斟酌,砍了不少一时心血来潮想做的东西,数据库课设的核心内容就定下来了. 公司 Company 名称 字段 数据类型 id id int 公司名 name varchar(20) 地 ...

  9. 地大c语言课程设计题目,中国地质大学数据结构课设-全国铁路运输网最佳经由问题课程设计报告精选.doc...

    中国地质大学数据结构课设-全国铁路运输网最佳经由问题课程设计报告精选 数据结构 上机实习报告 实验题目:全国铁路运输网最佳经由问题 班级: 姓名: 学号: 完成日期:2017年4月25日 目录 课程设 ...

最新文章

  1. WPF 基础到企业应用系列1——开篇故意
  2. Node.js笔记 - 修改文件后自动重启node服务
  3. Python 人脸识别就多简单,看这个就够了!
  4. 吸血鬼 java_吸血鬼数
  5. 【Java】对JTable里的元素进行排序
  6. bootstrap datetimepicker、bootstrap datepicker日期组件对范围的简单封装
  7. 读写二进制c# 二进制读写
  8. 快速排序算法_大佬的快速排序算法,果然不一样
  9. C++虚函数(多态性)
  10. SOUI使用总结知识汇总.
  11. 高效能管理之要事第一 时间管理表格2
  12. 说说我出道后的处女作:剪贴板神器 iPaste
  13. Morketing Summit 2019“破·局”:有破有立,突破棋局 | MS2019灵眸·全球营销商业峰会全面启动!...
  14. 在word中一个符号怎么打,这个符号是上边一个白三角,下边一个黑三角,两个三角对称形成一个向右的箭头。
  15. 如何做出 胜过 万龙洲海鲜的 双味腊肠芋头煲
  16. 英特尔DRM内核驱动程序默认启用PSR2省电功能
  17. Mysql分区表概述、分区类型、分区管理
  18. IT大侦“碳”:VxRail的可持续法宝
  19. 再谈OT算法的协同文档制作的底层基础架构记录
  20. 小x与三角形 c语言 1秒,[2019年第一水] 小x与神牛

热门文章

  1. 开关电源环路补偿设计及调节笔记
  2. Java之于Javascript就好比Car(汽车)之于Carpet(地毯)。
  3. 小白程序员的学习路线
  4. 细说设计模式七大原则(7):合成复用原则
  5. 圆柱体的投影特点_圆柱体三面投影作图方法分析
  6. Linux 统计一段时间内的文件大小
  7. 爬取雪球网股票信息(一)
  8. 计算机ccf试题答案,【计算机本科补全计划】CCF 2017-03 试题初试
  9. 激光雷达与相机融合(五)-------ros实时版点云投影到图像平面
  10. 【Tyvj1922】Freda的迷宫