分类

课内:
不限
类型:
不限 毕业设计 课程设计 小学期 大作业
汇编语言 C语言 C++ JAVA C# JSP PYTHON PHP
数据结构与算法 操作系统 编译原理 数据库 计算机网络 软件工程 VC++程序设计
游戏 PC程序 APP 网站 其他
评分:
不限 10 9 8 7 6 5 4 3 2 1
年份:
不限 2018 2019

资源列表

  • 基于JSP实现的学院成绩管理系统

    一、需求分析学院管理系统中学生成绩管理是重要的一环,本系统旨在让学生、班级管理员、学院管理员可以从不同角度查看学生的成绩信息。同时学院管理员可以进行信息的录入。三种用户分别拥有相应的权限。
    1.1 用户角度需求分析用户分为三种:普通学生、班级管理员和学院管理员。其中:
    班级学生可以查看自己已修课程的成绩,并且通过第几学期、课程是否通过、课程类别来组合查询自己的课程情况。下载自己成绩单。
    班级管理员可以查看班级的总体成绩和班级学生的基本成绩信息。下载班级成绩单。以及进入自己所管理班级学生主页的权限。
    学院管理员可以通过 Excel 文件录入学生信息、课程信息、学生成绩信息,还可以录入学生项目信息和学生竞赛信息。可以查看各专业基本成绩信息,查看每班的基本成绩信息,查看每班各学科详细成绩。分专业下载成绩单。以及进入班级管理员主页和学生主页的权限。
    1.2 界面功能角度分析
    登录界面:提供三个权限的用户登录
    注册界面:提供普通学生和班级管理员注册
    修改密码界面:提供普通学生和班级管理员修改密码
    学生界面:查看自己已修课程的成绩,通过第几学期、课程是否通过、课程类别来组合查询自己的课程情况。已修学分和剩余应修学分。下载成绩单
    班级管理员界面:查看班级基本信息,查看班级各个学生的基本成绩。下载成绩单。进入班级学生界面
    学院管理员界面:分专业查看专业基本信息,每个专业各班的基本成绩,查询班级各科成绩。通过 Excel 文件批量录入学生信息、课程信息、成绩信息。单个录入学生项目、竞赛情况信息。进入班级管理员界面

    二、系统功能分析系统的功能都是围绕从不同角度查看学生成绩信息开发的。同时进行了不同用户权限的控制和数据插入数据库之前的校验。
    权限由低至高一共分为三层:班级学生、班级管理员、学院管理员。高级权限用户可享有较低级权限用户的所有服务。
    2.1 注册在注册界面选择类别进行注册。普通学生选择班级学生,输入账号密码注册。班级管理员选择班级管理员,输入账号密码注册。学院管理员有默认账号,不提供注册服务。
    错误提示及原因:

    学号不存在:学院管理员未导入此学号相关信息
    学号已注册过:此学号已被注册
    格式错误:账号、密码不和要求


    2.2 登录在登录界面选择类别进行登录。普通学生选择班级学生,输入账号密码登录。班级管理员选择班级管理员,输入账号密码登录。学院管理员选择任一个输入账号密码登录。类别选择错误会登录失败。
    错误提示及原因:

    账号或密码错误:账号密码不匹配或类别选择错误
    学号未注册学号未注册:此学号未注册过
    格式错误:账号、密码不和要求
    班级不存在:当前系统中未查找到需要注册的班级的信息


    2.3 修改密码修改密码的进入方式为在学生界面和班级管理员界面点击右上角导航栏后选择修改密码一项进入。学院管理员不提供修改密码服务。
    错误提示及原因:

    旧密码错误:输入的旧密码和当前用户的密码不一致
    格式错误:旧密码、新密码格式不和要求

    2.4 我的主页我的主页的进入方式为在自己主页点击右上角导航栏后选择我的主页一项进入。
    当前用户若跳转到其他页面时提供跳转至自己主页的服务。
    2.5 账号注销账号注销的进入方式为在学生界面点击右上角导航栏后选择账号注销一项进入。
    用户一旦注销会删除他/她在本系统的所有信息。另外两类用户不提供注销服务。
    2.6 退出系统退出系统的进入方式为在自己主页点击右上角导航栏后选择退出系统一项进入。
    用户一旦点击退出系统,会删除本次会话在服务器端保存的所有的信息。页面会自动跳转至登录界面。

    2.7 学生主页班级学生可从登录界面进入,班级管理员可以从班级管理员界面进入,学院管理员进入班级管理界面后再进入。
    学生主页提供查看自己的基本成绩信息服务;由学期、类别、是否通过组合查询自己的成绩服务;已修学分、剩余应修学分服务;成绩单下载服务。

    2.8 班级管理员主页班级管理员可从登录界面进入。学院管理员可从学院管理界面进入。
    该主页提供查看本班级的基本成绩信息服务;查看每个同学的基本成绩信息服务;成绩单下载服务。点击学号可进入班级成员主页。
    其中基本信息是整个班级的基本信息。各同学详细信息一项只能查看已注册过本系统的学生,无法查看到未注册的学生的详细成绩信息。

    2.9 学院管理员主页学院管理员主页只能由学院管理员由登录界面进入。
    该主页分成三个子页面:计科页面、信息页面、信息录入页面。其中:

    计科页面查看计科基本信息,计科各班级基本信息,计科某班级某课程详细信息
    信安页面查看信安基本信息,信息各班级基本信息,信安某班级某课程详细信息
    信息录入界面可以通过 Excel 文件批量录入学生信息、课程信息、成绩信息。可以逐个添加学生项目信息、学生竞赛信息。

    说明:查看班级详细信息时只有存在选课记录的班级能被显示出来。无选课记录的班级不会显示。Excel 文件只能是 xlsx 文件,不能是 xls 文件。三种文件的格式要求必须和附录中提供的模板文件一致,且成绩文件中的学号和课程号录入必须先于成绩文件。
    数据导入的提示及原因:

    文件数据已导入:整个文件中的数据全部正确导入数据库
    文件不为空:未选择文件就点击上传按钮
    文件格式不允许:上传的文件不是 xlsx 文档
    数据导入失败:以上两种原因的错误外,其他任何异常都会被归纳为“数据导入失败” 。一般是由数据格式错误或者导入顺序不正确引起的问题

    专业基本信息

    班级课程详细成绩

    信息录入

    三、系统图解3.1 系统流程图图解
    3.2 核心功能图解
    四、数据库设计4.1 实体分析
    学生:学号、姓名、专业、班级、密码、GPA、级别
    课程:课程号、课程名、类型、学分、重要系数
    班级:班号
    班级管理员:账号、密码、级别
    竞赛:名称、年度
    项目:名称、年度

    一个学生可以选多门课,一门课可以被多个学生选择,每次选课有成绩、选课号、学期、学年。一个班级有多个学生,每个学生只有一个班级。一个班级有一个管理员,一个管理员管理一个班级。一个项目可以有多个学生参与,一个学生可以参与多个项目,每次参与项目有级别、是否是负责人。一个竞赛可以被多个学生参与,一个学生可以参与多个竞赛,每次参与有奖项、是否是负责人。
    4.2 E-R 图
    4.3 表结构
    学生:学号、密码、姓名、专业、班级、GPA、级别
    课程:课程号、课程名、类型、重要系数、学分、年度
    选课:选课号、学生学号、课程号、分数、年度、学期
    班级管理员:账号、密码、班号、级别
    竞赛和项目:ID、名称、年度、奖项/级别、是否是负责人、学号、类别

    4.4 视图系统中一共建了四个视图,以其中一个举例说明。班级管理员界面可以看见自己所管理班级学生的基本成绩信息来至于视图 classstudentscores。此视图是由学生表、课程表和选课表连接得到的。具体定义如下:
    SELECT `scores`.`stu_id` AS `id`, `studentinfos`.`name` AS `name`, `studentinfos`.`pwd` AS `pwd`, `studentinfos`.`cclass` AS `cclass`, `studentinfos`.`gpa` AS `gpa`, sum(`courses`.`credit`) AS `allcre`, `getStudentPassRate` (`scores`.`stu_id`) AS `passrate` FROM( (`studentinfos` JOIN `scores`) JOIN `courses` ) WHERE ( ( `studentinfos`.`id` = `scores`.`stu_id` ) AND ( `scores`.`cou_id` = `courses`.`id` ) AND (`scores`.`score` > 59) ) GROUP BY `scores`.`stu_id`
    4.5 触发器系统中使用到一次触发器。在学院管理员录入学生成绩时,触发器根据新录入的学生成绩的系统中已有的学生选课成绩计算出录入之后的学生 GPA。由于三种权限的用户都要使用 GPA,所以此触发器处在整个系统的核心位置。定义如下:
    BEGIN DECLARE myavg DOUBLE; DECLARE allcre DOUBLE; DECLARE temp DOUBLE; DECLARE sum DOUBLE DEFAULT 0.0; DECLARE t INTEGER; DECLARE t1 DOUBLE; DECLARE t2 DOUBLE; DECLARE done INT DEFAULT FALSE; DECLARE cur CURSOR FOR SELECT scores.score, courses.coefficient, courses.credit FROM studentinfos, scores, courses WHERE studentinfos.id = scores.stu_id AND scores.cou_id = courses.id AND stu_id = new.stu_id; DECLARE CONTINUE HANDLER FOR NOT found SET done = TRUE; SELECT SUM(courses.credit) INTO allcre FROM studentinfos, scores, courses WHERE studentinfos.id = scores.stu_id AND scores.cou_id = courses.id AND stu_id = new.stu_id AND score >= 60; OPEN cur; read_loop : LOOP FETCH cur INTO t, t1, t2; IF done THEN LEAVE read_loop; END IF; IF (t < 60) THEN SET temp = 0.0; END IF; IF (t >= 60) THEN SET temp = 1.0; END IF; IF (t >= 64) THEN SET temp = 1.6; END IF; IF (t >= 66) THEN SET temp = 1.7; END IF; IF (t >= 68) THEN SET temp = 2.0; END IF; IF (t >= 72) THEN SET temp = 2.3; END IF; IF (t >= 75) THEN SET temp = 2.7; END IF; IF (t >= 78) THEN SET temp = 3.0; END IF; IF (t >= 82) THEN SET temp = 3.3; END IF; IF (t >= 85) THEN SET temp = 3.7; END IF; IF (t >= 90) THEN SET temp = 4.0; END IF; SET sum = temp * t1 * t2 + sum; END LOOP; CLOSE cur; SET myavg = sum / allcre; UPDATE studentinfos SET gpa = myavg WHERE id = new.stu_id; END
    4.6 储存过程系统使用到一次存储过程。在获得班级总体的 GPA 时,使用了带输入输出参数的储存过程。参数:IN classID varchar(20),OUT avgpa double。定义如下:
    BEGIN DECLARE cgpa DOUBLE; DECLARE sum DOUBLE DEFAULT 0.0; DECLARE done int DEFAULT FALSE; DECLARE num int; DECLARE cur cursor for select gpa from studentinfos where cclass = classID; DECLARE CONTINUE HANDLER for not found set done = TRUE; set sum=0.0; set num=0; open cur; read_loop:LOOP FETCH CUR INTO cgpa; if done then leave read_loop; end if; set sum = sum + cgpa; set num = num+1; end loop; close cur; set avgpa = sum/num; SELECT sum,avgpa; END
    4.7 游标系统中使用到了两次游标及游标的循环。以触发器中的游标举例说明:
    DECLARE t INTEGER;DECLARE t1 DOUBLE;DECLARE t2 DOUBLE; DECLARE done INT DEFAULT FALSE; DECLARE cur cursor for SELECT scores.score, courses.coefficient, courses.credit from studentinfos, scores, courses where studentinfos.id = scores.stu_id and scores.cou_id = courses.id and stu_id = new.stu_id; DECLARE CONTINUE HANDLER for not found set done = TRUE; SELECT SUM(courses.credit) into allcre from studentinfos, scores, courses where studentinfos.id = scores.stu_id and scores.cou_id = courses.id and stu_id = new.stu_id and score>=60; open cur;read_loop:loop FETCH cur into t, t1, t2;
    4.8 函数系统中共使用了 6 次函数。以获得班级挂科率函数举例说明:
    参数:classID varchar(20);
    返回类型:double
    定义:
    BEGIN DECLARE sum DOUBLE; DECLARE notPassSum DOUBLE; select COUNT(*) into sum from scores,studentinfos where scores.stu_id = studentinfos.id and studentinfos.cclass = classID; select COUNT(*) into notPassSum from scores,studentinfos where scores.stu_id = studentinfos.id and studentinfos.cclass = classID and scores.score < 60; if(sum = 0) THEN return 0; end if; RETURN notPassSum/sum; END
    4.9 索引系统中除了 Navicat 自动添加的索引之外,使用到一次索引。在选课表中给成绩加上降序索引,因为后台获得的数据很多都是按成绩降序获得的。
    定义:
    create INDEX scoredesc on scores(score DESC);

    4.10 关系完整性
    实体完整性:主键均不为空且不重复
    域的完整性:成绩信息中的成绩、年度、学期默认值为 NULL
    参照完整性:成绩信息中的学号参照学生信息中的学号,成绩信息中的课程号参照课程信息中的课程号,项目竞赛信息中的学号参照学生信息中的学号。删除和更新采取的操作都是级联

    成绩表的完整定义如下:
    CREATE TABLE `scores` ( `id` INT (20) NOT NULL AUTO_INCREMENT, `stu_id` VARCHAR (20) NOT NULL, `cou_id` VARCHAR (20) NOT NULL, `score` INT (20) DEFAULT NULL, `year` INT (20) DEFAULT NULL, `term` INT (20) DEFAULT NULL, PRIMARY KEY (`id`), KEY `cou_id` (`cou_id`), KEY `stu_id` (`stu_id`), KEY `scoredesc` (`score`), CONSTRAINT `scores_ibfk_1` FOREIGN KEY (`cou_id`) REFERENCES `courses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `scores_ibfk_2` FOREIGN KEY (`stu_id`) REFERENCES `studentinfos` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = INNODB AUTO_INCREMENT = 443 DEFAULT CHARSET = utf8
    五、后台开发数据库一端除了使用基本的增删查改,还使用到了视图、触发器、存储过程、游标、函数、索引等技术。但如索引等技术不能在后台代码中很好的体现出来。所以将能在后台中明显体现的技术列举如下。
    例中的代码为 Dao 层的代码,即 sql 语句。事务的控制在 Service 层中。
    5.1 增加系统中多次使用到了增加,以导入学生信息时的增加为例说明:
    public void insert(StudentInfos studentInfo) throws SQLException{ String sql = "insert into studentinfos values(?,?,?,?,?,?,?)"; queryRunner.update(sql, studentInfo.getId(), studentInfo.getPwd(), studentInfo.getName(), studentInfo.getMajor(), studentInfo.getCclass(), studentInfo.getGpa(), studentInfo.getLevel()); }
    5.2 删除系统中多次使用到了删除,以学生注销时的级联删除为例:
    public void signOffAccount(String id) throws SQLException{ String sql1 = "delete from candp where stuid = ?"; String sql2 = "delete from scores where stu_id = ?"; String sql3 = "delete from studentinfos where id = ?"; queryRunner.update(sql1, id); queryRunner.update(sql2, id); queryRunner.update(sql3, id); }
    5.3 修改系统中使用到的修改不多,以修改密码为例:
    public void updatePwd(String id, String pwd) throws SQLException{ String sql = "update studentinfos set pwd = ? where id = ?"; queryRunner.update(sql, pwd, id); }
    5.4 查找系统中多次使用到了查找。以查询班级某课程详细信息为例:
    public ArrayList<StudentCourseScoresBean> getCourseScores(String id) throws SQLException{ String sql = "select name as name, type as type, score as score, coefficient as coefficient, score as gpa, " + "credit as credit from courses, scores where courses.id = scores.cou_id and stu_id = ?"; ArrayList<StudentCourseScoresBean> query = (ArrayList<StudentCourseScoresBean>) queryRunner.query(sql, new BeanListHandler<StudentCourseScoresBean>(StudentCourseScoresBean.class), id); return query; }
    5.5 调用函数系统多次调用了函数,以获得班级挂科率为例:
    public Double getClassNotPassRate(String id) throws SQLException{ String sql = "select getClassNotPassRate(?) as rate"; Double rate = (Double) queryRunner.query(sql, new ScalarHandler("rate"), id); return rate; }
    5.6 调用存储过程系统中使用到了一次存储过程,代码如下:
    private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver"; private static final String URL = "jdbc:mysql:///College-Achievement-Management-System"; private static final String USERNAME = "root"; private static final String PASSWORD = "root"; public Double getClassGpa(String id) throws SQLException, ClassNotFoundException{ Class.forName(DRIVER_CLASS); Connection connection = (Connection) DriverManager.getConnection(URL, USERNAME,PASSWORD); String sql = "{CALL getClassGpa(?,?)}"; CallableStatement cstm = connection.prepareCall(sql); cstm.setString(1, id); cstm.registerOutParameter(2, Types.DOUBLE); cstm.execute(); return cstm.getDouble(2); }
    5.7 事务控制系统中多次使用到了事务的控制,以增加成绩信息为例。
    public void add(ScoresInfos si) { Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); try { cid.add(si); } catch (SQLException e) { e.printStackTrace(); tx.rollback(); } tx.commit(); }
    说明:Transaction 是一个事务控制的类。beginTransaction()是用来开启事务的方法。rollback()事务回滚的方法。commit()是事务提交的方法。
    六、总结6.1 课程设计成果此次数据库原理课程设计没有选择实验指导书上的题目,而是自己想了一个题目,但题目灵感来至于实验指导书上的学校成绩管理系统。因为综合自己能力和时间考虑,做学校级别的难度太大,所以选择做了学院级别的成绩管理系统。
    该系统以 Java Web 技术为基础,实现了学院成绩管理的基本功能。学院管理员可以进行信息的录入,专业信息的查询。班级管理员可以进行班级信息的查询。学生可以进行自己成绩的查询。而且高权限用户兼有低权限用户的功能。
    除了功能的开发,对于非法访问也进行了处理,如低权限用户访问高权限用户页面等情况做了拦截处理。提高了系统的健壮性。
    6.2 不足及改进方法系统的健壮性不够。尤其是在通过 Excel 文件导入数据的时候,对相应错误处理不够完善,用户只知道有问题,不知道到底哪里出了问题。没有使用 Spring 层框架,导致代码冗余情况较为严重。没有使用到高级查找如外链接的技术。
    改进方法为不通过 Excel 文件导入数据,通过 csv 文件导入数据更方便快捷,而且容错性较好。使用 Spring 框架减小代码冗余性。增加系统功能以使用到外链接的功能。
    6.3 收获过本次数据库系统课程设计掌握了基础的以 Java 为核心的网站开发技术。掌握了数据库的分析设计。并且综合应用数据库系统原理课上讲的增删查改、视图、存储过程、游标、触发器、函数、关系完整性等知识到数据库系统课程设计中。提升了自己的专业竞争力。
    2 评论 14 下载 2019-02-15 21:03:33 下载需要12点积分
  • 基于C语言实现的超市管理系统

    1 需求分析超市随着市场经济和现代信息技术的的发展,不可必要的要卷入信息现代化的大潮,如何使用现代化的工具,使企业和经营者个人在最小的投入下获取最大的回报,成为每一个人的梦想。因此,在超市管理中引进现代化的办公软件,就成为时下最好的解决办法。使用软件办公,不仅能使经营者的劳力资本减少,同时能使超市的管理更规范更合理,解决了超市中用于管理进出货以及购买、库存等众多繁琐、工作量巨大从而导致耗费人员过多,超市经营紊乱等众多问题。
    1.1 主要功能
    超级管理员模块:(需帐号登录)

    添加管理员删除管理员
    管理员模块:(需帐号登录)

    商品信息录入(编号、名称、单价、库存)商品信息修改(修改商品的各种信息)商品信息查询(根据所输入的商品名字,编码查询库存信息)商品信息删除(从商品文件中删除商品信息)商品信息排序(按编号,单价,库存3种模式进行排序)输出商品全部库存信息删除普通用户功能(管理员有权限删除普通用户帐号)
    普通用户模块:(需帐号登录)

    新用户注册用户登录:
    商品查询商品排序输出商品全部库存信息购买商品(通过用户余额来进行购买)充值(通过输入充值卡卡号对用户余额充值)修改用户密码


    1.2 运行环境
    操作系统:Windows NT/2000/XP/VISTA/WIN7/WIN8/WIN10
    开发平台:Microsoft Visual Studio 2012

    1.3 文件说明
    程序源代码(超市管理系统.cpp)
    程序运行文件(超市管理系统.exe)
    管理员信息(管理员信息.txt)
    普通用户信息(普通用户信息.txt)
    商品信息(商品信息.txt)

    2 总体方案设计2.1 设计方案整个超市管理系统分为3个模块,超级管理员+管理员+普通用户,其中:

    管理员可以实现商品信息的录入,修改,查询等管理操作,同时还拥有对普通用户帐号的管理
    超级管理员是最高执行者,拥有对管理员帐号的操作权限,可以对管理员帐号进行添加或删除
    普通用户模块,由于考虑到该程序的真实性,所以实现了普通用户的注册和登录功能,用户要进行购物,必须使用帐号(可自行注册,无须经过管理员),其中普通用户具有商品查询等一部分功能。特色功能是具有帐号余额功能,同时购物可以进行充值功能(输入充值卡卡号,类似于购买充值卡来充值)

    2.2 主要结构
    超级管理员模块:(需帐号登录)

    添加管理员删除管理员
    管理员模块:(需帐号登录)

    商品信息录入(编号、名称、单价、库存)商品信息修改(修改商品的各种信息)商品信息查询(根据所输入的商品名字,编码查询库存信息)商品信息删除(从商品文件中删除商品信息)商品信息排序(按编号,单价,库存3种模式进行排序)输出商品全部库存信息删除普通用户功能(管理员有权限删除普通用户帐号)
    普通用户模块:(需帐号登录)

    新用户注册用户登录:
    商品查询商品排序输出商品全部库存信息购买商品(通过用户余额来进行购买)充值(通过输入充值卡卡号对用户余额充值)修改用户密码


    2.3 程序功能和流程图由于本程序模块功能较多,有超级管理员,管理员和普通用户,共3个模式的功能,流程图较大,因此分为3个子图。
    超级管理员模块

    管理员模块

    普通用户模块

    2.4 数据结构和算法的设计说明本程序有3个数据结构:管理员,普通用户,商品共3个结构体。其中程序拥有超级管理员、管理员和普通用户共3种身份,运用链表来存储和读取所保存的信息。
    2.4.1 结构体类型一开始选择模块,输入帐号和密码,进行验证,是否正确。正确就进入功能模块。
    typedef struct custom* cpointer;//结点指针类型struct custom{ string custom_ID;//帐号 string custom_name;//姓名 string custom_mima;//密码 double money;//账户余额 cpointer next;};typedef cpointer clklist;//单链表类型,即头指针类型
    其中,管理员、普通用户、商品都是定义结构体,而后进入系统,一开始便定义相对应的链表进行存储和获取已保存的信息。
    2.4.2 算法设计排序算法
    for(int i=0;i<Goodnum;i++){ for(int j=Goodnum;j>=i+1;j--){ if(Go.Good[j].Good_ID<Go.Good[j-1].Good_ID) {//比较编号大小,小的在前面,大的在后面 flag=1; p=Go.Good[j]; Go.Good[j]=Go.Good[j-1]; Go.Good[j-1]=p; } }
    通过对相邻2个商品的编号不断比较,排序,运用2个for循环,比较编号大小,小的在前面,大的在后面。不断变换,最终排序完成。
    2.5 程序关键源代码说明程序中拥有3个身份:超级管理员,管理员,普通用户。不同身份之间函数都差不多,因此将函数直接展示,不说明为哪个身份的权限功能。
    custom_ender函数:登录验证函数。对输入的帐号和密码进行验证检索,正确就进入对应的身份模块。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p,而后对p进行检索,如果p链表中的用户信息与输入的用户信息(帐号+密码)相同,就返回1;不同就显示“用户帐号不存在”,同时返回0。
    int custom_ender(clklist &head,string ID,string mima){ cpointer p; p=head; while(p!=NULL) { if(p->custom_ID==ID&&p->custom_mima==mima) return 1; else p=p->next; } cout<<"用户帐号不存在!"<<endl; return 0;}
    custom_creat函数:注册函数。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p,而后输入注册用户的各种信息(帐号,密码,姓名),如果输入的帐号ID与已保存的用户帐号相同,就显示已存在,提示重新输入。最后将输入的新注册用户信息运用头插法插入,保存到”普通用户信息.txt”文件中保存
    void custom_creat(clklist &head){ cpointer s,p; string ID,name,mima; int sign=1,flat=1; while(sign!=0){ flat=1; cout<<"请输入用户帐号"<<endl; cin>>ID; p=head->next; while(p!=NULL){ if(p->custom_ID==ID) flat=0; p=p->next; } if(flat==0) { cout<<"用户帐号已存在,请重新输入"<<endl; continue; } cout<<"请输入用户密码"<<endl; cin>>mima; cout<<"请输入用户姓名"<<endl; cin>>name; s=new custom; s->custom_ID=ID; s->custom_name=name; s->custom_mima=mima; s->money=0; s->next=head->next;//使用头插法建表 head->next=s; buyernum++;//输入一个用户信息,buyernum自加1 custom_save(head); cout<<"是否继续注册?<继续>请按1 <结束>请按0"<<endl; cin>>sign;//while循环判断条件,所以不需要用if }}
    custom_get函数:从文件获取用户信息函数。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p, 而后运用一个for循环,将用户信息从“普通用户信息.txt“全部导入到p链表中,返回给系统。
    clklist custom_get(clklist &buyer){ cpointer s,p;//s用于存储用户信息,p用于buyer的连接 string numname; string ID,name,mima; double money; buyer->next=NULL; p=buyer; ifstream ifile("C:\\普通用户信息.txt",ios::in); if(!ifile){ cerr<<"用户信息查询出错"<<endl;return 0; } ifile>>numname; ifile>>buyernum;//从文件中提取用户个数,用于for循环 for(int i=1;i<=buyernum;i++){ ifile>>ID; ifile>>name; ifile>>mima; ifile>>money; s=new custom; s->custom_ID=ID; s->custom_name=name; s->custom_mima=mima; s->money=money; s->next=p->next; p->next=s; } buyer=p; ifile.close(); return buyer;}
    Good_add函数:商品信息录入函数。把包含商品信息的链表Goods传入该函数,输入商品编号,if(Good_ender1(Goods,ID)==0)进行检索是否商品已存在,存在就提示重新输入,不存在就继续录入商品信息,导入到Goods链表中,最后运用Good_save(Goods)保存全部信息到“商品信息.txt”文件中。
    void Good_add(sqlist &Goods){ string ID,name; double piece; int last,sign,flat=1;//last为商品库存,sign用于判断选择 fstream ifile("C:\\商品信息.txt",ios::in); for(;flat!=0;) { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==0) { cout<<"请输入商品名称:"; cin>>name; if(Good_ender2(Goods,name)==0) { cout<<"请输入商品单价:"; cin>>piece; cout<<"请输入商品数量:"; cin>>last; Goods.Good[Goodnum].Good_ID=ID; Goods.Good[Goodnum].Good_name=name; Goods.Good[Goodnum].piece=piece; Goods.Good[Goodnum].last=last; Goodnum++;//添加完信息就自加1 Good_save(Goods);//添加完就保存至商品信息.txt cout<<"是否继续录入?<继续>请按1 <结束>请按0"<<endl; cin>>sign; if(sign==0) break; } else {cout<<"商品名称已存在!<重新输入>请按1 <结束>请按0"<<endl; cin>>flat;} } else {cout<<"商品编号已存在!<重新输入>请按1 <结束>请按0"<<endl; cin>>flat;} }}
    Good_change函数:商品信息修改函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种修改模式(按编号检索修改,还是按名称检索修改)。如果选择按编号检索修改,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后输入修改后的商品信息,保存至文件中;按名称检索修改类似。最后修改完后,会提示是否继续修改,如果不继续就返回用户功能界面,执行其他功能。
    void Good_change(sqlist &Goods){ string ID,name; int sign;//sign用于定位要修改商品的位置 int a,flat=1;//a用于switch for(;flat!=0;){ cout<<"<输入要修改的商品编号>请按1 <输入要修改的商品名称>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1) { sign=Good_locate1(Goods,ID); cout<<"商品编号:"<<Goods.Good[sign].Good_ID<<endl; cout<<"商品名称:"<<Goods.Good[sign].Good_name<<endl; cout<<"商品单价:"<<Goods.Good[sign].piece<<endl; cout<<"商品库存:"<<Goods.Good[sign].last<<endl; cout<<"请输入修改后的信息:"<<endl; cout<<"商品编号:"; cin>>Goods.Good[sign].Good_ID; cout<<"商品名称:"; cin>>Goods.Good[sign].Good_name; cout<<"商品单价:"; cin>>Goods.Good[sign].piece; cout<<"商品库存:"; cin>>Goods.Good[sign].last; Good_save(Goods);//保存信息 cout<<"修改成功"<<endl; } else cout<<"商品不存在!"<<endl; break; } case 2: 大致与编号模式相同 else cout<<"商品不存在!"<<endl; break; } }//switch的 cout<<"<继续修改>请按1 <退出>请按0"<<endl; cin>>flat; }//for循环的}
    Good_inquire函数:商品信息查询函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种查询方式(按编号检索查询,还是按名称检索查询)。如果选择按编号检索查询,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后输出该商品信息的全部信息;按名称检索查询类似。最后查询完后,会提示是否继续查询,如果不继续就返回用户功能界面,执行其他功能。
    void Good_inquire(sqlist &Goods){ string ID,name; int a,sign,flat=1; for(;flat!=0;){ cout<<"<按商品编号查询>请按1 <按商品名称查询>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1) { sign=Good_locate1(Goods,ID); cout<<"商品编号:"<<Goods.Good[sign].Good_ID<<endl; cout<<"商品名称:"<<Goods.Good[sign].Good_name<<endl; cout<<"商品单价:"<<Goods.Good[sign].piece<<endl; cout<<"商品库存:"<<Goods.Good[sign].last<<endl; } else cout<<"商品不存在!"<<endl; break; } case 2: 大致与编号模式相同 else cout<<"商品不存在!"<<endl; break; } }//switch的 cout<<"是否继续查询?<继续>请按1 <结束>请按0"<<endl; cin>>flat; if(flat==0) break; }//for循环的}
    Good_delete函数:商品信息删除函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种删除方式(按编号检索删除,还是按名称检索删除)。如果选择按编号检索删除,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后使用for(int i=sign; i\<Goodnum; i++)将该位置后的商品全部前移1位,覆盖掉该位置,最后保存删除后的商品信息至“商品信息.txt”中;按名称检索删除类似。最后删除完后,会提示是否继续删除,如果不继续就返回用户功能界面,执行其他功能。
    void Good_delete(sqlist &Goods){ int a,sign,flat=1; string ID,name; for(;flat!=0;){ cout<<"<输入要删除的商品编号>请按1 <输入要删除的商品名称>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { cout<<"请输入要删除的商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1){ sign=Good_locate1(Goods,ID); for(int i=sign;i<Goodnum;i++){ Goods.Good[i]=Goods.Good[i+1]; } Goodnum--; Good_save(Goods); cout<<"删除成功!"<<endl; } else cout<<"商品不存在!"<<endl; break; } case 2: 大致与编号模式相同 else cout<<"商品不存在!"<<endl; break; } }//switch的 cout<<"是否继续删除?<继续>请按1 <结束>请按0"<<endl; cin>>sign; if(sign==0) break; }//for循环的}
    Good_range函数:商品信息排序函数。把包含商品信息的链表Go传入该函数,选择排序模式(按编号,单价,库存进行排序),运用2层for循环,使用冒泡法进行排序,从尾部向头部进行对比检索,小的放前面,大的放后面,排序完之后就将排序后的商品信息显示给用户;3种模式大致相同。最后排序完后,会提示是否继续执行,如果不继续就返回用户功能界面,执行其他功能。
    void Good_range(sqlist Go){ Goods p; p.piece=0; p.last=0; int a,flag=0,flat=1; for(;flat!=0;){ cout<<"<按商品编号排序>请按1 <按商品单价排序>请按2 <按库存数量排序>请按3 <退出>请按0"<<endl; cin>>a; if(a!=0&&a!=1&&a!=2&&a!=3) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { for(int i=0;i<Goodnum;i++){ for(int j=Goodnum;j>=i+1;j--){ if(Go.Good[j].Good_ID<Go.Good[j-1].Good_ID){//比较编号大小,小的在前面,大的在后面 flag=1; p=Go.Good[j]; Go.Good[j]=Go.Good[j-1]; Go.Good[j-1]=p; } }//jfor的 if(!flag) break; }//ifor的 cout<<"商品编号"<<setw(10)<<"商品名称"<<setw(10)<<"商品单价"<<setw(10)<<"商品库存"<<endl; for(int i=1;i<=Goodnum;i++){ cout<<Go.Good[i].Good_ID<<setw(13)<<Go.Good[i].Good_name<<setw(8)<<Go.Good[i].piece<<setw(10)<<Go.Good[i].last<<endl; } break; } case 2: 大致与编号模式相同 case 3: 大致与编号模式相同 case 0:return; }//switch的 }//最外层for的
    Good_buy函数:购买商品函数。把包含商品信息的链表Goods以及包含用户信息的链表head传入该函数,选择购买模式(输入编号或名称进行购买),如果输入的商品编号与Goods中的商品信息相同,就提示购买数量,这时如果购买数量超过库存数量会提示“库存不足”,然后重新输入;如果购买商品所支付的钱超过用户的余额,则提示“余额不足”,是否前往充值页面进行充值。充值模块下面会展示。购买完商品后,用户可以继续购买,也可以返回用户功能界面。
    void Good_buy(sqlist &Goods,clklist &head,string cID){//cID为用户帐号 string ID,name; int a,shu,sign,flat=1; cpointer p; p=custom_locate(head,cID); for(;flat!=0;){ cout<<"<输入商品编号购买>请按1 <输入商品名称购买>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"输入有误,请重新输入"<<endl;continue;} switch (a) { case 1: { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1) { sign=Good_locate1(Goods,ID); cout<<"请输入购买数量:"; cin>>shu; if(shu<=Goods.Good[sign].last){ if(p->money<Goods.Good[sign].piece*shu) {cout<<"余额不足,请充值!"<<endl; cout<<"是否前往充值?<充值>请按1 <否>请按0"<<endl; cin>>flat; if(flat==0) break; if(flat==1) return;} Goods.Good[sign].last=Goods.Good[sign].last-shu; cout<<"购买成功"<<endl; p->money=p->money-Goods.Good[sign].piece*shu;//账户余额减少,扣费成功 custom_save(head); cout<<"账户余额:"<<p->money<<endl; Good_save(Goods); } else cout<<"库存不足!"<<endl; } else cout<<"找不到相应商品,购买失败"<<endl; break; } case 2:与编号模式类似 }//switch的 cout<<"是否继续购物?<继续>请按1 <结束>请按0"<<endl; cin>>flat; if(flat==0) break; }//for的}
    custom_addmoney函数:余额充值函数。余额是用户帐号中的一个成员,初始为0,用户在购物的时候余额会减少,如果余额不足就无法进行购物,需要进行充值,充值是输入系统给定的充值卡卡号进行充值,这是本系统的一大亮点。把包含用户信息的链表head传入该函数,运用 p=custom_locate(head,ID);定位是哪个用户的帐号要进行充值,其中,系统设定了2种充值卡“asd500”和“asd1000”分别可以充值500和1000元,这类似与用户购买不同的充值卡给自己的账户进行充值。用户输入充值卡卡号,进行检索是否与系统设定的充值卡卡号相同,如果相同就充值相应的金额;如果不同,就提示“充值卡无效”。最后充值后,用户可以选择继续充值或者返回用户功能界面进行购物等其他操作。
    void custom_addmoney(clklist &head,string ID){ cpointer p; int sign=1; p=custom_locate(head,ID); string acard,card1="asd500",card2="asd1000"; while(sign!=0){ cout<<"请输入您获得的充值卡卡号:"; cin>>acard;//acard是用户获得的充值卡 if(acard!=card1&&acard!=card2) cout<<"充值卡无效"<<endl; if(acard==card1) { p->money+=500; cout<<"充值成功!"<<endl; cout<<"账户余额:"<<p->money<<endl; }; if(acard==card2) { p->money+=1000; cout<<"充值成功!"<<endl; cout<<"账户余额:"<<p->money<<endl; }; custom_save(head);//充值成功 cout<<"是否继续充值?<继续>请按1 <结束>请按0"<<endl; cin>>sign;//while循环判断条件,所以不需要用if }
    3 程序功能测试一开始进入系统,初次使用会提示文件打开失败,是正常的,不影响功能。由于原本的“管理员信息.txt”“普通用户信息.txt”“商品信息.txt”是空的,当录入信息就不会有提示了。进入身份选择(都要帐号和密码)

    选择1进入超级管理员,(帐号:asd,密码123),先添加管理员。

    选择1,添加管理员信息(帐号+密码+姓名),添加完后可以选择继续添加或返回

    选择2,输入要删除的管理员帐号,直接删除管理员

    添加完管理员后,可返回主菜单,进入管理员模式,输入刚刚添加的管理员帐号+密码,进入管理员模式

    功能1,进入商品录入功能,输入商品的信息(编号,名称,单价,库存),当录入成功之后,管理员可以选择继续录入或返回(该模块当录入编号和名称和已录入的信息相同会提示出错,重新录入)

    功能2,可进行商品修改,有2种模式进行选择,输入商品编号101后,显示“商品信息.txt“文件中的商品信息,而后管理员可以输入修改后的信息

    功能3,可以进行商品信息查询,可以查询到刚刚修改的联想笔记本

    功能4,可以进行删除已录入的商品信息,例如,删除刚录入的联想笔记本

    删除后,进入查询功能查看联想笔记本,不存在,表明删除成功~ ~

    功能5,进行已录入商品信息排序,可选择(编号,单价,库存)进行从小到大排序,编号也是可以的

    功能6,输出全部商品信息

    功能7,删除普通用户,如果已经有普通用户,只需要输入普通用户的帐号就可以直接删除
    进入普通用户模块,如果没有帐号是无法查看和购物的,因此消费者可以自行注册

    注册完,就可以登录进入用户模块进行购物了

    其中,商品查询,排序,库存是和管理员一样的,就不展示了
    功能4,购买商品,一开始,由于没充值时,用户余额为0,余额不足,无法购买,用户可以返回,进行充值后购买。如果充值后,余额充足就可以购买了,购买后,余额相应减少

    这里我先前往充值2000元,后购买如下,主机单价50,购买后余额为1950,扣费成功

    功能5,用户可以随时修改自己的账户密码,保护自己的财产
    功能6,就是充值了,输入系统给定的充值卡卡号,有(asd500和asd1000)

    由于刚余额1950,现在输入卡号asd1000,成功充值1000,剩余2950
    4 总结这次选择了做“超市管理系统”,在完成基本功能之后,觉得要真正实现成功的超市管理系统,必须要有个人的帐号,因此增加了普通用户注册和帐号模式,同时管理员和超级管理员也都是用帐号+密码进入。普通用户可以自行注册,拥有自己的私人帐号。同时,超市管理系统普通用户在进行购买之后,应该是要有余额的,因此添加了余额成员。拥有余额成员之后,就想到,用户需要购买东西,余额不足就需要进行充值,为了实现真实性,就选定,用户需要输入充值卡卡号进行充值。最终完美实现。
    这个系统,是使用链表实现的,由于之前的大作业是使用文件流,不是使用链表,因此这次的大作业就决定说要使用链表来实现。在编程过程中,也发现了很多的bug,最终还是一一解决。感觉自己的编程能力在不断的提高,无论是什么bug都可以自行调试解决。
    同时,在思考程序的框架功能时,也逐渐重视用户体验,人机交互。编写大作业,不再只是仅仅满足基本功能,在基本功能上,还添加其余用户体验好的功能(比如帐号登录,充值等等功能),感觉大作业让我学会了很多。
    2 评论 66 下载 2018-10-31 11:28:48 下载需要12点积分
  • 基于Android Studio实现的论坛网站Android客户端和JAVA EE后台

    第一章 概述1.1 开发环境本安卓程序在Windows 10系统下使用Android Studio开发,后台使用MyEclipse开发,测试环境为安卓系统5.1、4.4、4.3、5.0,屏幕尺寸5.0、5.1、5.5的安卓手机。
    1.2 安装配置本安卓程序要求安卓SDK为API level 15以上,target level为23,即,android 4.0.3到android 6.0。
    1.3 需求分析本程序为安卓APP开发项目,项目内容为IT主题的论坛开发。根据需求分析,需要一下功能:

    用户的登陆与注册功能
    用户权限包括管理员、版主、普通用户和游客身份登陆
    根据不同权限登录用户可以对帖子进行不同程度的管理,管理员可以查看、删除所有帖子,版主可以查看所有帖子、删除做属板块的帖子,普通用户和游客都只能查看帖子
    除了游客外所有用户都能发帖、回帖,游客不能发帖、回帖
    用户可以查看自己发的帖子并管理自己的帖子

    第二章 程序概要设计2.1 程序功能模块本安卓程序分为登陆注册模块、查看帖子模块、删除帖子模块、回复帖子模块。

    登陆注册模块是程序的入口,如果已经登陆过了又没有退出登陆,就可以自动登陆,如果没有账号,可以游客登陆
    查看帖子模块可以根据板块选择性查看所有帖子,已注册用户可以查看自己的帖子,帖子信息包括标题、内容、时间等
    删除帖子模块包括管理员可以删除所有帖子,版主可以删除所属板块的帖子,所有用户可以删除自己的帖子,游客不能使用删除功能,程序根据登陆用户的权限自动显示是否可以使用
    回复帖子模块用于已注册用户对帖子的回复,游客不能回复帖子

    2.2 流程图
    2.3 程序文件结构分析java文件夹下MyWork包内的java文件是每个布局对应的Activity,其中Circle是自定义的一个控件;control包下是两个适配器,包括主页面的适配器MainAdapter和回复页面的适配器LookAdapter,还有联网的工具类NetWord。

    res资源文件夹下的layout布局资源文件包括各个Activity的布局和listview的自布局,其中tool_bar是ToolBar的布局。

    menu文件夹下是两个ToolBar的菜单布局,values文件夹下使用到了strings文件和colors文件,特别的是attrs文件,这个是Circle自定义控件的配置文件。

    2.4 数据库设计本程序使用javaEE后台,数据库为sql server,包括card表、section表和userTable表,分别的字段如下:

    card:id、nameId、contents、date、title、sectionId、replyId、isTop、topDate
    section:id、name、host
    userTable:id、username、password、power、pic

    第三章 程序详细设计3.1 关键代码分析联网:使用java jdk自带的HttpURLConnection进行联网,并使用json进行数据传输。图3-1包括了链接网络的方法connect()、传参的输出流ObjectOutputStream,图3-2判断了状态码是否为200然后接收后台传过来的参数并处理返回,接收参数使用InputStream输入流。


    自定义适配器:先写了继承BaseAdapter的适配器类,这个项目中使用了两个适配器,分别为MainAdapter、LookAdapter,作为主界面和回复节目的适配器。两个泪重写了getView方法,处理每个listview中每个item的布局,以显示每一个帖子。
    侧滑菜单:在布局中使用DrawerLayout如图3-3,在Activity中使用ActionBarDrawerToggle作为侧滑开关,并实现开和关的监听,如图3-4。


    界面返回刷新:使用Intent跳转时用startActivityForResult,并重写onActivityResult方法,如图3-5。

    3.2 疑难问题解决用户权限识别:在第一次登陆成功后将后台返回的用户信息存进SharedPreferences,后面根据从中取出来的权限信息进行判断,然后决定是否显示相应按钮。

    第四章 程序的发布和测试4.1 发布过程安卓端的发布,将程序运行到手机,通过android studio的Logcat查看运行信息;
    JavaEE端的发布,将程序部署到Tomcat,同样通过myeclipse的Logcat查看运行信息。
    4.2 测试过程图4-1为登陆界面,点击注册按钮到如图4-2的注册界面,注册成功后跳转回登陆界面登陆。



    登录
    注册









    图4-3为管理员登陆的界面(还有打开侧滑菜单的状态),图4-4为版主和普通用户及游客登陆后的界面。



    管理员登录
    普通用户登录









    图4-5为游客登陆的侧滑菜单界面,与其他用户是不同的,只有一个选项,当其他用户登录时,可以点击右上角的笔进入发帖节目,如图4-6。



    侧滑菜单界面
    发帖









    第五章 分析与总结5.1 优点本安卓程序的优点在于界面简洁,有与服务器后台联系,交互友好,基础功能及部分拓展功能已经实现。
    5.2 缺点本安卓程序的缺点在于界面跳转仍有部分不流畅,因为代码效率问题有待改进,还有其他计划中的拓展功能由于时间关系还没实现。
    5.3 总结通过此次安卓大作业的开发,让我对安卓开发更加熟悉,对知识点的运用更加熟练,由于运用到了javaEE后台,使我对javaEE的熟练度也增加了。因为这次大作业的制作时间比较短,所以刺激了自己的潜力,锻炼了自己赶项目的感觉。
    第六章 参考目录[1] 《疯狂安卓讲义》 电子工业出版社 李刚 2015.8
    [2] 《android应用开发学习手册》 清华大学出版社 管蕾 2015.7
    9 评论 81 下载 2018-11-06 15:32:08 下载需要10点积分
  • 基于Python实现的搜索和推荐系统

    一、引言伴随着科技的不断进步,互联网,万维网的不断发展。我们越来越热爱万维网,也欣赏他的发展方式。20世纪90年代初,万维网还只是一个将文档联系起来的简单网络。如今,他已经成为了全球信息的框架。显然,如何表达万维网上的数据是下一步需要解决的问题。但这个问题并不简单。
    关联数据是万维网上表示和连接结构化数据的一系列技术。通过关联数据将万维网转换为一个全球性的数据空,我们称之为数据网(Web of Data)。通过关联数据SPARQL查询语言同时查询多个信息源的关联数据,并动态合并并查询结果,这样的方法是传统数据管理技术很难实现的或根本无法做到的。
    籍由关联数据技术,我们更容易和他人共享数据。理论上说,可以采用关联数据描述任何内容。万维网上的关联数据可以被发现,共享并与其他用户的数据进行合并。与传统的数据管理系统不同,关联数据将信息从专有容器中(proprietary container)中释放出来,任何人都可以使用这些信息。与其他数据一样,关联数据的质量和效用由数据使用者来负责评估。人们只信任可靠的数据。
    我们正是基于这样一个数据可靠、安全、数据之间可关联的关联数据技术,来实现我们对于搜索服务和基于语义的推荐服务。
    二、准备2.1 软件工程语言选择世界上有非常多的软件编译语言,主流的有C、C++、JAVA、PYTHON、C#等等。每一种编译语言都有他们自己的特点,每一种编译语言都有他们自己的库和相关的编译工具。用什么样的语言来实现我们搜索和推荐服务是首先要考虑的。
    搜索和推荐服务是一个对互联网信息资源进行搜索整理、分类,并储存在网络数据库中供用户查询的系统,包括信息收集,信息分类,和目标查询三个部分组成。
    从使用者的角度看,搜索和推荐服务提供一个包含搜索输入框的页面,在搜索框中输入词汇,通过浏览器提交给搜索后台服务引擎后,搜索后台服务引擎就会返回跟用户输入的内容相关的信息列表。其实这样的搜索后台服务引擎涉及到很多领域的理论和技术:数字图书馆,数据库,信息检索,信息提取,人工智能,机器学习,自然语言处理,计算机语言学,统计数据分析,数据挖掘,计算机网络,分布式处理等等,具有综合性和挑战性。
    在世界范围内,百度,GOOGLE,搜狗就是非常好的搜索引擎。通过学习这些搜索服务,我们发现他们都是通过Web来进行搜索服务的。
    因此我们确定我们的搜索和推荐服务也应当是通过TCP方式,HTTP协议,以Web的方式进行搜索和推荐服务,通过Web来实现搜索和推荐的交互功能。
    在实现Web这样的B/S架构时,我们发现两种语言适用于开发这样的服务程序。一个是Java语言,一个是Python语言。
    在Java语言中有Tomcat服务来实现网页与后台的相互传参,运算;在Python语言中有Callimachus和Django来实现网页与后台逻辑的通讯。
    通过对比Java和Python开发我们发现:

    Java开发所需要的JDK版本一旦安装完成,在同一台PC机上是需要通过卸载重新安装来实现;在Python中对于Python2.7和Python3,我们通过virtualenv和anaconda等虚拟容易来盛放不同的python版本只需要通过cmd(windows下)命令就可以实现
    Java中的库主要都是对于类型转换,和网页servlet方式的库;在python中不仅包含于网页的相关库,他更强大的是有很多算法库,由于python属于脚本语言,所有他所支持和库所涉及的功能范围比java库要更加多
    在Java中进行相关的SPARQL查询,需要安装jena,并将安装好的jena文件进行相应的环境变量配置;但是在python中对于sparqlwrapper,只需要通过cmd命令(pip install xxx)就可以静待电脑自动安装相应文件,而不需要配置相应的环境变量

    因此基于以上分析,我们最终选用python来作为我们的软件开发语言。
    2.2 服务器的选取一个好的关联数据开发平台有助于提高开发效率。Callimachus和Django都是这样的一种平台。
    2.2.1 Callimachus尽管Callimachus的开发者们将其定义为关联数据管理系统,但是将其视为关联数据的应用服务器更加合适。Callichus主要具备以下特征:

    模板系统能自动为OWL类(OWL class)的所有成员生成网页。严格来说,OWL类与RDF schema类本身或其子类并无二致(取决于所用的OWL配置文件)。简单起见,我们认为OWL类与RDF Schema类是等价的
    在运行时检索数据,并将其转换为RDF格式
    将SPARQL查询与URL关联起来,对查询进行参数化,并使用带有图标库(charting library)的查询结果
    PURL(持久化URL)实现

    基于DocBook的结构化书写系统(structured writing system)包括可视化编辑环境。
    简而言之,Callimachus支持使用关联数据进行导航,可视化,构建应用程序等操作。数据既可以保存在本地,也可以从万维网上采集,甚至可以在载入Callimachus时被转换为RDF。
    2.2.2 Django而Django是一个开放源代码的Web应用框架,由Python写成。采用了MTV的框架模式,即模型M,模板T和视图V。
    Django 项目是一个Python定制框架,它源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来。Django 框架的核心优势有:

    用于创建模型的对象关系映射
    为最终用户设计的完美管理界面
    一流的 URL 设计
    设计者友好的模板语言
    缓存系统

    Django是一个基于MVC构造的框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式。它们各自的职责如下:

    模型(Model),即数据存取层:处理与数据相关的所有事务:如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等
    模板(Template),即业务逻辑层:处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。一般将网页html和js文件存放在此层中
    视图(View),即表现层:存取模型及调取恰当模板的相关逻辑。模型与模板的桥梁。在view里面进行python后台处理,他将网页的响应数据拿到,同时也为网页发送请求

    从以上表述可以看出Django 视图不处理用户输入,而仅仅决定要展现哪些数据给用户,而Django 模板 仅仅决定如何展现Django视图指定的数据。或者说, Django将MVC中的视图进一步分解为 Django视图 和 Django模板两个部分,分别决定 “展现哪些数据” 和 “如何展现”,使得Django的模板可以根据需要随时替换,而不仅仅限制于内置的模板。
    2.2.3 对比通过使用Callimachus和Django两种服务器我们发现:

    Django在后台可以植入各种py文件来作为算法和逻辑基础;在Callimachus所有的sparql操作统一下xhtml上div块中进行书写,也就是Callimachus将业务逻辑基本集成在网页上面编写
    系统稳定性:Django早在2005年的时候就已经开始使用,网上对于Djano开发时所遇到的问题都有全面的回答,维护起来非常方便;Callimachus是在近几年才推出来的关联数据管理器,他虽然针对关联数据有很好的执行能力,但是在网上不止是关于他运行时的一些解决问题,就连关于他的介绍都微乎其微,在Callimachus运行的时候所遇到的维护问题只能靠自己解决,稳定性不确定,属于试验阶段
    开发周期:Django因为有越来越多的人在使用,而且出来较早,对于Django的查询和学习资料较为广泛,开发时间短;Callimachus因为网上资料确实太少,仅有的介绍只是Callimachus的官网说明,因此开发难度较大,学习周期长

    基于以上分析,我们最终选用Django服务器来实现我们的搜索和推荐服务。
    三、搜索服务3.1 搜索服务软件目录结构
    该路径为项目目录的根文件夹。
    其中Paper_search文件作为Django生成的APP文件,在该文件内来实现网页的请求和响应,以及sparql查询功能。
    Statica文件用于存放javascript文件和css文件,用于增强网页效果。
    Templates文件用于存放html文件,来作为网页html的存放文件夹.
    Zhishi文件用于存放该项目文件中的一些配置文件,主要是其中的settings.py文件用于项目承认Paper_search这个APP,用于指定static文件为静态文件路径;另外该文件夹下的urls.py文件用于绑定方法与html路径。
    最后是manage.py文件,该文件作为Django运行的起始文件,整个项目的运行开端为manage.py文件。

    在app文件里面,我们主要的逻辑程序都在views.py文件中,其中的方法主要是sparql的查询,正则化处理,网页的请求和相应。
    3.2 搜索服务功能本搜索服务主要是通过在网页上输入一本书的名字,通过书名正则匹配的方式,检索出完整的书名、作者名字、书籍资源的url。
    首先(windows下)通过打开cmd,在命令行cd 到该项目路径:

    在项目路径下执行该命令:

    上一行workon bayou是virtualenv技术,workon来执行我项目所配置到的env环境中,通过让baoyu的env环境工作,使得当前环境为我需要的Python2.7环境。
    进入到环境后通过下一行执行manager.py文件,并指定端口号为9000。开启服务器后,网页输入以下网页来实现搜索的效果。

    通过在网页端输入你想输入的书籍名字,可以是大概名字,点击下面的“提交”按钮。然后经过后台检索,跳转到另一个HTML页面显示该搜索结果。

    跳转到的界面,输出该书的出版时间,作者,和书籍的资源路径
    3.3 SPARQL语句分析在搜索服务软件中,我们通过导入SPARQLWrapper,来实现通过SPARQL来基于DBpedia数据来进行的搜索:
    sparql.setQuery(""" PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX dbo: <http://dbpedia.org/ontology/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX onto: <http://dbpedia.org/ontology/> select ?BookName,?Author,?Country,?Subject,?Label,?ReleaseDate,?Publisher WHERE{ ?book a dbo:Book. ?book foaf:name ?BookName. ?book dbo:author ?Author. ?book dbo:country ?Country. ?book dct:subject ?Subject. ?book rdfs:label ?Label. ?book dbp:releaseDate ?ReleaseDate. ?book dc:publisher ?Publisher. FILTER regex(?BookName,"%s","i") } """ % name)以上为我们所采用的SPARQL语句,通过定义?book是一个BOOK书来实现的相关查找,对于查找我们在最后加入FILTER 来进行正则化过滤,确保我们查询的书籍跟网页上的书籍对应。由于在SPARQL中我们要传递的是一个变量,所以在这里我们采用%s的格式化标识来传参。
    3.4 经验与收获在通过该搜索功能的实现中,首先我们训练了基于Django实现的网页交互功能。主要熟悉了Django软件的请求与响应流程:网页的参数通过urls.py文件绑定到响应的APP下的viwe.PY文件中的响应方法,通过该方法拿到参数后,传递给相应的查询语句并返回结果,后通过urls.py文件传结果参数给相应的html文件进行前端显示。
    练习了SPARQL怎么作为查询语句在现目中实现,通过SPARQLWrapper库提供的功能,将查询语句写入,通过调用其相应的方法执行查询、格式化输出等操作。
    另外为了实现网页的参数在SPARQL查询语句里也依然是个参数,我们通过多方的探究,独立想出了使用格式化符的方法。在原来的实验中,我们尝试”””+变量+”””这样的拼接方式进行传入变量但是不成功,但是通过这样独立的思考,对于实现SPARQL接收其他类或方法下的变量,有了很好的印象。
    3.5 不足在搜索功能的中,我们对目标的检索只停留在对单一的,比如说单书本名字,单电影名字或者单游戏名字。我们应当将书籍,电影,游戏的名字与其他相关基本信息联系起来。比如通过电影名字仅仅提供单个字符,然后基于电影的导演名字配合来查找到相关目标。
    3.6 所需配置的环境与包
    Python2.7环境
    Django库(通过pip install django)或者在pycharm里面setting中添加也行
    SPARQLWapper

    四、推荐功能服务4.1 功能介绍基于B/S架构的推荐功能服务。通过在网页上输入相应的书籍名称,和你知道的书籍描述。通过书籍名字和描述来确定与书籍相同主题上的一部电影,并通过推荐算法来推荐与这部电影最相近的10部电影。
    首先进入到本地9000端口下的index界面:

    在书籍名字和书籍描述上一定要填上。这里以一千零一夜为例:通过填入一千零一页这本书,和该书的主题(在dbpedia中为该单词)one_thousand主题。通过提交按钮,在后台查询到与之主题最匹配的一个电影(Aladding(1992)film)将Aladding(1992)film这个结果返回给我们机器学习算法使用交叉回归的方式来实现与这部电影最相近的10部电影(推荐的方式都是基于用户对电影的评价和评分,通过评价和评分综合推荐相似的电影)。返回出结果

    通过填入一千零一页这本书,和该书的主题(在dbpedia中为该单词)one_thousand主题。通过提交按钮,在后台查询到与之主题最匹配的一个电影(Aladding(1992)film)。
    将Aladding(1992)film这个结果返回给我们机器学习算法使用交叉回归的方式来实现与这部电影最相近的10部电影(推荐的方式都是基于用户对电影的评价和评分,通过评价和评分综合推荐相似的电影)。返回出结果。

    通过点击提交按钮,跳转到可视化界面,在这里可视化界面需要在打开的chrome右键属性进行相应的目标文件配置。
    在目标那栏:"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"末尾空一行添加:--allow-file-access-from-files效果即为:"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files
    4.2 推荐服务的目录结构
    该路径为项目目录的根文件夹。
    其中Paper_search文件作为Django生成的APP文件,在该文件内来实现网页的请求和响应,以及sparql查询功能。
    Statica文件用于存放javascript文件和css文件,用于增强网页效果。
    Templates文件用于存放html文件,来作为网页html的存放文件夹。
    Zhishi文件用于存放该项目文件中的一些配置文件,主要是其中的settings.py文件用于项目承认Paper_search这个APP,用于指定static文件为静态文件路径;另外该文件夹下的urls.py文件用于绑定方法与html路径。
    最后是manage.py文件,该文件作为Django运行的起始文件,整个项目的运行开端为manage.py文件。
    4.3 推荐服务的逻辑流程4.3.1 方法目录所有的处理逻辑都集中在Paper_rearch文件夹下的view.py文件中:

    Def query_fun作为sparql查询方法,返回一个电影名称
    def read_item_names():电影名与电影id,电影id与电影名绑定映射
    def clearContentWithSpecialCharacter(content):正则化方法,用于对电影名字进行文字格式处理
    def receive_data(request):处理页面响应,并向页面发送请求

    4.3.2 执行逻辑首先通过网页上输入的书籍名字和书籍主题,通过receive_data(request):来接收书籍名字和书籍主题,将这两个参数传入给:query_fun(书籍名字,书籍主题)。
    query_fun找到电影名字,在query_fun配有相应的正则化方法来输出我们所需要的格式下的电影名字film_name。
    执行read_item_names()方法来输出“电影名与电影id”,“电影id与电影名”映射模型film_name与电影id相绑定,输入到surprise提供的交叉熵算法来求得,人们对该电影评价与评分最相近的10部电影,然后传递给网页显示。
    4.4 SPARQL分析sparql.setQuery(""" PREFIX onto: <http://dbpedia.org/ontology/> select ?b WHERE{ ?a dct:subject ?subject_a. FILTER regex(?subject_a,"characters"). FILTER regex(?subject_a,?subject). ?b dct:subject ?subject_a. ?b a dbo:film. { select ?a,?subject WHERE{ ?a dct:subject ?subject. FILTER regex(?a,"characters"). { select ?subject,?BookName,?book WHERE{ ?book dct:subject ?subject. ?book a dbo:Book. ?book foaf:name ?BookName. ?book rdfs:comment ?a. ?book dbp:author ?b. FILTER regex(?BookName,"%s"). FILTER regex(?subject,"%s").} } } }} """ % (name,subject))本查询语句使用了3层的子查询结构。在第一层查询中:
    select ?subject,?BookName,?book WHERE{ ?book dct:subject ?subject. ?book a dbo:Book. ?book foaf:name ?BookName. ?book rdfs:comment ?a. ?book dbp:author ?b. FILTER regex(?BookName,"%s"). FILTER regex(?subject,"%s").}我们来找到网页上输入的书籍名字和主题最契合的书和主题。主要将输出的主题提供给父查询来使用。在第二层查询中:
    select ?a,?subject WHERE{ ?a dct:subject ?subject. FILTER regex(?a,"characters"). { select ?subject,?BookName,?book WHERE{ ?book dct:subject ?subject. ?book a dbo:Book. ?book foaf:name ?BookName. ?book rdfs:comment ?a. ?book dbp:author ?b. FILTER regex(?BookName,"%s"). FILTER regex(?subject,"%s").} } }我们根据第一层查询到的主题,来找到一个大类,这个类与这个主题是一样的。同时输出这个类和主题供父查询来使用。
    在最外圈的查询,我们查找与?a类和?a的主题一样的电影,查询出来输出。把这个查询结构进行正则化处理后,交给推荐算法来进行电影推荐。
    4.5 经验与收获为了实现通过书籍来查询电影功能,我们通过w3c官网来查找相关文档学习SPARQL的相关查询方法,并总计了相关查询语句,写成了相应的博客文档:

    https://blog.csdn.net/qq_28666313/article/details/80782827
    https://blog.csdn.net/qq_28666313/article/details/80777155

    为了实现推荐功能,我们通过相关资料的查找,确定了Item-base算法,这种算法通过纵向(观众的评分)和横向(观众的评价)来交叉考虑得到与之最近的分类从而实现基于一个电影推荐其相关电影的功能。
    由于Item-base算法中对电影名字有严格的命名匹配,所以我们在处理python中的正则化方法的时候,进行了思考,对正则处理有了一定的经验
    4.6 不足在基于SPARQL中,电影与图书在相同谓语,相同宾语上的联系,不是那么方便。我们通常通过图书找到与子匹配的大主语,再通过大主语下是否有相应的小主语(电影类别)来进行的语义的查找。但是这样的匹配成功率不高,有很多图书并没相关电影;也有很多图书相关的电影太多了(但是匹配的主题很宽泛比如都是属于英国出版,都是表述爱情)。而且再DBpedia上这样的语义描述还是太少了,只是一些关键上的描述。对于这样的语义关联查询,在描述上越多越好查询。
    本次查询就是经过不断的尝试,发现了Thousand Nights and a Night(一千零一夜书籍)与Aladding(大类)有共同的subject(One_Thousand_and_One_Nights_characters),这个共同的主题就是他们的联系。通过Aladding(大类)再来找到Aladding_film(1992)年的电影,但这样的实例不太容易发掘,其主要原因还是SPARQL语句的不理解,和对基于语义的相关查询操作不深。
    4.7 环境组件
    Python2.7
    Django
    SPARQLWrapper
    Cpython
    Surprise

    如果是windows环境在安装surprise包会出现缺乏microsoft C++9.0组件,这需要去微软官网下载(MAC和linux 不存在这样的问题)。
    五、基于机器学习的推荐算法分析5.1 基于机器学习的推荐算法分析推荐系统应用数据分析技术,找出用户最可能喜欢的东西推荐给用户,现在很多电子商务网站都有这个应用。目前用的比较多、比较成熟的推荐算法是协同过滤(Collaborative Filtering,简称CF)推荐算法,CF的基本思想是根据用户之前的喜好以及其他兴趣相近的用户的选择来给用户推荐物品。

    如图1所示,在CF中,用m×n的矩阵表示用户对物品的喜好情况,一般用打分表示用户对物品的喜好程度,分数越高表示越喜欢这个物品,0表示没有买过该物品。图中行表示一个用户,列表示一个物品,Uij表示用户i对物品j的打分情况。CF分为两个过程,一个为预测过程,另一个为推荐过程。预测过程是预测用户对没有购买过的物品的可能打分值,推荐是根据预测阶段的结果推荐用户最可能喜欢的一个或Top-N个物品。
    5.2 User-based算法与Iter-based算法对比CF算法分为两大类,一类为基于memory的(Memory-based),另一类为基于Model的(Model-based),User-based和Item-based算法均属于Memory-based类型,具体细分类可以参考wikipedia的说明。
    User-based的基本思想是如果用户A喜欢物品a,用户B喜欢物品a、b、c,用户C喜欢a和c,那么认为用户A与用户B和C相似,因为他们都喜欢a,而喜欢a的用户同时也喜欢c,所以把c推荐给用户A。该算法用最近邻居(nearest-neighbor)算法找出一个用户的邻居集合,该集合的用户和该用户有相似的喜好,算法根据邻居的偏好对该用户进行预测。
    User-based算法存在两个重大问题:

    数据稀疏性:一个大型的电子商务推荐系统一般有非常多的物品,用户可能买的其中不到1%的物品,不同用户之间买的物品重叠性较低,导致算法无法找到一个用户的邻居,即偏好相似的用户
    算法扩展性:最近邻居算法的计算量随着用户和物品数量的增加而增加,不适合数据量大的情况使用

    Iterm-based的基本思想是预先根据所有用户的历史偏好数据计算物品之间的相似性,然后把与用户喜欢的物品相类似的物品推荐给用户。还是以之前的例子为例,可以知道物品a和c非常相似,因为喜欢a的用户同时也喜欢c,而用户A喜欢a,所以把c推荐给用户A。
    因为物品直接的相似性相对比较固定,所以可以预先在线下计算好不同物品之间的相似度,把结果存在表中,当推荐时进行查表,计算用户可能的打分值,可以同时解决上面两个问题。
    5.3 Item-based算法详细过程5.3.1 相似度计算Item-based算法首选计算物品之间的相似度,计算相似度的方法有以下几种:
    基于余弦(Cosine-based)的相似度计算,通过计算两个向量之间的夹角余弦值来计算物品之间的相似性,公式如下:

    其中分子为两个向量的内积,即两个向量相同位置的数字相乘。
    基于关联(Correlation-based)的相似度计算,计算两个向量之间的Pearson-r关联度,公式如下:

    其中Ru,i表示用户u对物品i的打分,Ri表示第i个物品打分的平均值。
    调整的余弦(Adjusted Cosine)相似度计算,由于基于余弦的相似度计算没有考虑不同用户的打分情况,可能有的用户偏向于给高分,而有的用户偏向于给低分,该方法通过减去用户打分的平均值消除不同用户打分习惯的影响,公式如下:

    其中Ru表示用户u打分的平均值。
    5.3.2 预测值计算根据之前算好的物品之间的相似度,接下来对用户未打分的物品进行预测,有两种预测方法:
    加权求和
    用过对用户u已打分的物品的分数进行加权求和,权值为各个物品与物品i的相似度,然后对所有物品相似度的和求平均,计算得到用户u对物品i打分,公式如下:

    其中Si,N为物品i与物品N的相似度,Ru,N为用户u对物品N的打分。
    回归
    和上面加权求和的方法类似,但回归的方法不直接使用相似物品N的打分值Ru,N,因为用余弦法或Pearson关联法计算相似度时存在一个误区,即两个打分向量可能相距比较远(欧氏距离),但有可能有很高的相似度。因为不同用户的打分习惯不同,有的偏向打高分,有的偏向打低分。如果两个用户都喜欢一样的物品,因为打分习惯不同,他们的欧式距离可能比较远,但他们应该有较高的相似度。在这种情况下用户原始的相似物品的打分值进行计算会造成糟糕的预测结果。通过用线性回归的方式重新估算一个新的Ru,N值,运用上面同样的方法进行预测。重新计算Ru,N的方法如下:

    其中物品N是物品i的相似物品,alpha和beta通过对物品N和i的打分向量进行线性回归计算得到,E为回归模型的误差。
    5.4 Surprise库的介绍在推荐系统的建模过程中,我们用到python库是 Surprise(Simple Python RecommendatIon System Engine),是scikit系列中的一个(很多同学用过scikit-learn和scikit-image等库)。所使用的数据库是MovieLens 100k,该数据集包括6040个用户对大概3900部电影的1000209条评分数据。(该数据集的链接是:https://grouplens.org/datasets/movielens/100k/ )。surprise库同时支持多种推荐算法:

    基础算法/baseline algorithms
    基于近邻方法(协同过滤)/neighborhood methods
    矩阵分解方法/matrix factorization-based (SVD, PMF, SVD++, NMF)


    其中基于近邻的方法(协同过滤)可以设定不同的度量准则:

    支持不同的评定标准:
    1 评论 1 下载 2019-06-18 09:24:46 下载需要15点积分
  • 基于C#和Sql Server的图书管理系统

    1 课程设计意义与目标1.1 课程设计的意义《可视化编程技术课程设计》是在学生学习完《可视化编程技术》以后进行的设计性集中实践课程,通过课程集中实践,目的是使学生能加深对理论教学内容的理解,学会可视化编程技术的综合应用,培养学生分析问题的解决问题的能力。
    1.2 课程设计的目标通过课程集中实践,要求学生加深对讲授内容的理解,累积经验、学会独立上机调试程序;并且逐步达到综合运用封装、继承和多态等C#难点知识,更深地理解面向对象程序设计的基本概念与方法,从而学会利用C#语言解决一般应用问题,能设利用可视化编程技术开发复杂和综合性的计算机管理信息系统,并为后续专业课程的学习奠定程序设计基础。
    2 课程设计的题目2.1 设计题目概述
    图书管理系统
    2.2 开发环境搭建
    开发语言:C#
    开发工具:Visual Studio 2010
    数据库管理工具:SQL Server 2008

    3 系统的设计与实现3.1 物理数据模型设计




    3.2 主要界面设计
    界面中用了textbox,label,combobox,textbox用于获取数据输入,combobox用于数据选取,button用于单击事件。在用户类别可以选择用户类型,管理员。

    界面中用了textbox,label,combobox,dataGridView,textbox用于获取数据输入,combobox用于数据选取,button用于单击事件,dataGridView用于数据显示。
    功能:可以增加,修改,删除图书。

    界面中用了textbox,label,combobox,dataGridView,textbox用于获取数据输入,combobox用于数据选取,button用于单击事件,dataGridView用于数据显示,用户借书,管理员可以查看用户的借书记录。

    密码修改:可以更改当前用户登录的密码,旧密码符合条件,新密码和旧密码不能相同,新密码和确认密码的相同的条件。

    界面中用了textbox,label,combobox,dataGridView,textbox用于获取数据输入,combobox用于数据选取,button用于单击事件,dataGridView用于数据显示,用户借书,管理员可以查看用户的借书记录。模糊查询在下面有具体介绍。

    管理员信息管理:可以对管理员进行增添改查。

    书库管理:对书库进行增删改查。

    书库查询:按地区分类和按书库编号分类,第二个combobox会自动加载所有记录的值供你选择。

    书库管理:用来增加书库,删除,修改。

    用户管理:对用户的增删改查。

    用户登录之后的界面。

    管理员登录之后的界面。
    4 调试过程中出现的问题及解决办法4.1 数组索引超出界限解决方法:利用断点调试,重新赋值。

    4.2 从试图获取数据时,应添加新的字段
    5 个人体会及建议在这次课设中,基本都是在学习新知识的过程,从powerdesigner到动软生成软件,让我知道了这个工具的强大之处,渐渐开始会用一点,在第一天晚上想重做一遍学生信息管理系统,不料,动软生成的路径没改,直接给覆盖了,所以只能重头再来,在这时就有想法想做个不一样的系统,上学期用C++做了个图书管理系统,有点印象,就选择做这个,一开始一直模范着你给的day1,day2,day3,看不懂BLL,DAL,MODEL之间的关系,经过思考,理解了他们之间的关系,BLL负责储存方法相当于API,DAL负责储存数据,MODEL负责各个对象的类,后面理解了就开始自己写,用户负责借书,用户的增删改,添加用户,管理员负责查询书库,书库的增删改查,查询图书,图书的增删改查,借书记录的增删改查,在这个过程中不仅了解了动软生成软件的机制,而且可熟练的利用这个工具,在这个工具的基础之上,我写出了更多好用的函数供自己使用。在windows应用开发上了解更多控件和控件属性的使用和结合,可以做出功能和界面相对完整的程序,总之,在这次课设中受益匪浅。
    2 评论 88 下载 2019-03-10 21:27:29 下载需要8点积分
  • 基于C#和SQL SERVER 2008实现的男士服装进销存管理系统

    摘 要系统主要包括基础用户和供应商数据、货物采购、货物销售、库存清点、库存调整等功能。基础数据用于维护用户和供货商的基本信息,如所属供应商和用户、联系人、联系方式等,用户可以通过系统的基础数据模块设置系统的基本信息,方便在其他模块中使用,有助于系统在企业信息结构发生变化时能够及时响应。
    软件主要服务中小型服销售商铺或者公司,是商铺和公司完善内部管理、理顺工作流程各个环节的强有力的管理工具。系统的设计采用大量的接口,方便以后的升级或者与其他系统的整合。系统的运行基础是企业内部局域网,采用基于WinForm的C/S结构,操作界面容易使用和掌握,基本上会Windows基本操作就能很快了解并且掌握系统的使用方法。
    关键词: 服装;企业;销售;管理
    第1章 绪 论1.1 课题介绍1.1.1 男士服装进销存管理系统男士服装企业围绕进货存储销售的管理往往是很繁琐的[1]。各个企业之间的管理体制不同,采购,生产,库存,销售流程有差异,所以必须根据企业的具体情况制定系统的方案以便提高工作效率。
    我国的中小企业不仅在数量上是巨大的,在我国社会主义经济建设中扮演的角色也越来越重要[2]。我国中小企业具有活力并且能够灵活适应市场机制,促进我国社会经济发展,成为我国重要的一项经济基础。随着ERP管理系统的日益发展,大部分中小企业迫切需要借助现有的ERP在企业管理中的应用,以达到突破自身发展的瓶颈的目的。
    中小服装企业存在问题:计算机使用率低,日常工作和记录很多是通过手工处理,所以工作效率低。企业内部的沟通不够流畅,企业员工工作效率较低[3]。为了增强企业的竞争力,提高效率,企业必须实现信息化。只有配备先进的办公自动化系统,实现企业内部信息的共享和管理,加强企业内部的沟通,才能以使企业在激烈的市场竞争中稳定发展。
    1.1.2 背景从整个世界的服装行业发展来看,服装生产加工企业的生产规模越来越大,大型企业将成为市场的主角,尤其一些沿海地区来说,服装的加工占据一部分的销售量。
    1.1.3 研究目的及意义本系统是对服装企业资源如物品流、资金流、业务流等相关信息的综合管理软件系统。软件应用程序的开发目标是使中小型服装企业的的进销存方面变得更加方便,减少人工的繁琐以及出错概率,帮助企业方便高效的解决进销存管理问题。
    该系统旨在为企业管理提供丰富的信息资源管理[5]。能否充分利用信息进行企业管理,帮助用户制定出实施有效的决策,是一个衡量的ERP应用成功的标志。该系统投入实际运行后,服装企业应根据管理需要将系统的初期设计制定好,并灵活地完成系统的初始化信息维护。本着尽可能完成系统需求阶段制定的各项功能的原则,力求物品在适当的时间到达适当的地点,用户的操作空间大。业务流的处理也是在标准的业务管理方案上进行准确的及时的设计,让服装企业在管理上面不失规范和高效,并预留出大量接口方便升级或者对接。
    1.2 研究内容
    进货管理模块,包括进货入库,以及查看进货记录
    销售管理模块,包括销售记录账单,退货处理,查看销售记录
    库存管理模块,包括查看库存信息,库存之间的调转,以及库存的盘盈盘亏
    配方管理,用于维护配方的基本信息
    基础数据,包括角色管理、用户管理、供应商管理

    第2章 相关技术介绍2.1 开发环境2.1.1 硬件环境本管理系统使用PC机进行开发,其硬件配置如下:

    中央处理器:Intel(R) Core(TM) i5-3560 CPU @ 2.60GHz
    内存:8.0GB
    主硬盘:ST500LT012-9WS14 SCSI DiskDevice(500G)
    显卡:Intel(R) HD Graphics

    2.1.2 软件环境在硬件开发环境之上搭建的软件开发环境包括以下部分:

    操作系统:64位Windows8
    开发工具:Microsoft Visual Studio 2013、Microsoft SQL Server 2008 R2

    2.2 开发工具2.2.1 Microsoft Visual Studio 2013Microsoft Visual Studio 2013简介
    本系统使用的开发环境是微软的 Visual Studio 2013,Microsoft Visual Studio 是Windows Vista、Web 2.0方向的开发工具,能够设计、开发基于Microsoft windows 的工程项目。解决方案是用来管理各个项目的,对于WinForm而言,每个项目都对应着一个命名空间,管理各种类的就是项目。一个解决方案可以包括多个项目。
    Microsoft Visual Studio 2013的特点

    NET Framework对重定向的支持,使用Microsoft Visual Studio 2013可以使用多个.net 框架版本的C#规范或者类库进行项目开发
    LINQ作为一种访问数据的程序模型,使得.NET平台可以直接进行处理数据。借助LINQ可以将数据封装成对象,方便与编程模型集成

    2.2.2 SQL Server 2008 R2Microsoft SQL Server 2008简介
    SQL Server是一个微软推出的关系型数据库。SQL Server 2008功能强大,同时简化建立企业数据系统,方便用户部署和处理企业数据以及分析应用
    SQL Server 2008的特点及功能

    .NET框架主机:通过SQL Server 2008,程序开发者可以使用多种语言,比如微软的VisualC#.net和微软的Visual Basic
    XML技术:在使用互联网或者本地局域网的情况下,在不同的应用程序中传递数据的时候,使用可扩展标记语言(XML)是一个重要的解决方案。SQL Server 2008将使用自己支持的存储和查询方式引进可扩展标记语言(XML)文件

    2.3 相关技术基础2.3.1 C/S结构C/S 结构,即Client和Server结构。C/S结构减少了系统之间的通讯。Client/Server形式的结构被经常使用着,尽管现在主流采用B/S结构[8]。内部的和外部的用户可以访问新的和现有的软件系统,通过现有的系统中的逻辑迁移到新的应用系统[9]。然而,C/S结构相比较更安全。
    2.3.2 WinForm技术WinForm是使用.NET开发平台中的Windows 窗体[10]。新的数据连接方式如ODBC。Windows窗体是基于微软公共语言运行库的。开发起来较其他平台方便快捷许多。
    2.4 本章小结本章主要介绍了本系统的开发环境与开发过程中使用的工具,设计之初决定创建窗体应用,所以采用了.NET平台的WinForm技术,这样开发效率比较高而且开发比较方便简单。
    第3章 系统需求与可行性分析3.1 可行性分析可行性分析(Feasibility Analysis)是在系统开启之前系统分析的基础上,针对新系统的开发的难度是否合理以及开发系统的必要性,从经济条件,技术难度,社会发展对系统进行的研究。可行性分析可以帮助分析人员提高新系统的认识,这在一定程度上保证了新工程朝着正确反向发展。一旦发现问题并且暂时没有可行的解决方案,项目将被搁置。
    3.1.1 技术可行性
    硬件环境本系统采用Microsoft Visual Studio 2013和SQL Server 2008 R2进行开发,内存要求最低为384M,5400 RPM 硬盘 。而开发机内存8G、500G硬盘满足了这点要求。SQL Server 2008 R2其处理器要求最低为Pentium III 兼容处理器,内存要求最低为512M,硬盘空间至少需要500MB的程序空间和1GB的数据空间,开发机Intel i5处理器满足了这点要求
    系统软件采用的64位的Windows 8操作系统都是可以满足以上开发要求的
    开发工具Microsoft Visual Studio允许开发人员使用不同的编程语言,作者选用C#完全可行。SQL Server在本系统中用于对基础信息的存储
    最后,开发者对编译原理知识的储备,以及对于开发工具Microsoft Visual Studio和SQL Server 2008 R2的熟悉,都使得程序的开发在技术上是完全可行的

    3.1.2 操作可行性由系统分析可知系统用户多为企业部门领导,能够熟练使用计算机,能够使用本系统。程序界面充分考虑了用户的操作习惯,操作简单。同时程序的操作选项都有相应的提示。所以从整体来讲,该系统应具有易用性、灵活性和可视性。熟悉Windows操作系统的人都能很快地掌握该系统的使用。
    3.1.3 社会可行性整套系统面向企业流程管理,采用面向对象设计,具有良好的扩展性。系统主要包括基础数据、生产管理、采购管理、配方管理、库存管理等功能。本套系统可以帮助中小型服装企业提高生产效率。
    3.2 系统需求该系统设计的主要目的是帮助服装企业充分将此套软件应用在日常企业管理中,提高企业生产效率,减少人为数据,提升企业的生产,系统具有以下几点需求:

    首先与各个厂商进行联系,然后记录这些厂商的信息,接着跟厂商确定要购买的货物,然后再进行采购开单
    将采购到的货物入库并定期对仓库进行盘点
    前台进行货物销售生成销售单减少库存,记录到数据库
    基础数据用来维护日常所需要的信息,如角色、职务、部门、联系方式

    3.3 本章小结本章主要描述了本套系统的需求可实现的可行性,描述了系统的实现可能性与相关工具。讲述了系统所要涵盖的主要功能,以及用户使用本套系统可以获得的便利和系统设计的主要目的以及应用环境。
    第4章 系统设计4.1 概要设计一个系统的功能框架和人机交互的感官框架的形成,其目的主要反映在人机交互的界面。系统界面的功能分组、页面布局和整体样式格局,这是用户习惯和系统设计之间的纽带。系统研究和用户的目标和需求的无缝集成的设计是转化为具体的界面设计的一个重要阶段。
    概要设计的主要目的是根据需求分析将系统的整体功能体系架构和各个模块的联系进行规划。设计出软件的整体结构有助于系统的框架功能的开发并在前期给客户展示一些系统涵盖的功能范围。数据结构的设计包括数据的分享,设计出数据结构,数据库的生成与优化。
    男士服装进销存管理系统包含如下几大模块:采购、库存、生产、配方的管理、基础数据维护。各个模块相互协作共同完成企业的业务流程。系统框架如下图所示。

    各个模块功能介绍

    常用事物模块主要是完成采购开单、采购批准、采购执行管理VIP、前台销售操作
    其他事物模块主要是仓库管理、库存调整完成物品的数量的维护和库存信息的设置与维护
    系统设置模块主要是对供货商和使用该系统的用户进行数据的设置,以便系统能够灵活稳定的运行

    4.2 详细设计详细设计主要是对算法和数据结构和特定的计算机语言实现各模块的实现初步描述。定义各个模块直接通信的接口,与数据库连接的统一接口和实现,为正式开发制定规范。
    更改详细设计方案,不能对概要设计方案造成影响;详细设计阶段要出几篇文档,包括详细设计文档和模块设计方案。每个模块的详细设计文档都应该形成规范并以文档的形式公布。详细设计的任务包括:

    确定每个模块的算法的使用,一个合适的工具来表达算法的过程中选择,掌握每个算法的优缺点
    为模块内的数据结构进行设计。将需求分析、概要设计阶段确定的概念性的数据类型进行确切的定义
    这个阶段我们将设计出系统开发中使用的大量的接口,接口的规范有助于开发人员程序书写的条理性和一致性的约束。采用接口还有助于我们本套系统与其他遗留系统的整合与集成。对于后期的维护和功能修改,采用统一的接口的方式将会使后期的开发方便快捷

    4.2.1常用事物详细设计
    采购货物:采购部门根据库存量或者公司数据开具采购单,然后和有关部门联系采购货物,将货物信息录入到系统中
    前台销售:销售部门根据当前系统中存的货物信息进行职能销售,并生成销货单
    VIP管理:前台销售部门根据用户的购买情况,对一些特殊顾客开通VIP服务,可以进行打折服务

    4.2.2 其他事物详细设计
    库存盘点:根据要求进行盘盈盘亏调整,并定期记录到数据库当中
    库存调整:如果服装企业存在多个仓库,可以进行货物的调整并调整仓库中的库存数量
    退货管理:如果销售的货物客户要求退货,可以使用退货管理来对退货进行详细的记录

    4.2.3 系统设置详细设计此模块会对系统的一些参数以及用户和供应商的相关数据进行设定,以便后期来方便的使用。
    4.3 界面设计4.3.1 界面设计采用WinFormWinForm自身包含了大量的窗体控件,当然,设计者也可以通过给定的接口来设计自己的窗体控件。本着简洁方便的原则,通过使用微软提供的窗体控件使得程序风格统一并且与用户日常接触的习惯一致。通过为按钮等控件赋予一些声音和颜色特性,给用户更好的反馈效果。
    4.3.2 主页面设计系统主页面分为三个部分,最上面是菜单栏(MenuStrip),菜单栏有功能菜单、用户名、退出、帮助等菜单选项。左侧是工具栏(SideBar),用户登录进来后所拥有的功能都在这里显示。中间最大的区域是业务操作区,单击左侧功能项之后弹出的窗口都将在此显示。系统主页面如下图所示。

    4.3.3 数据表格设计系统为数据表格设计了统一的表现形式。数据表格提供按条件查询的功能,用户可以根据条件查询所需数据。用户可以自定义页面显示数据的数量、刷新数据表格。用户可以选中整条数据进行相应的业务处理,比如批准某条记录。数据表格同时提供拖拽功能,用户可以根据自己的需要或者爱好调整各数据列的显示大小,同时系统提供打印的功能,可以将当前表格数据打印出来。当数据过多时,自动生成滚动条。提供的下拉框和查询功能能够让用户快速定位到需要的数据。数据表格支持立刻刷新,当用户完成操作时,数据表格也马上进行更新,这样就保证用户能够及时方便地看到操作后的结果。数据表格如下图所示。

    4.4 本章小结本章描述了系统的整体功能设计,每个模块流程的详细设计,还有数据库设计。展示了几个主要界面的设计效果,还有为了方便用户或者提升用户体验而设计的一些解决方案与一些主流的设计。
    第5章 系统实现5.1 基础数据模块实现拥有权限的用户可以对系统的角色、部门、职务、规格、单位、仓库等信息进行管理。用户根据公司的管理结构设定职务与部门,基于业务流程与物品信息维护物品规格与单位。通过设定角色并将角色赋予用户,从而实现权限管理。页面如下图所示。

    5.2 进货管理模块实现进货管理首先包括最基本的信息维护。采购商品拥有编码、名称、规格、单位属性,为了库存管理,商品还具有库存上限与库存下限。用户可以查询、添加、删除和修改商品信息。商品管理如下图所示。

    供应商拥有编码、名称、邮编、联系人等属性。用户可以查询、添加、删除和修改供应商信息。供应商管理如下图所示。

    选中某一行数据,然后点击修改按钮即可弹出修改供应商信息的对话框。修改供应商信息如下图所示。

    5.3 库存管理模块实现库存管理模块主要是协助采购、生产、销售等模块进行业务最终的入库操作。并负责各物品库存信息维护和仓库状态查询。库存管理模块交由库存管理人员进行使用,因为库存管理在业务流程中比较重要,而且通常是整个业务流的终点,所以库存管理模块经常需要与其他模块合作。采购入库如下图所示。

    选中某一条记录然后点击修改按钮,下方会将数据显示出来在进行修改提交即可,因为库存数据比较重要而且一般情况下由系统自行维护,比如采购入库完成的时候系统会将对应原料的库存数量增加入库的数量,出库时则减少库存数量,所以每次人为更改都会有记录。库存的修改界面如下图所示。

    5.4 本章小结本章主要通过截图的方式展现了系统的主要功能架构,通过演示一个流程的步骤给用户简单讲解了系统的使用方法和效果。针对有特色的几个功能模块都进行了截图描述。
    第6章 结论与展望6.1 结论本系统服务的对象是中小型服装企业,主要包含的模块有基础数据、进货管理、销售管理、库存管理和配方管理。采购、销售两大流程贯穿各个模块,并且经过缜密的设计后符合企业的实际业务流程。在系统的过程中我学到了并使用到了很多技术,包括WinForm、SQLServer,最重要的是学习能力得到了很大提高。
    从系统功能来讲,基于WinForm的服装企业综合管理系统采购管理子系统的功能达到了预期的效果,程序界面设计的水平也得到了很大提高。
    6.2 展望虽然目前男士服装进销存管理系统已经能正常使用,但是因为个人的能力以及开发周期等原因仍然存在许多不完善的地方,系统有待于进一步改正。目前正朝着几个方向努力:

    进一步方便查看,比如,在查看记录时,可以采用一个输入框供用户填写起止日期来查看在期望期间的记录
    进一步接口化,争取使系统内部融合的很好,并争取与历史遗留或者其他开发者的系统兼容。各个模块要设计出合理的接口以便以后扩展
    软件的各项显示可以实现定制化,比如,采购记录中的各项信息比较多,业务人员可以根据自己的需要和喜好选择自己想要看到的信息项
    引入智能化的思想,系统能根据库存的数量与上下限提示用户该进行相应的操作
    2 评论 18 下载 2018-11-05 16:22:04 下载需要9点积分
  • 基于JAVA实现的幼儿园信息管理系统

    第一章 系统概述1.1 开发环境
    Eclipse_1.08
    jdk 1.8

    1.2 实验内容要求实现某个幼儿园日常工作:

    入园、入班、离班、离园登记,要求登记准确的时间、接送人等信息,并实时发送通知消息
    安全教育:可以定期发布安全教育小贴士,记录儿童在园期的表现等
    健康:在入园死要登记体检情况:如体温、是否咳嗽等
    消息通知,可以将需要通知家长的信息通过短信,邮件发送
    用到的数据保存到文件或者数据库中

    1.3 实验要求
    学生学籍信息增删改除
    学生入园离园时间接送人信息
    短信邮件发送

    第二章 需求分析入园、入班、离班、离园要求登记准确的时间,这就需要设定的数域里包含calendar类型的这四个private的数据域,准确的登记时间可以用当前系统的时间。接送人:因为接送人不是固定的,考虑到实际情况接送人可以用一个链表实现,当学生入籍时,将这些可接送学生的接送人添加进去,然后再面板中做一个复选框,选择接送人。
    体检情况可另外设一个类,当学生入籍时填写这些内容,这些内容包括:性别、身高、体重、视力、听力、是否发烧、是否有心脏病等。
    在学生信息的中还包含家长的联系方式包括电话,邮件,以String的形式保存以便后续的使用。
    2.1 实验功能描述功能介绍如下所示:

    【学生信息】:此界面可以实现学生学籍的存档和删除等功能;存档时需存入的信息有:

    姓名、性别、身高、家长姓名,联系方式,家庭住址等体重健康状况(视力、听力、是否含有心脏病等)
    【登记信息】:登记每天幼儿接送情况,需记录准确的时间、接送人等信息,通过短信和邮件等方式实时通知学生监护人,教师需认真记录学生在校的表现也通过短信和邮件的方式实时通知家长
    【邮件短信通知】:选择点击学生列表或直接输入号码,可以对已选学生发送邮件和短信通知

    2.2 系统流程图
    第三章 分工合作3.1 系统模块化
    储存模块
    邮件短信发送模块
    读写模块

    第四章 功能展示4.1 类设计概要4.1.1 储存类设计ROLL类
    Name(学生姓名)stringoutschooltime(毕业时间)calendarInschooltime(入籍时间calendareMail(家长的邮件)stringPhonenumber(家长的电话)string方法包括个数据的set和get方法
    Medicialcondition类
    Bloodtype(血型)stringEyesight(视力)doubleHearring(听力)doubleHeight(身高)doubleWeight(体重)doubleIsfever(发烧症状)booleanHeartcondition(心脏病)boolean
    Registinformation类
    Expression(日常表现)stringInclasstime(进入学校登记时间)calendarOutclasstime(出学校登记时间)calendarPickupperson(接送人)string
    4.1.2 程序设计(关键代码)private ArrayList<dayInformation> dairyRecord = new ArrayList();
    因为学生的日常出离学校等情况需要保存和实时查看所以,我们需要对这些记录进行保存,在这里常见一个列表,方便及时添加。
    public Roll(){ this.Name=null; this.inSchoolTime=null; this.outSchoolTime=null; this.condition=null; this.eMail=null; this.phoneNumber=null; NUMBER++;}
    构造函数在创建时学生数量要+1,方便以后的添加和查询等功能的实现。
    public Date getDate() { return date;}public void setDate(Date date) { this.date = date;}
    这两个函数用来设置和返回时间,以便在登记学生日常信息是使用。
    public static void addRecord(Roll r,Date date,String inClassTime, String outClassTime, String expression, String pickUpPerson){ r.getDairyRecord().add(new dayInformation(date,inClassTime, outClassTime, expression, pickUpPerson));}
    用于日常信息的修改,增加一条记录。
    4.1.3 邮件发送类设计MyAuthenticator类

    MailSenderInfo类

    SimpleMailSender类

    Sender类(邮件)

    Sender类(短信)

    4.1.4 邮件发送类通过网上查找资料得知,JAVA邮件发送的大致过程是这样的:

    构建一个继承自javax.mail.Authenticator的具体类,并重写里面的getPasswordAuthentication()方法。此类是用作登录校验的,以确保你对该邮箱有发送邮件的权利
    构建一个properties文件,该文件中存放SMTP服务器地址等参数
    通过构建的properties文件和javax.mail.Authenticator具体类来创建一个javax.mail.Session。Session的创建,就相当于登录邮箱一样。剩下的自然就是新建邮件
    构建邮件内容,一般是javax.mail.internet.MimeMessage对象,并指定发送人,收信人,主题,内容等等
    使用javax.mail.Transport工具类发送邮件

    具体实现中,我决定:

    新建一个类名为MyAuthenticator的类,该类继承于Authenticator。并且重写其中的getPasswordAuthentication()方法
    新建一个类名为MailSenderInfo的类,设置邮件发送者、接收者地址以及SMTP服务器地址等属性,这些都是private的,故还要写相关的set()和get()方法
    新建一个类名为SimpleMailSender的类,该类主要有一个sendTextMail()方法,发送邮件成功返回true,否则返回false
    新建一个类名为Sender的类,该类中的sendmail()静态方法作为可被面板调用的发送邮件功能的接口。

    4.1.5 短信发送类成功完成邮件模块后,我接着进行短信模块的开发。通过上网查资料得知,JAVA发送手机短信有几种方法:

    使用webservice接口发送手机短信,这个可以使用sina提供的webservice进行发送,但是需要进行注册
    使用短信mao的方式进行短信的发送,这种方式应该是比较的常用,前提是需要购买硬件设备
    使用中国网建提供的SMS短信平台。

    通过比较分析,我决定用第三种方式,即尝试通过中国网建提供的SMS短信平台来实现短信功能。
    通过深入的了解,我发现这个短信平台基于java提供专门的接口,其原理是:给用户发送短信主要是通过移动提供给的接口,而我们程序主要是将短信信息(手机号码、短信内容)发给这个接口,之后就是移动的事情了(根据信息发给相应的用户)。
    具体实现中,我决定:
    新建一个类名为Sender的类,其中包含中国网建给的用户名Uid、密码Key(新注册用户可免费发送5条短信和3条彩信)、接口地址、转码方式、以及发送内容和收件人号码。


    4.2 界面设计概要根据需求:学生学籍信息增删改除,学生入园离园时间接送人信息,短信邮件发送。
    设计一个主界面,三个分界面。主界面包含菜单和功能,分别来实现所需的功能。
    4.3 界面功能介绍根据需求将界面分为一个主界面,三个分界面。主界面中包含一个菜单,菜单中有导入文件,保存另存为,安全小贴士定期发送,帮助的子选项。
    分界面有学生界面,登记界面,邮件发送界面,分别实现各自功能。

    学生界面:输入学生姓名并按下添加按钮能够添加一个学生,再右侧面板中可以编辑其信息并保存
    登记界面:左侧选择学生,可以添加每日接送信息并保存,点击历史记录可以查看以往保存的记录
    邮件发送界面:通过点击左侧学生列表看多选并发送短信与邮件。由于短信发送功能由第三方平台提供,短信数量有限





    3 评论 34 下载 2018-11-06 15:37:17 下载需要8点积分
  • 基于Java和Sql Server 2012实现的高校成绩管理系统

    1、需求分析计算机已经深入到日常工作和生活的方方面面,成为我们学习和工作的得力助手,比如文字处理、信息管理、辅助设计、图形图像处理、教育培训以及游戏娱乐等。随着越来越多的应用软件出现,人们对它的要求也越来越高;虽然现在世界上的各种软件层出不穷,但它们依然不能满足用户的各种特殊需要,所以人们仍是不得不开发适合特殊需求的软件。高校成绩管理系统记录了一个大学生成绩的系统,它的出现使得查询、更新、插入简单化,高效化,成本也随之大大减少。使用计算机对成绩信息的管理,具有手工管理所 无法比拟的优点:信息存储及时,检索迅速、查找方便、可靠性高、存储量大、保密性好、寿命长、成本低等。这些优点能够极大地提高学 生成绩管理的效率,也是高校成绩正规化管理的重要途径。
    本软件控件均以中文形式表示,对普通程序使用者的查询提供简单方便的快捷操作,不需要技术含量。
    以SQL SERVER数据库管理系统为平台,通过设计数据库概念模型、逻辑模型以及利用标准SQL语言的数据库实现,掌握关系数据库系统的设计与实现方法,增强数据库设计和数据库应用系统开发能力。
    操作人员与维护人员应懂的SQL语言。

    硬件环境

    LENOVO-G470
    软件环境

    Windows 8企业版Microsoft SQL Server 2012 UltimateNETBEANS 7.3

    1.1 数据需求描述
    1.2 系统功能需求
    管理员

    添加教师名单查询教师名单修改教师信息删除教师名单添加学生名单查询学生名单修改学生信息删除学生名单统计生源地信息修改密码
    教师

    查看个人信息查看每门课程平均成绩统计输入学生成绩, 自动生成该学生已修总学分查看任课信息查看学生成绩名次修改密码
    学生

    查看个人信息查看自己的课表查看不同班级的开课情况查询考试成绩修改密码

    1.3 其他性能需求
    用户输入出错时,有错误提示
    给管理员,教师,学生不同的权限,提高数据安全性
    创建触发器,存储过程,防止数据不一致


    2、概念结构设计
    3、逻辑结构设计
    教师(教师编号、教师姓名、教师性别、教师年龄、职称、联系电话)
    上课(教师编号,班级编号)
    授课(教师编号,课程编号)
    课程(课程编号,课程名称,教师姓名,学期,学时,考试或考查,学分)
    学习(学号,课程编号,学期,课程名称,成绩)
    学生(学号、学生姓名、学生性别、学生年龄、生源所在地、已修学分总数,班级编号)
    开设(课程编号,班级编号)
    班级(班级编号,班级名称,专业编号)
    专业(专业编号,专业名称)
    学生账号(学生编号,学生密码)
    教师账号(教师编号,教师密码)
    管理员账号(管理员编号,管理员密码)

    3.2 数据类型定义教师



    数据项名
    数据类型
    长度
    完整性约束




    教师编号
    char
    20
    主键,唯一,非空


    教师姓名
    char
    20



    教师性别
    char
    2



    教师年龄
    char
    20



    职称
    char
    10



    联系电话
    char
    20



    上课



    数据项名
    数据类型
    长度
    完整性约束




    教师编号
    char
    20
    主键,唯一,非空,外键


    班级编号
    char
    20
    外键



    授课



    数据项名
    数据类型
    长度
    完整性约束




    教师编号
    char
    20
    主键,唯一,非空


    课程编号
    char
    20
    外键



    课程



    数据项名
    数据类型
    长度
    完整性约束




    课程编号
    char
    20
    主键,唯一,非空


    课程名
    char
    20



    教师姓名
    char
    20



    开课时间
    char
    20



    学时
    int
    10
    >0


    考试或考查
    char
    4



    学分
    int
    4
    >0



    学习



    数据项名
    数据类型
    长度
    完整性约束




    学生学号
    char
    20
    主键,唯一,非空


    课程编号
    char
    20
    外键


    学期
    char
    10



    课程名称
    char
    20



    成绩
    int
    10



    教师姓名
    char
    20



    学生



    数据项名
    数据类型
    长度
    完整性约束




    学生学号
    char
    12
    主键,唯一,非空


    学生姓名
    char
    10



    学生性别
    char
    2



    学生年龄
    int
    4



    生源所在地
    char
    20



    已修学分总数
    int
    4



    班级编号
    char
    10
    外键



    开设



    数据项名
    数据类型
    长度
    完整性约束




    课程编号
    char
    20
    联合主键,唯一,非空


    班级编号
    char
    20



    班级



    数据项名
    数据类型
    长度
    完整性约束




    班级编号
    char
    20
    主键,唯一,非空


    班级名称
    char
    20



    专业编号
    char
    20
    外键



    专业



    数据项名
    数据类型
    长度
    完整性约束




    专业编号
    char
    20
    主键,唯一,非空


    专业名称
    char
    20



    学生账号



    数据项名
    数据类型
    长度
    完整性约束




    学生编号
    char
    20
    主键,唯一,非空


    学生密码
    char
    20



    教师账号



    数据项名
    数据类型
    长度
    完整性约束




    教师编号
    char
    20
    主键,唯一,非空


    教师密码
    char
    20



    管理员账号



    数据项名
    数据类型
    长度
    完整性约束




    管理员编号
    char
    20
    主键,唯一,非空


    管理员密码
    char
    20



    3.3 关系模式的优化对关系模式进行规范化处理,对关系模式进行评价与修正。
    4、物理结构设计4.1 聚簇设计该高校成绩管理系统数据库可建立聚簇:














    这几个聚簇设计是因为这几张表都是实体表,,且聚簇中的属性都是主键或是外键,被访问的概率很高,而其他表或者这些表上的其他属性被访问的概率就相对较低。
    4.2 索引设计索引就是表中数据和相应存储位置的列表,使用索引可以大大减少数据的查询时间。
    对于一个确定的关系,通常在下列情况下可以考虑建立索引。

    在主键属性列和外键属性列上通常都可以分别建立索引,不仅有助于唯一性检查和完整性检查,而且可以加快连接查询的速度
    以查询为主的关系可建立尽可能多的索引
    对等值连接,但满足条件的元组较少的查询可以考虑建立索引
    如果查询可以从索引直接得到结果而不必访问关系,则对此种查询可以建立索引

    该高校成绩管理系统数据库可建立以下索引:

    教师(教师编号)
    课程(课程编号)
    学生(学生学号,班级编号)
    班级(班级编号)
    学习(学号,课程编号)

    4.3 分区设计涉及到数据库文件和日志文件的分区问题。
    磁盘分区设计的一般原则:

    减少访问冲突,提高I/O并发性。多个事物并发访问同一磁盘时,会产生磁盘访问冲突而导致效率低下,如果事务访问数据均能分布于不同磁盘上,则I/O可并发执行,从而提高数据库访问速度
    分散热点数据,均衡I/O负担。在数据库中数据访问的频率是不均匀的,那些经常被访问的数据成为热点数据,此类数据宜分散存在于不同的磁盘上,以均衡各个磁盘的负荷,充分发挥多磁盘的并行操作的优势
    保证关键数据快速访问,缓解系统瓶颈。在数据库中有些数据如数据字典等的访问频率很高,为保证对它的访问不直接影响整个系统的效率,可以将其存放在某一固定磁盘上,以保证其快速访问

    该成绩管理系统由于程序较小,所以不进行分区设计。
    5、数据库实施建立数据库D01jiangnan

    5.1 基本表建立教师
    CREATE TABLE 教师jn( 教师编号jn CHAR(20) PRIMARY KEY, 教师姓名jn CHAR(10), 教师性别jn CHAR(2), 教师年龄hn INT, 职称jn CHAR(20), 联系电话jn CHAR(10),);
    专业
    CREATE TABLE 专业jn( 专业编号jn CHAR(20) PRIMARY KEY, 专业名称jn CHAR(20),);
    班级
    CREATE TABLE 班级jn( 班级编号jn CHAR(20) PRIMARY KEY, 班级名称jn CHAR(20), 专业编号jn CHAR(20) constraint Major_Class foreign key(专业编号jn) references 专业jn);
    课程
    CREATE TABLE 课程jn( 课程编号jn CHAR(20) PRIMARY KEY, 课程名jn CHAR(20), 教师姓名jn CHAR(10), 学时jn INT, 考试或考查jn CHAR(4), 学分jn CHAR(4));
    学生
    CREATE TABLE 学生jn( 学生学号jn CHAR(20) PRIMARY KEY, 学生姓名jn CHAR(10), 学生性别jn CHAR(2), 学生年龄jn int, 生源所在地jn char(20), 已修学分总数jn int, 班级编号jn CHAR(20) constraint Class_Student foreign key(班级编号jn) references 班级jn);
    上课
    CREATE TABLE 上课jn( 教师编号jn CHAR(20) , 班级编号jn CHAR(20) , PRIMARY KEY(教师编号jn,班级编号jn), CONSTRAINT Class_Teach1 FOREIGN KEY(教师编号jn) REFERENCES 教师jn, CONSTRAINT Class_Teach2 FOREIGN KEY(班级编号jn) REFERENCES 班级jn,);
    授课
    CREATE TABLE 授课jn( 教师编号jn CHAR(20) PRIMARY KEY, 课程编号jn CHAR(20), CONSTRAINT Course_Instruct FOREIGN KEY(课程编号jn) REFERENCES 课程jn CONSTRAINT Course_Instruct2 FOREIGN KEY(教师编号jn) REFERENCES 教师jn);
    学习
    CREATE TABLE 学习jn( 学生学号jn CHAR(20) , 课程编号jn CHAR(20), 学期jn char(10), 课程名称jn char(20), 成绩jn int, 教师姓名jn char(20), primary key(学生学号jn,课程编号jn), CONSTRAINT Course_Study FOREIGN KEY(课程编号jn) REFERENCES 课程jn);
    开设
    CREATE TABLE 开设jn( 课程编号jn CHAR(20) , 班级编号jn char(20), primary key(课程编号jn,班级编号jn), CONSTRAINT Class_Setup FOREIGN KEY(班级编号jn) REFERENCES 班级jn);
    5.2 视图的建立学生成绩统计
    create view 学生成绩统计jnas select 学习jn.学生学号jn,学生姓名jn,学习jn.课程名称jn, 班级名称jn,学习jn.教师姓名jn,学分jn,课程jn.学期jn,成绩jn from 学生jn, 课程jn, 班级jn,学习jn where 学生jn.学生学号jn = 学习jn.学生学号jn AND 学习jn.课程编号jn = 课程jn.课程编号jn AND 班级jn.班级编号jn = 学生jn.班级编号jn
    每门课程平均成绩统计
    create view 每门课程平均成绩jnas select avg(成绩jn) 平均成绩jn,课程编号jn from 学习jngroup by 课程编号jn
    学生所学课程及学分统计
    create view 学生所学课程及学分统计jn as select 学生学号jn, 课程名称jn, 学分jn from 学生成绩统计jn
    教师任课查询
    create view 教师任课查询jnas select 教师jn.教师编号jn, 课程jn.教师姓名jn, 课程jn.课程编号jn, 课程名jn, 学时jn, 学分jn from 教师jn, 课程jn,授课jn where 授课jn.课程编号jn=课程jn.课程编号jn and 授课jn.教师编号jn=教师jn.教师编号jn
    班级课程开设查询
    create view 班级课程开设查询jnas select 班级jn.班级编号jn, 班级jn.班级名称jn, 课程jn.课程编号jn, 课程名jn, 学时jn,学分jn from 班级jn, 课程jn,开设jn where 班级jn.班级编号jn = 开设jn.班级编号jn AND 开设jn.课程编号jn = 课程jn.课程编号jn
    地区学生数统计
    create view 地区学生数统计jnas select 生源所在地jn,count(学生学号jn) 地区学生总数jn from 学生jn group by 生源所在地jn
    5.3 索引的建立教师编号
    create unique index UI_教师编号jnon 教师jn(教师编号jn)
    专业编号
    create unique index UI_专业编号jn on 专业jn(专业编号jn)
    班级编号,专业编号
    create unique index UI_班级及专业jn on 班级jn(班级编号jn,专业编号jn)
    课程编号
    create unique index UI_课程编号jn on 课程jn(课程编号jn)
    学生学号,班级编号
    create unique index UI_学号及班级号jn on 学生jn(学生学号jn,班级编号jn)
    学生学号,课程编号
    create unique index UI_学号及课课程号jn on 学习jn(学生学号jn,课程编号jn)
    5.4 触发器建立当删除“教师jn”中的‘教师编号jn’记录时,需要相应地删除“授课jn”和“上课jn”里的“教师编号jn”,所以在“教师jn”上建立触发器:
    create trigger TR_DELETE_教师编号jnON 教师jninstead of deleteas delete from 授课jn from deleted where 授课jn.教师编号jn = deleted.教师编号jn delete from 上课jn from deleted where 上课jn.教师编号jn = deleted.教师编号jn delete from 教师jn from deleted where 教师jn.教师编号jn=deleted.教师编号jn
    当更新“教师jn”中的“教师编号jn”记录时,需要相应地更新“授课jn”和“上课jn”里的“教师编号jn”,所以在“教师jn”上建立触发器:
    create trigger TR_UD_教师编号jnON 教师jnfor update as if update (教师编号jn) begin update 授课jn set 教师编号jn = Ins.教师编号jn from deleted De,inserted Ins ,授课jn K where k.教师编号jn=De.教师编号jnendbegin update 上课jn set 教师编号jn = Ins.教师编号jn from deleted De,inserted Ins ,上课jn K where K.教师编号jn=De.教师编号jnend
    5.5 存储过程建立建立一个输入成绩,自动生成其总学分的存储过程:
    create procedure PRO_输入成绩自动生成学分jn@学生学号jn char(20),@课程编号jn char(20),@课程名jn char(20),@学期jn char(20),@成绩jn int,@教师姓名jn char(20)as begin update 学生jn set 学生jn.已修学分总数jn =学生jn.已修学分总数jn +(select 学分jn from 课程jn where @课程编号jn=课程编号jn ) where 学生jn.学生学号jn=@学生学号jnend
    6、系统简介登陆界面

    进入学生界面

    学生管理-个人信息

    学生管理-课程查询

    学生管理-班级开课

    学生管理-成绩查询

    学生管理-修改密码

    教师登陆


    教师管理-任课查询

    教师管理-查询自己教授不同课程的平均成绩

    教师管理-输入学生成绩

    管理员登陆

    管理员维护-管理教师信息

    管理员维护-管理学生信息

    管理员维护-生源地统计

    7、实验总结7.1 遇到的问题和解决的办法ER图,基本表设计问题
    开始的时候什么都不懂,上课学过的东西虽然朦朦胧胧有些听懂了,不知道如何使用。开始建E-R图的时候,先建好了教师,学生,班级的属性集,但是如何将他们结合起来,却是个大问题.后来与同学交流想明白,教师负责给班级授课,一个教师课上多门课程,一个班级可以选很多课,教师给学生打分时通过课程编号,班级编号,学号来选确定。
    另外加了三张表负责记录登陆时的账号和密码,为什么不把密码这一项加入学生,教师,管理员中呢?
    因为个人觉得密码一项和别的信息联系很少,独立出来更易管理。但是建的基本表越多,冗余和异常就越容易出现。
    SQL视图设计问题
    首先,刚开始写软件是一直是直接连接基本表,以为视图不会用到。但后来要实现复杂功能时,才意识到要用视图来实现,于是后期才实现视图。
    其次,我在设计基本表的时候,为了顾及信息的详细和全面,设计了12张基本表,为后面的设计带来了很大的麻烦。设计视图的时候,因为有很多信息的交叉,还有很多外键,需要很多自然连接 ,非常繁琐。
    触发器和存储过程设计问题
    表示触发器和存储过程上课没怎么讲,自己觉得很高深,一直不敢去动这一方面的设计。后来因为管理员删除教师时,必须要删除关联的‘授课表’,‘上课表’,还有教师输入某个同学成绩时,要同时修改‘学生表’中的‘已修学分总数’。才开始接触这一方面。但是语法还是理解了好久。
    由于前期理解问题,随便写了一个触发器,导致管理员无法正常删除教师,在同学细心指导下,重新写了一个trigger,测试通过。
    触发器:触发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS USER_TRIGGERS 数据字典中查到。
    存储过程:存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,是利用SQL Server所提供的Transact-SQL语言所编写的程序。经编译后存储在数据库中。存储过程是数据库中的一个重要对象,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,存储过程可由应用程序通过一个调用来执行,而且允许用户声明变量 。同时,存储过程可以接收和输出参数、返回执行存储过程的状态值,也可以嵌套调用。
    用NETBENS设计软件
    其实刚开始比较偏爱Eclipse,因为它挑错能力很强,还可以利用快捷键实现代码自动生成。选择NETBEANS是因为同学推荐,支持可视界面设计,自动生成相应代码.显然相比于用代码将组件一个一个的add进panel,这会大大缩短设计时间,但是这些auto-generated-code,冗余度很大,举个例子 javax.swing.JButton;java.awt.event.ActionListener.而这些自动生成的代码不允许用户修改。由于很纠结这一点,于是把代码复制到Eclipse下,自己手动修改这些代码,但是很烦,每改一次界面设计,NetBeans就会重构代码,意味着前面白改了,后来就放弃这种吃力的方法。
    虽然不需要敲很多代码,但是为了让界面布局合理花了好多时间去调组件参数,有时候修改一个组件的参数,相邻的组件都会改变,很复杂。
    实现对jButton,jComboBox的事件监听很方便,只要求把逻辑调对就可以了。
    数据库与NetBeans连接问题
    其实前期一直以为连接数据库很烦,后来在同学指导下学会如何接.Netbeans对数据库支持很好,在netbeans的IDE可以像SQL Server一样登陆数据库D01jiangnan,查看基本表,视图,能实现select,update,delete语句.还有需要配置软件编译时的库文件,必须要把sqljdbc4.jar放到编译库中去(sql server 2008及以上用 sqljdbc.jar文件,sql server 2005 要用sqljdbc,jar).还有连接数据库有两种方式:jdbc或者jtds.
    sql语句撰写问题在调试软件的时候,很多时候都是sql语句写错了,但因为sql类型是String,编译时查不出来,需要运行相关代码时才会报错。
    7.2 系统设计的不足数据库中数据量太少
    在进行数据设计的时候,只考虑了几个最简单的数据输入,可能只能用于应付作业,并不能用于实际。
    界面比较丑
    对于netbean使用比较生疏.而且逻辑上存在问题,修改比较繁琐。
    3 评论 16 下载 2019-05-01 11:59:46 下载需要15点积分
  • 基于C语言的操作系统

    项目目的
    通过参考、修改源码模块,实现自己的OS模块,加深对系统底层的认识
    理解汇编语言与底层硬件的交互

    开发环境
    操作系统:Ubuntu 14.04
    虚拟机:Bochs
    编辑器:Vim
    编译器:GCC

    任务描述修改或者重新实现参考源码的一个或多个模块
    系统界面

    实现细节重构alloc_imap_bit()与alloc_smap_bit()int alloc_imap_bit(int dev)//为新文件分配位置int alloc_smap_bit(int dev,int nr_sects_to_alloc)//为文件内容分配扇区空间由于上述两个函数功能相似,可合并为一个函数,故重构,以减少重复代码。将上述两个函数重构为:
    int alloc_ismap_bit(int dev,int nr_sects_to_alloc)其中原来两个函数的第一参数相同,故保留;而<code>alloc_imap_bit()</code>不含第二参数,且<code>alloc_smap_bit()</code>的第二参数<code>nr_sects_to_alloc//要求分配的扇区数</code>不应为0,故合并后的函数保留两个参数,当<code>nr_sects_to_alloc</code>为0时转入相应代码段实现<code>alloc_imap_bit()</code>的功能,不为0时转入相应代码段实现<code>alloc_smap_bit()</code>的功能。由此实现两个函数的合并。
    实现MESSAGE收发自行添加文件任务下的<code>MYFSMSG</code>和磁盘任务下的<code>DEV_MYFSMSG</code>两个MESSAGE。
    在用户进程中调用<code>myfsmsg()</code>,此函数用于收发<code>MYFSMSG</code> MESSAGE。
    文件任务接收<code>MYFSMSG</code> MESSAGE后发送<code>DEV_MYFSMSG</code> MESSAGE给磁盘任务,从而完成一次MESSAGE收发的模拟。
    以下为<code>myfsmsg()</code>函数代码实现,其他相关代码略。
    //myfsmsg()函数代码实现PUBLIC int myfsmsg(){ MESSAGE msg; msg.type = MYFSMSG; send_recv(BOTH, TASK_FS, &msg); assert(msg.type == SYSCALL_RET); return msg.FD;}下图为文件系统测试用户进程:
    其中<code>MyFSmsg gets fd=0</code>为MESSAGE收发的测试输出,其余为文件系统创建、打开、读取、删除的测试输出。

    输出磁盘信息获取<code>hdinfo[]</code>数组,根据<a href="http://read.pudn.com/downloads97/ebook/399380/ata_atapi-6.pdf" target="\_blank">ATAPI-6文档(P115 Table-Identify device information)</a>,分别取出<code>hdinfo[]</code>数组多个元素;其中,元素为十六进制,每一位(0或1)表示不同的属性,需要通过与运算(&),提取各位的值,判断0或1,据此来判断磁盘特性,并打印输出至显示屏。
    示例如下:
    int capabilities = hdinfo[49];printl("Timer values supported: %s\n",(capabilities & 0x2000) ? "Yes" : "No");下图为输出节选:

    修改屏幕滚动机制源代码中,屏幕由<code>SHIFT + UP/DOWN</code>来控制屏幕信息的滚动,但是在修改中发现,如果屏幕打印信息超过一定行数时,较早打印的信息将会被清空;通过直接修改代码中<code>SCR_SIZE</code>的值,使屏幕能够容纳更多的信息,而不用担心被清空。
    其他改动美化了输出界面,使得各部分测试输出更加易于辨认,结构清晰。修改了console相关的部分参数和常量,保证系统正常显示输出。修改了Makefile与bochsrc,保证系统运行。
    0 评论 0 下载 2019-06-17 16:20:11 下载需要10点积分
  • 基于JAVA和SQL SERVER数据库实现的个人财务管理系统

    一、需求分析个人财务管理系统是智能化简单化个人管理的重要的组成部分。并且随着计算机技术的飞速发展,计算机在管理方面应用的旁及,利用计算机来实现个人财务管理势在必行。本文首先介绍了个人财务管理系统的开发目的,其次对个人财务管理系统的需求分析做了详细的描述。接着,又对系统数据库设计和功能结构的划分做了详细论述。然后又对个人财务管理系统的实现做了详尽的说明。在报告的最后给出了项目的测试结果以及结果分析。
    本系统是对个人的收支情况做一个简单的管理,其中宝库哦个人信息管理以及收支信息管理。 其中,个人信息管理包括用户对自己的信息进行增删查改的一些操作,同样,收支信息管理包括用户对收支情况的信息进行增删查改的管理。
    1.1 系统业务需求该系统具体需求应该有用户登录模块,用户修改信息模块,用户修改信息模块,收支查询模块,收支删除模块,收支添加模块,收支修改模块。
    1.2 系统技术目标该系统的目标主要是能对个人信息以及收支信息进行较快的增删查改,同时也能对收支信息进行各种方式的查询。
    1.3 系统的具体需求根据以上对系统的任务和目标的分析,系统的具体需求如下:

    个人信息:用户名(唯一),密码,姓名,性别,出生日期,工作,身份证号,电话号码
    收支信息:收支编号(唯一),收支日期,收支方式,收支项目,收入金额,支出金额,,总金额

    二、软件功能结构分析由需求分析可知,软件的功能应包括:个人信息管理,收支信息管理。其中,个人信息应包括,个人信息的增删查该,登录时候验证功能。收支信息管理应包括对对收支信息的各种方式查询,以及对收支信息的增加,修改以及删除功能。当然,每个用户应对应其各自的收支信息。
    2.1 个人信息功能在登录界面用户输入用户名以及密码,如果用户与密码都输入正确则可以登录进系统,如果其中任何一项与数据库中的数据不匹配则要求重新输入。当用户没有账户时候,可以点击登录界面的注册按钮注册。成功进入系统后,可以进行个人信息的查询以及修改。
    具体流程图如下:

    2.2 收支管理功能用户登录成功后进入主界面后可以选择查询方式,全部查询:查询用户所有收入支出的信息;收入查询:查询用户收入信息;支出查询:查询用户支出信息;按日期查询:查询用户当天的收入支出信息。用户也可以对收入支出信息进行修改和删除以及添加。
    具体流程图如下:

    三、数据库设计经过以上的需求的分析以及系统功能的分析,需要建立出该系统数据库的各种模型,为建立一个好的,完善的数据库做准备。
    3.1 概念模型由于该系统涉及的较少,只涉及到用户以及财务管理,所以设计比较简单。一个用户可以有多条收支记录,所以用户表与收支表是一对多的关系。通过PowerDesigner工具设计出的概念数据模型如下:

    其对应的E-R模型如下图:

    3.2 逻辑模型联系转换
    一个用户可以有多条记录,而一条记录只能对应一个用户,所以用户与记录之间是一对多的关系。
    其逻辑结构设计如下

    个人信息(用户名,密码,姓名,性别,出生日期,工作,身份证号,电话号码)
    收支信息(收支编号,收支日期,收支方式,收支项目,收入金额,支出金额,总金额)

    关系模式

    个人信息(用户名,密码,姓名,性别,出生日期,工作,身份证号,电话号码)
    收支信息(收支编号,收支日期,收支方式,收支项目,收入金额,支出金额,总金额)

    3.3 物理模型通过PowerDesigner中的概念模型生成物理模型如下:

    3.4 表结构设计用户表

    收支信息表

    四、软件代码设计本系统是对个人财政的管理,下面给出具体的功能模块以及代码实现。
    4.1 功能模块登录界面模块

    说明:

    该界面为登录界面,如果没有账户,则可以点击注册按钮注册
    当用户输入的用户名或者密码输入错误时,会提示用户名或者密码输入错误
    当点击登录时,如果用户名以及密码都正确则会提示登录成功,并跳转到主界面

    用户注册模块

    说明:

    该界面为用户注册模块
    用户填入信息,其中用户名唯一,当用户名重复时会提示“用户名已存在,请重新输入”

    主界面模块

    说明:
    该界面为用户主信息界面

    用户可以有多种查询方式:全部查询(查询全部收支信息)、收入查询(只查询收入信息)、支出管理(只查询支出信息)、日期查询(查询当天收支信息)
    显示用户所有的收入总计、支出总计以及收入支出总计

    个人信息显示模块

    说明:

    该界面为用户显示模块
    用户如果不想使用该系统可以注销掉自己的账户

    个人信息修改模块
    说明:

    修改界面与个人信息查询界面在同一模块
    用户名不能修改

    收支信息插入模块
    说明:

    该界面为添加收支信息界面
    当点击主界面的插入按钮时候,会跳转到该界面
    收支编号不能重复


    收支信息修改界面

    说明:

    该界面为收支信息修改界面
    当点击主界面中的修改按钮时(必须选中一行),跳转到该界面
    收支编号不能修改

    收支信息删除界面
    说明:

    该功能与在主界面上
    选中一行,然后点击删除,即可提示删除成功

    4.2 代码实现登录界面主要功能实现(Login.java)
    jb1.addActionListener(new ActionListener() {//登陆按钮 public void actionPerformed(ActionEvent e) { jLabel5.setVisible(false); String ad = jf1.getText(); String pass = jf2.getText(); int i=0; String sc = "select userName,passWord from admin where userName='"+ad+"'"; try { ResultSet rs = st.executeQuery(sc); while (rs.next()) { i++; String userName = rs.getString("userName"); System.out.println(userName+"sdgdfgdf"); String password = rs.getString("passWord"); if (!ad.equals(userName)||userName.equals("")) { jLabel5.setVisible(true); } else if (!pass.equals(password)) { jLabel6.setVisible(true); } else { JOptionPane.showMessageDialog(null, "登陆成功!"); Show show = new Show(); show.s=jf1.getText(); show.setVisible(true); setVisible(false); } } System.out.println(i+"sdfd"); } catch (SQLException ex) { Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex); } if(i==0){ jLabel5.setVisible(true); } } });
    说明:该代码实现了登录界面的登录、判断用户名与密码输入是否正确。当用户名或者密码输入错误的时候会提示用户名或者密码错误。同时还添加了一个注册按钮让没有账户的用户注册账户。
    用户注册功能实现(UserInsert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { String s1 = jf1.getText();//y用户名 String s2 = jf2.getText();//姓名 String s12 = jf7.getText();//密码 String s3 = (String) jcb.getSelectedItem();//性别 String s5 = jf4.getText();//职业 String s6 = jf5.getText();//身份证号码 String s7 = jf6.getText();//电话号码 String s8 = (String) jcb1.getSelectedItem(); String s9 = (String) jcb2.getSelectedItem(); String s10 = (String) jcb3.getSelectedItem(); String s11 = s8 + "-" + s9 + "-" + s10;//出生日期 ResultSet rs; String str ="select userName from admin where userName='"+s1+"'"; rs = st.executeQuery(str); int i=0; while (rs.next()) { i++; } if (i == 0) { if (s6.length() != 18 || s7.length() != 11) { if (s6.length() != 18) { jLabel5.setVisible(true); } if (s7.length() != 11) { jLabel14.setVisible(true); } } else { String sql = "insert into admin Values ('" + s1 + "','" + s12 + "','" + s2 + "','" + s3 + "','" + s11 + "','" + s7 + "','" + s5 + "','" + s6 + "')"; st.executeUpdate(sql); JOptionPane.showMessageDialog(null, "注册成功"); setVisible(false); } } else{ jLabel15.setVisible(true); } } catch (SQLException ex) { Logger.getLogger(UserInsert.class.getName()).log(Level.SEVERE, null, ex); } } });
    说明:该代码实现了个人信息的注册,其中用户名唯一,重复会给出提示“用户名已存在”,并且判断身份证与电话号码填写的格式是否正确。*
    全部查询实现函数(Show.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收入查询实现函数(Show.java)
    jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    支出查询实现函数(Show.java)
    jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    日期查询实现函数(Show.java)
    jb4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息查询功能模块(Show.java)
    jb9.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息修改功能模块(User.java)
    jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息删除功能模块(User.java)
    Jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息插入功能模块(UserInsert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息添加功能模块(Insert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息删除功能模块(show.java)
    Jb7.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    五、总结通过该课程设计,我认识到软件设计是基于需求分析和可行性分析的基础上的,软件设计阶段需要合理的分析需求分析中的细节部分的实现,既要考虑到关键处代码的可实现性,又要考虑到开发过程中遇到的问题。刚开始觉得该 项目建立的数据库比较简单,没有认真进行需求分析,所有导致后面举步维艰。后来重新进行需求分析,一步一步来,最终完成了该课程设计。软件设计是把需求分析中的问题抽象化,又要把抽象化了的需求形象的从预期的实现中体现出来。 本小组的个人财务管理系统系统的设计实现了预期的功能,对个人消费进行记录,个人的收入进行统计,对个人收支进行汇总并给出相应的理财提示信息。在这次的个人财务管理系统设计中将理论知识应用到实际中使得对理论知识的理解有了更进一步的理解,如果仅仅只是运用理论知识,是远远不够的。必须理论联系实际,才能很好的将各门课程学好,并用于实际案例中。
    这次设计使我的编程水平提高了一大步。由于这次设计涉及到数据库,我的学到了不少编程工具与数据库连接的知识,对数据库的操作有了进一步的了解。这次设计对我的综合能力是一次很好的锻炼,自己的能力和知识还很有限。所以今后我的学习道路还是很漫长的。
    2 评论 129 下载 2018-10-25 21:36:27 下载需要6点积分
  • 基于Android Studio实现的2048游戏

    1 需求分析1.1 背景与意义1.1.1 手机应用市场发展现状随着4G越来越普及以及手机应用的日益丰富还有智能水平的不断提高,从便携性和随身性这两方面来考虑,电脑所带来的体验已经不能跟手机相提并论了,它已经完美的超越了电脑。
    现如今Android、苹果等各智能手机已经基本占领整个手机市场,从而使得更多应用的出现,而手机游戏应用在其中占领主要位置。
    随着Android智能手机的普及以及游戏种类的多元化,使得Android手机游戏用户规模保持着稳步增长之势。
    1.1.2 国内外现状目前国内外的Android开发还是主要以应用开发为主,主要分成三类:企业应用、通用应用及游戏应用。企业应用的开发主要是一些大公司为了自己的品牌而开发的;通用应用主要是一些创业型公司或者独立开发者为了自己盈利开发的应用;游戏应用目前和通用应用相同。
    2048小游戏是一款最近风靡全球的手机游戏,简单的游戏模式和趣味的玩法,几乎游戏下载排行榜的前20名都可以看到“它的身影”。
    1.1.3 此游戏的意义现如今,手机游戏已在我们的生活中占据一席之地,并在一步步的壮大。可以说,随着它的迅猛发展,现今的手机游戏已经不单单是一种缓解压力的工具,而是形成了一种文化现象。随着游戏软件在市场的一步步壮大,与其有关的文化也随之传播。
    2048游戏的制作属于电子游戏中益智类小游戏,它做到了娱乐性、趣味性、教育性相统一。益智类的游戏即是需要去开动大脑思考从而获得游戏的胜利。简单的益智类游戏可以使玩家在娱乐中不断地开发大脑。这样一来就实现了在娱乐中学习。
    1.2 系统需求分析1.2.1 系统功能需求分析系统主要实现以下的几个功能:呈现游戏界面、重新开始游戏、当前分数和最高分数、游戏帮助等功能。
    重新开始游戏是当玩家无法满足当前进度时点击此按钮就会重新开始游戏,如果玩家处于不同关卡时提示重新开始游戏还是停留在此关卡。游戏帮助是当新手玩此游戏时无法知道游戏玩法时给予相应的提示。呈现游戏界面是游戏开始时主界面在游戏区域会生成4x4的矩阵同时在矩阵里面随机生成两个2或4的游戏卡片。当前分数和最高分数是显示此局玩家所获得的分数和历史上最高的分数,如果当前的分数超过最高的分数,那么最高分数显示当前的分数。如下图所示:

    1.2.2 游戏的基本规则在开始游戏后玩家通过滑动屏幕来操控卡片的移动方向,当卡片滑动中如果有两张卡片相同且他们中间也没有其他卡片时,在滑动的过程中这两张卡片会合并,显示为这两张卡片之和。在滑动过程中有三张卡片相同时只会合并向滑动方向两张卡片。在滑动中如果有两张卡片一样同时又有一张卡片的值跟这两张卡片相加的值时,滑动只会使那两张相同的卡片合并而不会接着让合并后的卡片和另一张卡片合并。
    2 系统分析与设计2.1 系统流程设计游戏进入开始页面,能够进入游戏的主界面并开始普通开局,从主界面能够重新开始游戏、查看帮助和进入关卡选择界面。当玩家点击重新开始按钮会弹出相应的对话框让玩家选择,如果玩家选择“是”时则重新开始游戏,如果选择“否”则返回游戏界面不做任何处理。在开始界面按返回按钮时则会退出游戏。
    游戏流程如下图所示:

    2.2 系统模块设计从总体出发,将该系统划分为三大模块:“菜单设计”、“界面设计”和“算法设计”。
    2.2.1 菜单设计菜单的实现是在游戏界面,可进一步划分为三个模块,分别是:“重新开始”、“退出游戏”、“游戏帮助”,如图所示:

    2.2.2 界面设计


    开始界面
    游戏界面









    2.2.3 算法设计当有两张卡片相同时,向它们可以碰撞的方向滑屏,卡片会移动到最底边并生成其两倍数字的卡片,并且生成一个“2”或者“4”的卡片。如图所示:



    生成2
    生成4









    当有两张卡片相同时,且在它们相同的方向有张跟他们之和的卡片,向它们可以碰撞的方向滑屏,相同的卡片会移动到无法移动的位置并生成其两倍数字的卡片,但合成的方向不会跟那两张数字的卡片合并,并且生成一个“2”或者“4”的卡片。如图所示:



    生成2
    生成4









    当界面上没有空位并且两两相邻的卡片不相同时游戏结束。如图所示:

    2.3 本章小结本章主要对游戏所实现的功能进行需求分析,分析了图形的特点和实现的可行性。对系统的性能进行了详细的分析。对系统的流程,系统所需的图形文件,系统的总体架构和系统用例进行了设计。通过本章的分析、设计能更加具体的了解系统功能,对系统所要实现的功能和图形文件有了更深的认识。为下一章系统功能的具体实现提供了可靠的参考依据。
    3 系统实现3.1 开始界面的实现游戏的主界面是按钮,只是为了实现界面的跳转,当玩家点击开始游戏就会调用loginActivity.java,此函数让页面跳转到游戏界面开始游戏,代码及图片如下所示:
    public class loginActivity extends MainActivity { protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.login); }}

    3.2 游戏界面的实现游戏界面主要是在activity_main.xml中当前分数、最高分数、重新开始按钮、退出游戏按钮、游戏帮助按钮、帮助按钮,当跳转到游戏界面时就会调用并执行MainActivity.java函数来展示游戏界面,代码及图片如下所示:
    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);}

    3.3 游戏滑动卡片移动的实现当玩家滑动屏幕时,主要通过GameView函数来监听玩家手指滑动的位置,先通过获取开始坐标和结束坐标,然后通过比较结束坐标跟开始坐标的差值来判断玩家是怎么滑动屏幕的。判断出玩家的滑动轨迹后,通过调用swipeLeft、swipeRight、swipeUp、swipeDown方法来实现卡片的移动,代码及图片如下所示:
    private void initGameView(){ setColumnCount(4); //将面板设置成4列 setBackgroundColor(0xffbbada0); System.out.println("initGameView"); setOnTouchListener(new View.OnTouchListener() { /* * startX:手机刚开始在屏幕上的X坐标 * startY:手机刚开始在屏幕上的Y坐标 * offsetX,offsetY,分别是手指在屏幕上的X,Y上的偏移量 */ private float startX,startY,offsetX,offsetY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_UP: offsetX = event.getX() - startX; offsetY = event.getY() - startY; if(Math.abs(offsetX) > Math.abs(offsetY)){ if(offsetX < -5){ swipeLeft(); System.out.println("Left"); }else if(offsetX > 5){ swipeRight(); System.out.println("Right"); } } else{ if(offsetY < -5){ swipeUp(); System.out.println("Up"); }else if(offsetY > 5){ swipeDown(); System.out.println("Down"); } } break; } return true; } });}//向左滑动public void swipeLeft(){ boolean meger = false; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { for (int x1 = x+1; x1 < 4; x1++) { if(cardsMap[x1][y].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x1][y].getNum()); cardsMap[x1][y].setNum(0); x--; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x1][y])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x1][y].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger = true; } break; } } } } if(meger){ addRandomNum(); checkComplete(); }}//向右滑动public void swipeRight(){ boolean meger = false; for (int y = 0; y < 4; y++) { for (int x = 3; x >=0; x--) { for (int x1 = x-1; x1 >= 0; x1--) { if(cardsMap[x1][y].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x1][y].getNum()); cardsMap[x1][y].setNum(0); x++; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x1][y])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x1][y].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger =true; }break; } } } } if(meger){ addRandomNum(); checkComplete(); }}//向上滑动public void swipeUp(){ boolean meger = false; for (int x= 0; x< 4; x++) { for (int y = 0; y < 4; y++) { for (int y1 = y+1; y1 < 4; y1++) { if(cardsMap[x][y1].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x][y1].getNum()); cardsMap[x][y1].setNum(0); y--; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x][y1])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x][y1].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger =true; } break; } } } } if(meger){ addRandomNum(); checkComplete(); }}//向下滑动public void swipeDown(){ boolean meger = false; for (int x = 0; x< 4; x++) { for (int y = 3; y>= 0;y--) { for (int y1 = y-1; y1 >=0; y1--) { if(cardsMap[x][y1].getNum()>0){ if(cardsMap[x][y].getNum()<=0){ /* * 将下标为(x,y)所在位置的卡片上的数字 * 设置为,坐标为(x1,y)所在位置的卡片上的值; * 第二步,将坐标(x1,y)所在位置的卡片上的数字 * 设置为0 * (即:变成空卡片) */ cardsMap[x][y].setNum( cardsMap[x][y1].getNum()); cardsMap[x][y1].setNum(0); y++; meger =true; break; }else if(cardsMap[x][y].equals(cardsMap[x][y1])){ cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2); cardsMap[x][y1].setNum(0); MainActivity.getMainActivity(). addScore(cardsMap[x][y].getNum()); meger =true; } break; } } } } if(meger){ addRandomNum(); checkComplete(); }}



    效果1
    效果2









    3.4 重新开始游戏功能的实现当玩家点击游戏界面的重新开始游戏时,会弹出给玩家选择的对话框,让玩家选择“是”时游戏会重新开始,代码及图片如下所示:
    public void onClick(View view){ AlertDialog.Builder dialog3 = new AlertDialog.Builder(this); dialog3.setTitle("提示:"); dialog3.setMessage("你确定重新开始吗?"); dialog3.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog3.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog3.show(); }

    3.5 退出游戏功能的实现当玩家中途有事想退出游戏时会弹出给玩家选择的对话框,让玩家选择“是”时游戏会退出,代码及图片如下所示:
    public void onClick(View view){ AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setTitle("提示:"); dialog.setMessage("你确定要离开吗?"); dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); } }); dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); dialog.show(); }

    3.6 游戏帮助功能的实现当新玩家进入到游戏且不知道此游戏玩法时,玩家可以点击游戏帮助按钮来了解游戏玩法,点击按钮时游戏会弹出对话框显示游戏玩法,代码及图片如下所示:
    public void onClick(View view){ AlertDialog.Builder dialog2 = new AlertDialog.Builder(this); dialog2.setTitle("hey,guy!"); dialog2.setMessage("这么简单的游戏你确定需要帮助?"); dialog2.setNegativeButton("继续玩~", new DialogInterface.OnClickListener({ @Override public void onClick(DialogInterface dialog, int which) { } }); dialog2.show();}

    3.7 本章小结本章主要阐述本游戏相关功能的实现,详细的讲述了主界面的实现和各按钮功能的实现。
    4 测试本章主要对系统的功能进行测试,此次测试只是进行简单的调试,来确定游戏的各项功能是否能够正常运行。
    4.1 游戏流程测试该测试主要验证游戏能否实现场景的切换,当界面在开始界面时只显示按钮画面,当玩家点击此界面的开始按钮时跳转到游戏界面,如图所示:



    效果1
    效果2









    4.2 游戏模式该测试主要是测试游戏能否正常运行,当玩家滑动屏幕时能否正常的移动和当卡片相同时是否能够相加,还有就是测试游戏是否能正常结束。



    效果1
    效果2









    4.3 本章小结本章是对游戏系统进行简单的测试,通过测试可以看出此游戏可以正常的工作,同时一些功能也能够实现。
    5 总结本次课程设计的内容大部分都是参照课堂所讲以及一些网站给出的各种建议写的,在写的过程中遇到了很多问题,学到了很多东西。期间大概是因为基础不够好,只是找错误就花了很长时间。不过正因为这些错误,才能学到更多的知识,才能把知识点掌握的更牢靠,对于一些没有实现的功能,之后我一定会多花费些时间研究出来。我的课程设计优化的空间还相当大,希望老师能给出指导!
    5 评论 199 下载 2018-12-20 18:49:18 下载需要8点积分
  • 基于JSP实现的个人网站

    摘 要本报告是JSP程序设计的期末设计的课程设计报告。本网站基本满足了所有需要的内容和功能需求,包含了个人的简介,家乡的介绍,包括个人的信息,留言板等内容。
    也包含了数据库的增(用户注册,留言板的留言等),删(个人留言支持删除),改(个人信息的修改等),查(留言板的查看,个人信息的查看等)四个功能。数据库的3张表,包括用户登录信息表,用户个人信息表,留言板内容表。
    主题:JSP、增删改查、数据库、个人服务器
    1、系统设计背景意义1.1 开发背景随着WWW(World Wide Web)的普及,动态网页技术也急速发展。从原来的CGI(Common Gateway In-terface)到ASP(Active Server Page),都从某种程度上满足了网页开发人员对动态网页开发技术的需求。但是不管是CGI还是ASP都存在一定的局限性,如CGI对服务器资源的耗费,ASP只能同Microsoft IIS一起使用等,这些都限制了这些技术的使用范围,极大地阻碍了它们的推广。
    广大的页面开发人员都热切地盼望一种统一的页面开发技术,该技术应该具有的特点:

    与操作平台无关,能够在任何Web或应用程序服务器上运行
    将应用程序逻辑和页面显示分离
    提供代码重用,简化开发基于Web的交互式应用程序的过程

    JSP(Java Server Page)技术就是被设计用来满足这样的要求的。JSP是由Sun MicroSystem公司于1999年6月推出的新的网页开发技术,它是基于Java Serv-let以及整个Java体系的Web开发技术,是Servlet2.1API的扩展。利用这一技术,可以建立先进、安全和跨平台的动态网站。
    1.2 研究现状JSPJava语言以不依赖于平台、面向对象、安全等优良特性成为网络程序设计语言中的佼佼者。目前,许多与Java有关的技术得到了广泛的应用与认可,JSP(JavaServerPages)就是其中之一。JSP是基于Java语言的一种Web应用开发技术,可以建立安全、跨平台的先进动态网站。
    许多Web网站都使用了JSP技术。利用JSP技术创建的Web应用程序可以实现动态页面与静态页面分离,便于Web应用程序的扩展和维护。由于JSP是基于Java语言的Web技术,相对其他Web技术,JSP具有脱离硬件平台束缚、编译后运行等优点,已成为Internet上的主流Web技术之一。
    2 、需求分析2.1 系统需求分析设计一个个人网站,网站内容必须包括个人的基本信息(含个人照片),比如个人爱好,家乡特产、特色旅游等静态网页内容;必须调用数据库,且具备数据库的增删改查的功能,这是动态网页部分内容。
    2.2 数据需求需要一个数据库,包括三张数据表,分别记录用户的登录信息,记录用户每个人的用户信息,记录用户的留言内容。
    3 、系统设计3.1 系统原理
    3.2 数据库设计3.2.1 数据库概念结构设计数据库概念结构设计是在需求分析的基础上,设计出能够满足用户需求的各种实体,以及它们之间的关系,为后面的逻辑结构设计打下基础。用E-R图是描述数据实体关系的一种直观描述工具,所以本系统采用了E-R图的方法进行数据库概念结构设计。
    用户登陆E-R图

    用户实体E-R图

    留言板E-R图

    实体之间关系E-R图

    3.3.2 数据库逻辑结构设计概念结构是独立于实际数据模型的信息结构,必须将其转化为逻辑结构后才能进行数据库应用的设计。也就是要将概念上的结构转化为BP数据库系统所支持的实际数据模型。
    个人网站数据库中各个表格的设计结果如下面的四个表所示。每个表表示数据库中的一个表。
    用户登录表

    username:记录用户注册时的用户名
    password:记录用户注册时的密码

    且用户名和密码均不能为空值,所以在提交到数据库之前已经在网页中进行检查。


    用户留言板表

    username:记录留言的用户
    date:记录用户留言的时间,精确到秒。格式为“YYYY-MM-DD HH-MM-SS”
    message:记录用户留言的内容,格式为TEXT

    注:date的记录利用数据库自带的now()函数,方便网页的内容的传输。


    用户信息表

    username:记录个人信息的所有者
    gender:记录用户的性别
    age:记录用户的年龄
    phone_number:记录用户的联系方式
    school:记录用户的所在学校
    address:记录用户的地址



    3.4 系统模块设计
    4、系统实现4.1 欢迎页(index.jsp)本页是网站的第一页,可以选择用户登录(login.jsp)或者跳过登录直接进去主页(Home.jsp),如果没有注册,可以点击注册按钮,进入注册页面(register.jsp)。
    效果示意图:

    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head><style> body{ text-align:center; background: url("./img/bg.jpg") fixed center center no-repeat; background-size: cover; width: 100%; } #center{ margin:0 auto; border:1px soild #000; width:300px; height:100px } *{ padding: 0; margin: 0; } .black_half{ padding: 25px; background-color: rgba(0,0,0,0.5); } .black_half h1{ color: #FFFFFF; } .black_half a{ text-decoration:none; color: #FFFFFF; } .black_half a:hover{ text-decoration:underline; color: #FFFFFF; } .white h3{ color: #FFFFFF; }</style><title>欢迎——…的期末作业</title></head><body> <br><br> <div class="black_half"> <h1>W E L C O M E !</h1> </div> <div class="black_half"> <h2> <a href="login.jsp">用户登陆</a>   <a href="register.jsp" style="font-size:12px;">还没有账号?点此注册</a> </h2><br> <h2> <a href="Home.jsp">我是游客,跳过登录</a> </h2> </div> <br><br> <div class="white"> </div></body></html>
    4.2 主页(Home.jsp)本页面是网站的主页,内容比较简单。
    最上端的是导航栏,如果前面选择了登陆,则左上角会显示“您好,xxx”,可以选择退出登录,右边导航栏也会多一个“个人信息”按钮,可以进入个人信息页面(details.jsp)。
    如果未登录,会显示“您还未登陆,点击登录” ,可以选择登录按钮,进入(login.jsp)。
    右边导航栏的其他按钮还包括作者简介(profile.jsp)、家乡介绍(hometown.jsp)、留言板(board.jsp)、关于(about.jsp)、返回欢迎页(index.jsp)。
    效果示意图:

    <!DOCTYPE html><html><head> <title>主页</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <% String username = (String)session.getAttribute("username"); if (username != null){ out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  "); } else{ out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  "); } %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <% if (username != null){ out.println("<li><a href='details.jsp'>个人信息</a></li>"); } %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><div class = white_box> <p style="font-size:200px;">你好。</p> <p style="font-size:200px;" align="right">欢迎。</p></div></body></html>
    4.3 注册(register.jsp/checkregister.jsp)本页面是网站的注册页面,包含两个jsp文件,register.jsp获取用户输入的表单,包括用户名和两次密码,在通过js函数判断(判断用户名、密码是否为空,两次密码是口相同)之后通过onsubmit的方法决定是否将表单传送给checkregister.jsp。
    如果通过判断,checkregister.jsp连接数据库并先用select查询是否存在用户名相同的用户,如果不存在用insert的sql语句把用户信息输入数据库,并返回注册成功或者失败的提示框,如果成功跳转到主页,如果失败跳转回注册页面。
    效果示意图:

    register.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head><title>用户注册</title></head><style> @import"style.css"</style><script> function addCheck() { var username = document.regfrm.username.value; var password = document.regfrm.password.value; var double_times = document.regfrm.double_times.value; if (username == "") { alert("用户名不能为空!"); return false; } if (password == "") { alert("密码不能为空!"); return false; } if (password != double_times) { alert("两次输入密码不相同!"); return false; } } function validate() { var flag = addCheck(); if (flag == false) return false; return true; }</script><body> <div id = center> <form action="checkregister.jsp" method="post" name = "regfrm" onsubmit="return validate();"> <table class="hovertable"> <tr> <td colspan="5" align="center" style="font-size:30px;height:80px;width:300px;"><strong>注册</strong></td> </tr> <tr > <th>用户名:</th> <td><input type="text" name="username" value="输入16个字符以内" maxlength="16" onfocus="if(this.value == '输入16个字符以内') this.value =''"></td> </tr> <tr> <th>输入密码:</th> <td><input type="text" name="password" value="输入20个字符以内" maxlength="20" style="width:200px;" onfocus="if(this.value == '输入20个字符以内'){this.value =''; this.type='password'}"></td> </tr> <tr> <th>确认密码:</th> <td><input type="text" name="double_times" value="请再次输入密码" maxlength="20" style="width:200px;" onfocus="if(this.value == '请再次输入密码') {this.value =''; this.type='password'}"></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" value=" 注 册 "> <input type ="button" value=" 返回登陆 " onclick="location='login.jsp'"> </td> </tr> <tr> <td colspan="5" align="center"><a href="index.jsp"> 返 回 主 页 </a></td> </tr> </table> </form> </div></body></html>
    checkregister.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ page import = "java.sql.*" %><!DOCTYPE html><html><body> <% String user = new String(request.getParameter("username").getBytes("ISO8859_1"),"utf-8"); String pwd = new String(request.getParameter("password").getBytes("ISO8859_1"),"utf-8"); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); PreparedStatement pStmt = conn.prepareStatement("select * from user_data.user_info where username = '" + user + "'"); ResultSet rs = pStmt.executeQuery(); if(rs.next()){ out.println("<script language='javascript'>alert('该用户已存在,请直接登陆!');window.location.href='register.jsp';</script>"); } else{ PreparedStatement tmt = conn.prepareStatement("Insert into user_data.user_info values('" + user + "','" + pwd + "')"); int rst = tmt.executeUpdate(); if (rst != 0){ PreparedStatement tmt2 = conn.prepareStatement("Insert into user_data.details values('" + user + "',1,0,' ',' ',' ')"); tmt2.executeUpdate(); out.println("<script language='javascript'>alert('用户注册成功!');window.location.href='login.jsp';</script>"); } else{ out.println("<script language='javascript'>alert('用户注册失败!');window.location.href='register.jsp';</script>"); } } %></body></html>
    4.4 登陆(login.jsp/checklogin.jsp)本页面是网站的登陆页面,包含两个jsp文件,login.jsp获取用户输入的表单,包括用户名和两次密码,在通过js函数判断(判断用户名、密码是否为空)之后通过onsubmit的方法决定是否将表单传送给checklogin.jsp。
    如果通过判断,checklogin.jsp连接数据库并通过select的sql语句查询数据库中用户信息,如果成功显示登陆成功的消息框并跳转到主页,如果失败显示登陆失败的消息框跳转回登陆页面。
    效果示意图:

    login.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head><title>用户登陆</title></head><style> @import"style.css"</style><script> function validateLogin() { var userName = document.frmLogin.username.value; var password = document.frmLogin.password.value; if ((userName == "") || (userName == "输入您的用户名")) { alert("请输入用户名!"); return false; } if ((password == "") || (password == "输入您的密码")) { alert("请输入密码!"); return false; } }</script><body> <div id = "center"> <form action="checklogin.jsp" method="post" name="frmLogin"> <table class="hovertable" > <tr> <td colspan="5" align="center" style="font-size:30px;height: 80px;width:300px;"><strong>登陆</strong></td> </tr> <tr> <th style="font-size:15px;">用户名:</th> <td style="font-size:15px;"><input type="text" name="username" value="输入您的用户名" maxlength="16" style="width:200px;" onfocus="if(this.value == '输入您的用户名') this.value =''"></td> </tr> <tr> <th style="font-size:15px;">密 码:</th> <td style="font-size:15px;"><input type="text" name="password" value="输入您的密码" maxlength="20" style="width:200px;" onfocus="if(this.value == '输入您的密码'){this.value =''; this.type='password'}"></td> </tr> <tr> <td colspan="5" align="center" style="font-size:15px;"> <input type="submit" value=" 登 录 " onclick="return validateLogin()"> <input type ="button" value=" 新用户注册 " onclick="location='register.jsp'"> </td> </tr> <tr> <td colspan="5" align="center"><a href="index.jsp"> 返 回 主 页 </a></td> </tr> </table> </form> </div></body></html>
    checklogin.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ page import = "java.sql.*" %><!DOCTYPE html><html><body> <% String username = new String(request.getParameter("username").getBytes("ISO8859_1"),"utf-8"); String password = new String(request.getParameter("password").getBytes("ISO8859_1"),"utf-8"); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); if(conn != null){ String sql = "select * from user_data.user_info where username='"+username+"' and password='"+ password + "'"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); if(rs.next()){ session.setAttribute("username",username); out.println("<script language='javascript'>alert('登录成功!');window.location.href='Home.jsp';</script>"); } else{ out.println("<script language='javascript'>alert('登录失败!');window.location.href='login.jsp';</script>"); } } %></body></html>
    4.5 个人信息(details.jsp/setdetails.jsp/getdetails.tag)本页面是网站的个人信息页面,每次打开页面getdetails.tag都会从数据库中查询个人信息(每个新注册的用户默认都是空数据的),并显示在details.jsp中。并且可以修改表中的数据,点击修改按钮,表中的数据会以表单的形式以post的方式传递给setdetails.jsp,该setdetails可以连接数据库并通过update方式修改数据库。
    效果示意图:

    details.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="getdetails" %><%@ page import = "java.sql.*" %><!DOCTYPE html><html><head> <title>个人信息</title> <style> @import"style.css" </style></head><body><getdetails:getdetails></getdetails:getdetails> <div id = center> <form action="setdetails.jsp" method="post" name="set_details"> <table class="hovertable"> <tr> <td colspan="5" align="center" style="font-size:30px;height: 80px;width:350px;"><strong>个人信息</strong></td> </tr> <tr> <th>性别:</th> <td> <label> <input type="radio" name="gd" id="" class="a-radio" value=1 <%= gender==1?"Checked":"" %> > <span class="b-radio"></span>男 </label> <label> <input type="radio" name="gd" id="" class="a-radio" value=0 <%= gender==0?"Checked":"" %> > <span class="b-radio"></span>女 </label> </td> </tr> <tr> <th>年龄:</th> <td> <label> <input type="text" type="text" name="age" value = <%=age %> style="width:200px;" maxlength="2"> </label> </td> </tr> <tr> <th>联系方式:</th> <td> <label> <input type="text" type="text" name="phone_number" style="width:200px;" maxlength="11" value = <%=phone_number %> > </label> </td> </tr> <tr> <th>所在学校:</th> <td> <label> <input type="text" type="text" name="school" style="width:200px;" maxlength="40" value = <%=school %> > </label> </td> </tr> <tr> <th>详细地址:</th> <td> <label> <input type="text" type="text" name="address" style="width:200px;" maxlength="40" value = <%=address %> > </label> </td> </tr> <tr> <td colspan="2"> <input type = "submit" value = " 修 改 "> <input type = "button" value = " 返 回 " onclick="location='Home.jsp'"> </td> </tr> </table> </form> </div></body></html>
    setdetails.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ page import = "java.sql.*" %><!DOCTYPE html><html><body> <% String gender = new String(request.getParameter("gd").getBytes("ISO8859_1"),"utf-8"); String age = new String(request.getParameter("age").getBytes("ISO8859_1"),"utf-8"); String phone_number = new String(request.getParameter("phone_number").getBytes("ISO8859_1"),"utf-8"); String school = new String(request.getParameter("school").getBytes("ISO8859_1"),"utf-8"); String address = new String(request.getParameter("address").getBytes("ISO8859_1"),"utf-8"); String username = (String)session.getAttribute("username"); int _gender = Integer.parseInt(gender); int _age = Integer.parseInt(age); Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); if(conn != null){ PreparedStatement tmt2 = conn.prepareStatement("UPDATE user_data.details set gender="+ _gender +",age="+ _age +",phone_number='"+ phone_number +"',school='"+ school +"',address='"+ address +"' where username='"+username+"'"); int rst = tmt2.executeUpdate(); if(rst != 0){ out.println("<script language='javascript'>alert('修改成功!');window.location.href='details.jsp';</script>"); } else{ out.println("<script language='javascript'>alert('修改失败!');window.location.href='Home.jsp';</script>"); } } %></body></html>
    getdetails.tag
    <%@ tag language="java" pageEncoding="utf-8"%><%@ tag import="java.sql.*" %><%@ variable name-given="gender" variable-class="java.lang.Integer" scope="AT_END"%><%@ variable name-given="age" variable-class="java.lang.Integer" scope="AT_END"%><%@ variable name-given="phone_number" variable-class="java.lang.String" scope="AT_END"%><%@ variable name-given="school" variable-class="java.lang.String" scope="AT_END" %><%@ variable name-given="address" variable-class="java.lang.String" scope="AT_END"%><% String username = (String)session.getAttribute("username"); if (username != null){ Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://127.0.0.1:3306/user_data"; String um = "root"; String psw= "8876"; Connection conn = DriverManager.getConnection(url, um, psw); if(conn != null){ String sql = "select * from user_data.details where username='"+username+"'"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); if(rs.next()){ String ss = rs.getString(1); int gender = rs.getInt(2); int age = rs.getInt(3); String phone_number = rs.getString(4); String school = rs.getString(5); String address = rs.getString(6); jspContext.setAttribute("gender", gender); jspContext.setAttribute("age", age); jspContext.setAttribute("phone_number", phone_number); jspContext.setAttribute("school", school); jspContext.setAttribute("address", address); } } } else{ out.println("<script language='javascript'>alert('请先登录!');window.location.href='login.jsp';</script>"); }%>
    4.6 作者简介(profile.jsp)本页面是本网站的个人简介页面,除了导航栏之外为静态网页,简单的自我介绍。
    效果示意图:

    profile.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><!DOCTYPE html><html><head> <title>作者简介</title><style> @import"home_style.css"</style></head><body> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <% String username = (String)session.getAttribute("username"); if (username != null){ out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  "); } else{ out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  "); } %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>"); } %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><div class = white_box> <div style="text-align:center;"> <br> <h1><b>作者简介——我</b><br></h1> <br> <img src="./img/myphoto.jpg" style="display:block;max-height:200px;max-width:200px;margin:0 auto;"/><br> <br> <h2 style="display:inline;">name:</h2> <br><br> <h2 style="display:inline;">pingyin:</h2> <br><br> <h2 style="display:inline;">En-name:</h2>Ray8876 <br><br> <h2 style="display:inline;">birth:</h2>1998-08 <br><br> <h2 style="display:inline;">phone:</h2>158****2095 <br><br> <h2 style="display:inline;">e-mail:</h2> <br><br> <h2 style="display:inline;">school:</h2>中国计量大学现代科技学院 <br><br> <h2 style="display:inline;">major:</h2> <br><br> <h2 style="display:inline;">class:</h2> </div></div></body> </html>
    4.7 家乡介绍(hometown.jsp)本页面是本网站的家乡介绍页面,除了导航栏之外为静态网页,大部分内容摘自乌镇导游网。本页面源代码较长且为静态网页,这里省略
    效果示意图:

    4.8 留言板4.8.1 留言板(board.jsp/getboard.tag)本页面是网站的留言板网页,每次打开页面都会调用getboard.tag,从数据库中查询所有的留言内容(SELECT * FROM user_data.board order BY date DESC;),并且按照时间倒序排序,排在最上面的为最新留言。
    第一个白框是留言的模块,第二个白框是搜索模块(search.jsp)和我的留言的链接(myboard.jsp)。
    效果示意图:

    board.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="getboard" %><!DOCTYPE html><html><head> <title>留言板</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg4.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"><getboard:getboard></getboard:getboard> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <%String username = (String)session.getAttribute("username");if (username != null){out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  ");}else{out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  ");} %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>");} %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><div class = white_box> <form action="checkboard.jsp" method="post"> <textarea rows="5" cols="" name="txt"></textarea> <br><br><br> <center> <input type="submit" value=" 留 言 " style="font-size:20px;" > </center> </form></div><div class = white_box> <form action="search.jsp" method="post"> <center> <input type="text" value=" 留 言 搜 索 " style="font-size:20px; display: inline;" onfocus="if(this.value == ' 留 言 搜 索 ') this.value =''" name="src"> <input type="submit" value=" 搜 索 " style="font-size:20px;" > <input type ="button" value=" 我的留言 " onclick="location='myboard.jsp'" style="font-size:20px;" > </center> </form></div><%=content %></body></html>
    4.8.2 搜索留言(search.jsp/searchboard.tag)搜索留言与留言栏内容相似,唯一的差别就是tag文件可以接收input框中的搜索的内容并且通过select语句查询包含查询内容的留言内容并返回内容。
    效果示意图:

    search.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="searchboard" %><!DOCTYPE html><html><head> <title>留言板</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg4.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <%String username = (String)session.getAttribute("username");if (username != null){out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  ");}else{out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  ");} %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>");} %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><% String search_message = new String(); try{ search_message = new String(request.getParameter("src").getBytes("ISO8859_1"),"utf-8"); } catch(Exception e){}%><div class = white_box> <form action="search.jsp" method="post"> <center> <input type="text" value=" 留 言 搜 索 " style="font-size:20px;display:inline;" onfocus="if(this.value == ' 留 言 搜 索 ') this.value =''" name="src"> <input type="submit" value=" 搜 索 " style="font-size:20px;" > </center> </form></div><searchboard:searchboard src="<%=search_message%>" /><%=content %></body></html>
    4.8.3 我的留言(myboard.jsp/myboard.tag/deleteboard.jsp)本页面是留言板内容中的我的留言网页,网页通过myborad.tag文件查询用户名为当前登录用户的数据库中的留言内容,并显示在网页上,并且显示删除按钮,点击就可以调取deleteboard.jsp来删除指定的留言内容。
    效果示意图:

    myboard.jsp
    <%@ page language="java" contentType="text/html; charset=utf-8"%><%@ taglib tagdir = "/WEB-INF/tags" prefix="myboard" %><!DOCTYPE html><html><head> <title>留言板</title><style> @import"home_style.css"</style></head><body style=" font-size: 16px; line-height: 1.4em; letter-spacing: 0.08em; padding: 0; margin: 0; background: url('./img/bg4.jpg') fixed center center no-repeat; background-size: cover; width: 100%;"> <div class="ace-head-inner"> <div class="ace-head-container ace-container"> <div class="ace-head-row"> <div id="ace-head-col1" class="ace-head-col text-left"> <span> <%String username = (String)session.getAttribute("username");if (username != null){out.println("您好,"+username+" <a href='logout.jsp'>退出登陆</a>  ");}else{out.println("您还未登陆 <a href='login.jsp'>点此登陆</a>  ");} %> </span> </div> <nav id="ace-main-nav"> <ul class="clear-list"> <%if (username != null){out.println("<li><a href='details.jsp'>个人信息</a></li>");} %> <li><a href="Home.jsp">主页</a></li> <li><a href="profile.jsp">作者简介</a></li> <li><a href="hometown.jsp">家乡介绍</a></li> <li><a href="board.jsp">留言板</a></li> <li><a href="about.jsp">关于</a></li> <li><a href="index.jsp">返回欢迎页</a></li> </ul> </nav> </div> </div></div><% String search_message = new String(); try{ search_message = new String(request.getParameter("src").getBytes("ISO8859_1"),"utf-8"); } catch(Exception e){}%><myboard:myboard></myboard:myboard><%=content%></body></html>
    5、总结本网站基本满足了所有需要的内容和功能需求。
    包含了个人的简介,家乡的介绍,包括个人的信息,留言板等内容。也包含了数据库的增(用户注册,留言板的留言等),删(个人留言支持删除),改(个人信息的修改等),查(留言板的查看,个人信息的查看等)四个功能。数据库的3张表,包括用户登录信息表,用户个人信息表,留言板内容表。
    6、参考文献[1]耿祥义,张跃平.JSP实用教程(第三版),清华大学出版社
    [2]刘长生,谢强,丁秋林,Java应用中的乱码问题分析[J] 计算机技术与发展,2006,25(5):77-80.
    [3]飞思科技产品研发中心。JSP应用开发详解(第二版)[M].北京:电子工业出版社,2004
    [4]萨师煊,王珊。数据库系统概论(第三版)[M].北京:高等教育出版社,2000
    [5]张红梅,王磊。在JSP中访问数据库的方法[J].农业图书情报学刊,2006,18(12):142-144
    3 评论 11 下载 2019-04-12 14:24:51 下载需要12点积分
  • 基于J2EE的新闻管理系统的设计与实现

    摘 要为了实现网上新闻的发布与管理,方便后台人员操作,提高工作效率,构建了基于Java Web技术的新闻管理系统。文中论述了新闻管理系统的开发工具,系统分析、设计、实现和测试过程。分析了系统的可行性和用户需求,给出了系统的总体设计,包括功能模块划分和数据库设计,进一步阐述了系统的详细设计与实现。经过测试,系统实现了用户身份验证,管理员可以对新闻进行添加、修改、删除、查询等操作,普通用户可以浏览和评论新闻。系统比较完善,达到了预期目标。
    关键词:新闻管理,系统分析,系统设计,系统测试
    ABSTRACTIn order to implement the release and management of news on-line, be convenient to operate for administrators and improve the efficiency, the news management system based on Java Web technology is constructed. In the paper, it elaborates the development tools of the system, the procedure of system analysis, design, implementation and test. First, the feasibility and requirement are anglicized. Next, the general design, including function module dividing and database design is given. Furthermore, the detail design and implementation are expounded. After testing, the system has realized the functions of user authentication. Administrator can add news, update news, delete news, and search news, beside the ordinary people can browse news and review news. The system is nearly perfect, and the expected goal has achieved.
    KEY WORDS: News Management, System Analysis, System Design, System Testing
    1 绪论1.1 选题的背景现在是一个科学技术飞速发展的世纪。随着计算机及网络技术的飞速发展,Internet应用在全球范围内日益普及,当前社会正快速向信息化社会前进,各个领域都向系统化、规范化、自动化的方向发展,信息自动化的作用也越来越大,使得人们的工作效率、工作成绩和生活水平都日益提高。为了满足人们各自兴趣,如阅读新闻或对时事新闻的评论,社会上有不少的各类新闻网站等为人们提供获取新闻及新闻评论的平台。新闻管理系统在信息技术的强有力的推动下,已经叩响了人类的大门。当今社会,人们深深领略到了网络新闻的迅猛发展,在已经迈入21世纪的今天,认识、了解新闻管理系统,是每个人都要认真对待的一项新任务。
    1.2 选题的意义随着Internet的兴起,网络已经成为现代人生活的一部分,人们越来越想在最短的时间内知道所发生的各种新闻。于是新闻自动化便成了人们向往的事情,本系统就是一个基于B/S模式的新闻管理系统,采用的是J2EE技术,实现了网站新闻的动态管理,使得对信息的管理更加及时、高效,提高了工作效率。一方面,它提供了一个新闻发布和管理的功能;另一方面,现在的新闻发布要求与普通的用户实现交互,这一点也是其他一些媒体(电视、电台等)现在无法做到的,以后新闻管理系统会成为人们生活中不可缺少的一部分。
    1.3 系统及开发工具简介本系统是基于Java Web技术的新闻管理系统,其主要功能是信息的发布和管理,涉及到前台用户对新闻的浏览及评论和后台管理员对用户和新闻的管理。在前台新闻浏览模块,对新闻进行分类别展示,并通过栏目导航进入特定的新闻信息分类模块。前台浏览新闻不需要用户登录注册,对所有用户均开放,但是只有注册登录的用户才能发表评论。后台管理一般只有使用了正确的管理员账号和密码才能进入后台管理新闻和用户信息。
    本系统是采用Myeclipse8.6作为开发工具,MySQL作为后台数据库的基于B/S模式的新闻管理系统。MyEclipse是功能丰富的J2EE集成开发环境,包括了完备的编码、调试、测试和发布功能。MyEclipse可以简化Web应用开发,利用它可以在数据库和J2EE的开发、发布,以及应用程序服务器的整合方面极大地提高工作效率。MySQL是一套功能强大的关系型数据库管理系统,适用于Windows平台,采用它作为新闻管理系统的数据来源,可以让用户很简便地实现所要进行的数据存取操作。
    2 系统分析2.1 系统设计原则新闻是直接与广大用户进行会面的,新闻管理系统是用户对外发布消息的门户,对用户也有非常重要的影响。在进行系统设计时要充分考虑新闻管理工作的特点,需要遵循以下几个原则[1]:
    目的要明确
    首先,要有明确的设计目标和意图,需要设计开发什么类型的系统,系统应该有哪些功能,只有这样才会构建一个良好的新闻管理系统。
    可扩展性较强
    新闻管理系统完成并投入使用以后,主、客观条件难免会发生变化,同时在使用过程中也许会发现软件系统不够完善,此外为了加强系统功能,都需要对该系统进行维护和优化,因此在系统开发过程中要预先考虑到系统可扩展性,采取一定方法,增强系统的可扩展性。
    实用性和经济性
    在新闻管理系统设计开发过程中,要在尽量降低成本的同时,满足系统实用的需要,使的系统操作更加简便,使用效率更高,灵活性更强。
    2.2 系统需求分析作为软件的开发人员,无论开发任何一种软件,设计任何一个软件系统,首先要做的第一步骤就是需求分析[2]。软件需求分析是软件生存期中重要的一步,也是决定性的一步。需求分析的基本任务是准确地回答“系统必须做什么”这个问题,深入描述软件的功能和性能需求,确定软件设计的约束和软件同其他系统元素的接口细节,定义软件的其他有效性需求[3]。
    系统的需求分析在整个系统的开发过程中有着举足轻重的作用,只有在做好系统需求分析的基础上,才能开发出好的应用系统。
    2.2.1 系统的功能需求分析在对文献研究以及对相关用户充分调研的基础上,总结出了新闻管理系统的功能需求:

    新闻管理系统首先要具有新闻管理的功能,即发布新闻、修改新闻和删除新闻
    级别不同的用户要有不同的权限:管理员不仅可以对新闻进行分类、添加、修改和删除,还可以管理普通用户;普通用户登录系统后可对新闻进行浏览和评论
    要优化新闻管理流程,提高效率,保证新闻时效性

    综上所述,可将新闻管理系统分为前台页面模块和后台管理模块两大部分进行设计与实现。
    前台页面模块主要提供浏览功能,是用户访问新闻的界面。具体功能如下:

    首页是整个新闻管理系统的第一个页面,负责从总体上对系统信息进行显示。在首页的顶部要有用户注册和登录的模块
    用户注册和登录模块的下方要有新闻分类的主题。可以将新闻分为国内、国际、军事、财经、体育、娱乐、科技、房产、汽车、社会、游戏、教育等几类。点击某个主题后,仅对应该分类的所有新闻要以列表的形式分页显示出来
    首页的左侧,要将新闻标题以列表的形式显示出来,图片新闻显示在首页的右侧
    由于新闻管理系统的数据量极大,新闻标题也会很多,所以系统对新闻标题的显示要有分页功能,每一页显示一定数量的新闻标题
    首页的底部要显示网站的服务链接,网站地图,留言反馈,常见问题解答,热线电话,举报邮箱,以及版权等相关信息
    点击新闻标题,打开一个新闻后,要在新闻内容的下方显示出评论列表。评论包括评论人、评论内容和评论时间。如果一条新闻还没有用户评论,则在新闻内容的下方显示“暂无评论”
    新闻阅读页面顶部要有返回新闻首页的链接,页面底部要有合作伙伴的友情链接
    普通用户登录新闻管理系统后,在首页的顶部要有“返回用户主页”的链接。管理员登录系统后,在首页的顶部要有“返回后台主页”的链接,方便管理员进入系统后台对新闻管理系统进行管理
    新闻管理系统要有一定的出错提示。例如用户登录时没有输密码或者密码输入错误,要有“请输入密码”或“密码错误,请重新输入”的提示;用户注册时输入的密码和确认密码不一致时也要有提示,同时,为了方便数据库的管理,对用户注册输入的用户名和密码要有长度限制,如果用户输入的信息不在此限制范围内,也要有出错提示
    系统还要用一定的确认操作提示,以防止用户在不小心的情况下对系统做出错误的操作,造成损失。例如管理员在删除用户、删除新闻和删除分类主题时,要有确认是否删除的对话框提示

    后台管理模块 主要实现新闻管理系统的管理与维护,又分为管理员管理维护系统的界面和普通用户的个人主页。具体功能如下:

    管理员登录系统后进入后台管理界面。用户管理模块实现用户信息的查看和删除。新闻管理模块实现新闻的添加、分类、编辑、删除及相关属性的设置。分类管理模块实现新闻类别的添加、修改、删除
    普通用户登录系统后进入个人主页,在个人主页可以查看个人信息,可以修改密码
    注册并登录过用户可以对新闻发表评论,未注册的用户则不能对新闻发表评论

    2.2.2 系统的性能需求分析在功能需求基础上,要提出系统的性能目标,新闻管理系统需要达到以下性能要求[4]:

    界面友好。系统各个模块的界面布局和背景要美观,不能给用户很乱的感觉
    操作简单。新闻管理系统所面向的用户众多,用户角色也各不相同,他们中有系统管理人员,有注册过的普通用户,也有以游客身份访问系统、无需登录系统的匿名用户。其文化程度各异,掌握的计算机水平也不同。因此,设计的新闻管理系统在操作上要简单易用,人机界面友好,使用户无需培训就能在较短时间内熟练使用系统,完成新闻的管理、浏览和评论等业务
    安全性高。新闻管理系统是用户对外宣传的门户,系统设计的安全性十分重要。一旦系统遭到非法入侵,破坏系统或发布不良信息,将对用户产生严重的不良影响。为此,新闻管理系统将采取用户信息加密、用户权限设计、数据库备份等措施来保证系统的安全性
    稳定性高,易维护。一般来讲,新闻管理系统运行在中心服务器上,因此新闻管理系统必须有较强的稳定性和易维护性,一旦系统出现问题,可以快速修复,恢复正常运行

    2.3 用例图用例图描述的是参与者(actor)所理解的系统功能。用例图的建立是系统开发者和用户反复讨论的结果,描述了开发者和用户对需求规格达成的共识[5]。首先,它描述了待开发系统的功能需求;其次,它把系统看做黑盒子,从参与者的角度来理解系统;第三,它驱动了需求分析之后各阶段的开发工作,不仅在开发过程中保证了系统所有功能的实现,而且被用于验证和检测所开发的系统,从而影响到开发工作的各个阶段和UML的各个模型[6]。
    用例图的主要元素是用例和参与者。该新闻管理系统的参与者主要有:管理员,注册过的用户和没有注册过的匿名用户。
    注册过的用户可以浏览新闻、评论新闻,可以查看个人信息,也可以修改自己的登录密码。
    注册过的用户在新闻首页任意点击一个新闻标题,系统就会跳转到新闻阅读界面,用户就可以查看新闻的具体内容。
    新闻内容的下方是评论列表,注册过的用户登录系统后,还可以在评论列表下方的评论框里发表对该新闻的评论。
    注册过的用户登录系统后会跳转到个人主页。
    在个人主页里,用户点击查看个人信息,就会在个人主页看到自己的用户名和密码。用户点击修改密码,在出现的文本框里输入自己的新密码,点击修改,提示修改成功,则用户的密码被成功修改。
    注册用户的用例图如图2-1所示:

    没有注册过的匿名用户只可以浏览新闻,在新闻首页点击任意一个新闻的标题,就能在阅读页面看到该新闻的具体内容和其他用户对该新闻的评论。
    匿名用户的用例图如图2-2所示:

    管理员对新闻管理系统的管理主要分为用户管理、新闻管理和主题管理。其中在用户管理模块中,管理员可以查看其他用户的信息,可以删除其他用户。在新闻管理模块中,管理员可以添加新闻、修改新闻、删除新闻和查找新闻,当然管理员也可以浏览和评论新闻。在主题管理模块中,管理员可以添加主题、修改主题和删除主题。
    管理员登录系统后会跳转到后台管理页面。
    管理员点击“用户管理”,用户的详细信息就会以表格的形式出现在用户管理页面。点击任意一条用户信息后面的“删除”,会弹出确认删除对话框,点击“确认”,就可以删除一条用户信息。
    管理员点击“添加新闻”,在添加新闻页面,从新闻分类的下拉菜单选择新闻分类的主题,输入新闻的标题、作者以及正文内容,点击“提交”,就能成功发布一条新闻。
    管理员点击“编辑新闻”,会出现新闻的标题列表,在新闻标题的后面有“修改”和“删除”两个按钮。
    点击新闻标题后的“修改”,会跳转到新闻编辑页面,管理员在新闻编辑页面可以对新闻的分类主题、标题、作者以及正文内容进行修改,修改完后点击“提交”,就能成功修改一条新闻。
    点击新闻标题后的“删除”,会弹出确认删除对话框,点击“确定”,就能成功删除一条新闻。
    管理员点击“查找新闻”,在查找框里输入要查找的新闻标题,点击“提交”,想要查找的新闻的标题就会以列表的形式出现在查找结果页面。点击新闻标题或者标题后的“修改”和“删除”,就可以对查找到的新闻进行进一步的操作。
    管理员点击“添加主题”,输入要添加的新闻分类的名称,点击“提交”,就能成功添加一个新闻分类。
    管理员点击“编辑主题”,新闻的分类主题就会以列表的形式分页显示出来,在每个主题的后面都有“修改”和“删除”两个按钮。
    点击主题名称后的“修改”,管理员在修改框里输入新的标题,点击“提交”,就能成功修改一个新闻分类。
    点击主题名称后的“删除”按钮,会弹出一个确认删除对话框,点击“确定”,就能成功删除一个新闻分类。
    管理员的用例图如图2-3所示:

    2.4 系统的可行性分析系统的可行性分析是对开发系统的可行性程度进行评价,以便对系统开发、应用进行评测,主要包括技术可行性、经济可行性、操作可行性等[7]。
    技术可行性分析
    新闻管理系统使用计算机对新闻信息进行全面管理。为了提高工作效率和工作质量,系统通过运用计算机网络技术和数据库技术,对新闻管理系统的各个阶段实现计算机管理和控制。
    考虑到系统的扩展性,本系统以Java为开发语言、MySQL作为后台数据库,进行新闻管理系统的研究与开发。Java语言是一种跨平台、适合分布式计算机环境的面向对象编程语言。它具有的特点很多,如简单易学、面向对象性、分布式、可靠性、安全性、平台无关性、高性能、多线程、动态性等。
    系统开发步骤依据软件工程的项目开发模型,结合通用的应用开发平台进行系统配置,且有很多相关的成熟系统可以参考,因此,课题开发在技术上完全可行的。
    操作可行性分析
    该系统基于B/S模式,客户端只需安装Web浏览器即可访问系统,通用简单的操作界面,具有一般计算机知识的人员都可以轻松掌握其使用方法。用户交互界面友好,简洁明了,能切实提高新闻管理系统的可操作性,几乎无需人员培训。
    经济可行性分析
    根据新闻系统的实际需求,开发本系统,不但可以提高用户的新闻管理水平,同时还可以大大提高新闻采编的效率,优化新闻流程,保证新闻的时效性。就目前这个系统,需求方并不需要花太大的代价就能保证系统的运行。服务器可以用原有的Tomcat6,至于数据库,需求方只需在服务器上安装MySQL5.5.15就可以了,运行维护过程中也不要花费很多人力和物力,只要有管理员和一般维护性人员即可,所以在经济方面也是可行的。
    3 系统总体设计3.1 系统体系结构设计新闻管理系统是典型的管理信息系统。管理信息系统的结构设计是系统设计中的一项重要工作,系统结构设计的好坏,直接影响着系统的效率、安全性、可维护性。管理信息系统常用的体系结构有:文件服务器模式(File/Server)、C/S模式(Client/Server,客户机/服务器)和B/S模式(Browser/Server,Web浏览器/服务器)[8]。
    新闻管理系统需要向外发布信息,用户众多,并且数据库信息的更新和维护涉及到地域和即时性的制约,系统的实现一般采用B/S结构,操作方便快捷,而且对服务器端数据库的访问量较小[9]。 B/S结构用通用浏览器就实现了原来需要复杂专用软件才能实现的强大功能,简单易用,节约了开发成本,减轻了系统维护和升级的成本。可以说B/S结构,是当今Web应用软件的首选体系结构[10]。
    采用B/S结构的新闻管理系统可以轻松地发布新闻信息,而用户也无须安装专门的客户端软件,直接使用浏览器就可以查看新闻。
    未注册的普通用户可浏览新闻信息;注册用户可浏览新闻、发表评论等;系统管理员完成新闻管理、用户管理、系统维护等。
    3.2 系统功能模块新闻管理系统具有多个模块。该系统的用户分为三种:未注册的匿名用户,注册过的普通用户和管理员。
    所有用户都能浏览新闻。
    注册过的普通用户登录系统后可以查看自己的个人信息,可以对新闻进行评论,修改自己的密码。管理员登录后可以管理新闻、主题和用户,实现信息的添加、修改和删除。其中用户管理分为查看用户信息、删除用户;新闻管理分为添加新闻、查找新闻、编辑新闻和删除新闻;主题管理分为添加主题、修改主题和删除主题。
    系统功能模块如图3-1所示。

    3.3 数据库设计新闻管理系统的大量新闻信息保存在数据库中,同时新闻管理系统的用户相关信息也保存在数据库中。由于新闻管理系统处理的新闻信息数据更新较快,随着新闻管理系统使用时间的增长,数据日积月累,必将产生海量数据。同时在功能上考虑到数据处理速度、数据处理能力、性能稳定性、安全可靠性等,需要合理设计数据库系统。由于大量的信息被组织在数据库中,数据库的设计将影响整个管理系统的性能,数据库设计是系统设计中的一个重点。
    数据库作为新闻管理系统的基础,首先要保证其设计的合理性。在使用应用系统时,拥有设计合理的数据库往往可以起到事半功倍的效果。数据库设计是针对给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够高效地存储数据,满足系统用户的应用需求[11]。目前通用的数据库设计开发流程,主要分以下几个阶段:需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施、数据库运行和维护[12]。设计一个完善的数据库应用系统是不可能一蹴而就的,它往往是上述六个阶段的不断重复。
    本新闻管理系统一共用到四个表:评论信息表(comments),新闻信息表(news),用户信息表(news_users),分类信息表(topic)。这四个表的设计分别如下:
    评论信息表(comments)



    字段名称
    字段类型
    字段长度
    字段说明




    CID
    int
    11
    评论编号


    CNID
    int
    11
    评论所对应的新闻编号


    CCONTENT
    varchar
    3000
    评论内容


    CDATE
    datetime
    0
    评论日期


    CAUTHOR
    varchar
    100
    发表评论的用户



    新闻信息表(news)



    字段名称
    字段类型
    字段长度
    字段说明




    NID
    int
    11
    新闻编号


    NTID
    int
    11
    所属分类号


    NTITLE
    varchar
    200
    新闻标题


    NAUTHOR
    varchar
    50
    作者


    NCREATEDATE
    datetime
    0
    发布时间


    NCONTENT
    mediumtext
    0
    新闻内容



    用户信息表(news_users)



    字段名称
    字段类型
    字段长度
    字段说明




    USID
    int
    11
    用户编号


    UNAME
    varchar
    20
    用户名


    UPWD
    varchar
    20
    用户密码



    分类信息表(topic)



    字段名称
    字段类型
    字段长度
    字段说明




    TID
    int
    11
    主题编号


    TNAME
    varchar
    50
    主题名



    3.4 实体关系图实体关系图,简记E-R图,是指以实体、关系、属性三个基本概念概括数据的基本结构,从而描述静态数据结构的概念模式[13]。
    本新闻管理系统有四个实体,分别为用户、主题、新闻和评论。

    用户的属性:登录名,密码
    新闻的属性:主题,标题,作者,发布时间,内容。
    评论的属性:用户,内容,发表时间
    **主题只有主题名一个属性

    其中用户分为管理员和普通用户。管理员可以管理主题、新闻以及普通用户。所有用户都可以发表新闻评论。
    各实体之间的关系如图3-2和图3-3所示:


    3.5 过程设计概要设计的任务完成后,就进入详细设计阶段,也就是过程设计阶段。在这个阶段要解决新闻管理系统各个模块的实现算法,并使用过程描述工具(程序流程图、N-S图、PAD图、决策树等)精确地描述这些算法。对于比较简单的算法,可以采用自然语言来描述。但是对于此新闻管理系统,有一些算法比较复杂,使用自然语言描述就不太合适。一方面自然语言在语法上和语义上往往具有歧义性,常常要依赖上下文才能把问题描述清楚;另一方面,自然语言本身具有顺序性,不适合描述具有很多分支和循环的算法[14]。
    因此本新闻管理系统使用程序流程图来描述一些比较复杂的算法。
    用户注册的流程为:在新闻首页点击“注册”,输入用户名和密码,如果密码长度少于6位,则会提示“密码长度为6-255”,重新输入符合标准的密码后,输入“确认密码”,确认密码要和密码一致,否则会提示“密码不正确,请重新输入”。最后点击“注册”,跳转到注册成功页面,提示“注册成功”。
    用户注册流程图如图3-4所示:

    用户登录的流程为:用户输入登录名和密码,点击登录,如果是管理员账户,则跳转到后台管理页面;如果是注册过的普通用户,则跳转到普通用户的个人主页;如果输入的登录名和密码不是注册过的,则不能登录到系统,会提示请先注册。
    用户登录流程图如图3-5所示:

    3.6 类图模型的静态结构也称为静态模型,在UML中表示为类图。类图显示了类(及其接口)、类的内部结构以及与其他类的联系。联系是指类元之间的联系,在类的建模中可以使用关联、聚合和泛化(继承)关系[15]。
    在新闻管理系统中,涉及到的主要类有CommentsServlet,ExitServlet,LoginServlet,NewsServlet,ShowInfoServlet,TopicServlet,UserServlrt;CommentsServiceImpl,NewsServiceImpl,TopicServiceImpl,UserServiceImpl;CommentsDaoImpl,NewsDaoImpl,TopicDaoImpl,UserDaoImpl;DButil等。
    新闻管理系统的核心类图如图3-6所示。

    其中,CommentsServlet,CommentsServiceImpl,CommentsDaoImpl,这三个类是控制用户对新闻的评论的,实现的功能有用户新增评论,所有的评论以列表的形式显示出来,管理员删除评论。
    NewsServlet,NewsServiceImpl,NewsDaoImpl,这三个类是控制新闻管理的。实现的功能有浏览新闻、添加新闻、按标题查找新闻、编辑新闻、删除新闻等。
    TopicServlet,TopicServiceImpl,TopicDaoImpl,这三个类是控制主题管理的。所实现的功能有添加主题、编辑主题、删除主题等。
    UserServlrt,UserServiceImpl,UserDaoImpl,这三个类是控制用户管理的。所实现的功能有显示用户的信息,添加用户,修改用户信息,删除用户等。
    4 系统实现4.1 新闻首页用户进入本新闻管理系统后,首先看到的是新闻首页。
    首页的顶部是用户注册和登录模块,用户在本新闻管理系统注册后,输入登录名和密码即可登录本系统。
    在用户注册和登录模块的下方,是新闻管理系统的logo,“新闻中国,有态度的新闻门户”。网站logo里包含有一个超链接,用户在任意页面,只要点击网站的logo,就可以返回到新闻首页。
    网站logo的下方是一个类似于分割线功能的有色框。
    再下方是新闻分类主题的导航模块。有国内新闻、国际新闻、军事新闻、财经新闻、体育新闻、娱乐新闻、科技新闻、房产新闻、汽车新闻、社会新闻、游戏新闻、教育新闻等分类。
    新闻分类导航模块的下方是新闻浏览模块。新闻浏览模块左边是新闻列表,可以看到新闻标题列表和新闻发布时间。
    点击新闻标题,可以超链接到另一个显示新闻具体内容的阅读页面,可以查看新闻的具体内容。
    新闻浏览模块的右边,上部分是滚动的图片新闻,新闻的图片会自动切换,时间间隔是1秒。用户也可以分别点击滚动框里的四个按钮,可以查看相对应的新闻图片。
    下部分是旋转新闻,新闻标题以旋转的方式显示出来,旋转的轨迹是一个球形。把鼠标放在一个标题的上面,该标题的颜色会发生变化,突出显示出来。用户点击新闻标题就可以跳转到新闻阅读界面,查看新闻的详细内容。
    滚动新闻和旋转标题,这两部分都是用的特效。用Javascript控制图片滚动和标题旋转,用CSS控制这两部分的样式,再把Javascript和CSS引用到控制首页显示的JSP页面中,这两个特效就显示在网站的首页了。
    首页底部显示网站的一些服务的链接,包括广告服务、供稿服务、法律声明、招聘信息、网站地图、留言反馈等。还有热线电话,常见问题解答,举报邮箱,以及版权等信息。
    首页如图4-1所示。

    4.2 各类新闻浏览模块在该模块中,显示新闻的分类,新闻的标题列表,以及新闻的发布时间,还有图片新闻。
    新闻浏览模块如图4-2所示。

    4.3 用户注册点击新闻首页上方的“注册”,用户即可进入注册页面,输入用户名、密码和确认密码,点“注册”,即可完成注册。
    如果输入错误,可以点击“重置”,就会清空所有已输入的信息,重新输入用户名、密码和确认密码。
    注册页面如图4-4所示:

    注册成功后,系统会跳转到注册成功的提示页面。点击“现在登录”,返回新闻首页,即可用刚才注册的用户信息登录新闻管理系统。
    注册成功页面如图4-5所示:

    实现注册功能的关键代码如下:
    private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); String pwd = request.getParameter("pwd"); User n = new User(); n.setUname(name); n.setUpwd(pwd); boolean b = userServiceImpl.save(n); if (b) { request.getRequestDispatcher("WEB-INF/user/doregister.jsp").forward(request, response); } }
    4.4 用户登录在新闻管理系统中有三种用户:未注册的用户,注册过的用户,管理员。
    在新闻首页,管理员和注册过的用户输入登录名和密码,点击“登录”即可进入新闻管理系统。在登录前勾选“七天免登录”,系统会自动记住该用户的登录名和密码,该用户七天内即可免登录进入新闻管理系统。
    用户登录模块如图4-6所示:

    其中,管理员登录到系统后会进入后台管理页面,普通用户登录到系统后会进入个人主页。判定输入的登录名和密码是否是管理员的关键代码如下:
    if ("admin".equals(name)) { request.getSession().setAttribute("sname", name); response.sendRedirect("NewsServlet");}if (!("admin".equals(name))) { request.getSession().setAttribute("sname", name); response.sendRedirect("UserServlet");}
    4.5 管理员后台管理模块用管理员账号登录后,即可进入后台管理页面,对新闻管理系统进行管理。
    在后台管理的欢迎页面,左边是功能模块,包括用户管理、添加新闻、编辑新闻、查找新闻、添加主题、编辑主题。欢迎页面的右边有欢迎语:“欢迎来到后台管理,数据无价,谨慎操作!”
    后台管理的欢迎页面如图4-7所示:

    4.5.1 用户管理页面在后台管理页面,点击“用户管理”进入用户管理界面,可以查看到注册用户的用户信息(包括用户名和密码),点击“删除”,会弹出确认删除对话框,再点击确定,就可删除一条用户信息。
    用户管理页面如图4-8所示。

    实现删除用户信息的关键代码如下:
    private void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String usid = request.getParameter("id"); System.out.println("++++deleteUser_usid++++"+usid); Integer id=Integer.parseInt(usid); System.out.println("++++deleteUser_usid++++"+id); boolean b = userServiceImpl.deleteById(id); if (b) { request.getRequestDispatcher("UserServlet?model=show_users").forward(request, response); }}
    4.5.2 添加新闻页面在该页面中,输入新闻的各项信息:点击下拉菜单选择新闻的分类主题,输入新闻的标题、作者、内容。点击“提交”,即可成功发布一条新闻,在新闻首页可以查看到新添加的新闻。如果新闻的某项信息填写有误,点击“重置”,即可清空所有已输入信息,方便重新输入。
    添加新闻页面如图4-9所示:

    实现添加新闻功能的关键代码如下:
    private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String ntid = request.getParameter("ntid");// 获取新闻id String ntitle = request.getParameter("ntitle");// 获取新闻title String nauthor = request.getParameter("nauthor");//获取新闻的author System.out.println("---->"+nauthor); String ncontent = request.getParameter("ncontent"); News n = new News(); // request获取到的值是字符串类型,转换成integer类型的。 Integer tid = Integer.valueOf(ntid); n.setNtid(tid); n.setNtitle(ntitle); n.setNauthor(nauthor); n.setNcontent(ncontent); boolean b = newsServiceImpl.save(n); if (b) { response.sendRedirect("NewsServlet"); }}
    4.5.3 编辑新闻页面管理员进入后台管理页面后,点击编辑新闻,会显示出新闻标题列表。
    新闻标题列表如图4-10所示。

    点击新闻标题后的“修改”,就进入新闻修改页面。在修改新闻页面可以对新闻的主题、标题、作者、内容进行修改,修改完后再点击“提交”即可完成修改。或者点击“重置”,就可以清空该新闻的所有信息,再重新输入新闻的主题、标题、作者、内容等。
    点击新闻标题后的“删除”,会弹出确认删除对话框,点击“确定”即可删除一条新闻。
    新闻修改页面如图4-11所示:

    实现修改新闻功能的关键代码如下:
    private void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String nid = request.getParameter("nid"); // 获取新闻id String ntid = request.getParameter("ntid"); // 获取新闻主题id String ntitle = request.getParameter("ntitle"); // 获取新闻title String nauthor = request.getParameter("nauthor"); // 获取新闻author System.out.println("nauthor"+nauthor); String ncontent = request.getParameter("ncontent"); News news = new News(); // request获取到的值是字符串类型,转换成integer类型的。 Integer id = Integer.valueOf(nid); Integer tid = Integer.valueOf(ntid); news.setNid(id); news.setNtid(tid); news.setNtitle(ntitle); news.setNauthor(nauthor); news.setNcontent(ncontent); boolean b = newsServiceImpl.update(news); if (b) { response.sendRedirect("NewsServlet"); } else { response.sendRedirect("NewsServlet?model=update_jsp"); }}
    4.5.4 查找新闻页面新闻管理系统的查找新闻的功能是根据新闻的标题查找的。
    在后台管理页面中点击“查找新闻”,在查找新闻页面中输入要查找的新闻标题,点击“提交”,即可得到想要查找的新闻。
    查找新闻页面如图4-12所示:

    查找结果如图4-13所示:

    实现查找新闻功能的关键代码如下:
    /*** 按新闻标题检索新闻* * @param request* @param response*/private void search(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String ntitle = request.getParameter("ntitle"); System.out.println("++++++++"+ntitle); List<News> lst = newsServiceImpl.findNews(ntitle); System.out.println("++++++++"+lst); request.setAttribute("lst", lst); request.getRequestDispatcher("WEB-INF/news/newList01.jsp").forward(request, response);}
    4.5.5 添加主题页面在该页面输入要添加的新闻分类名称,点击“提交”,即可添加一个新闻分类。在新闻首页就可以看到新添加的分类。同时,在“添加新闻”页面的新闻主题下拉菜单中也会增加新添加的新闻主题。
    添加主题页面如图4-14所示:

    4.5.6 编辑主题页面点击主题后的“修改”,就进入主题修改页面,在修改主题页面可以对主题进行修改,再点击“提交”即可完成修改。点击主题后的“删除”,会弹出确认删除对话框,点击“确定”即可删除一个新闻分类,否则点击“取消”。
    主题列表如图4-15所示:

    修改主题页面如图4-16所示:

    4.6 普通用户功能模块普通用户登录新闻管理系统后会进入个人主页的欢迎页面。
    欢迎页面的左边是功能模块,包括查看个人信息和修改密码。欢迎页面的右边是欢迎语:欢迎来到个人主页。
    欢迎页面如图4-17所示:

    4.6.1 查看个人信息普通用户登录系统后,点击“查看个人信息”,可查看该用户的登录名和密码。
    查看个人信息的页面如图4-18所示:

    实现查看个人信息功能的关键代码如下:
    private void show_users(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub List<User> lst=userServiceImpl.findAll(); request.setAttribute("lst", lst); request.getRequestDispatcher("WEB-INF/admin/userList.jsp").forward(request, response);}
    4.6.2 修改密码普通用户进入个人主页后点击“修改密码”,输入新密码,点击“修改”,即可修改该用户的密码。如果点击“取消”则会清空已输入的新密码。
    修改密码的页面如图4-19所示:

    实现修改密码功能的关键代码如下:
    private void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uname=request.getParameter("uname"); String upwd = request.getParameter("password"); User user=new User(); user.setUname(uname); user.setUpwd(upwd); boolean b=userServiceImpl.update(user); if(b){ request.getRequestDispatcher("WEB-INF/user/success.jsp").forward(request, response); }else{ response.sendRedirect("UserServlet?model=update_jsp"); }}
    4.6.3 评论新闻普通用户登录新闻管理系统后,可以点击新闻标题浏览新闻,也可以在新闻内容的下方进行评论。用户在评论框里输入评论后,点击“发表”,即可发表评论。评论列表里会显示出发表评论的用户名、评论日期和评论内容。
    评论列表如图4-20所示:

    没有注册过的用户则只可以浏览新闻,不能对新闻进行评论。匿名用户在评论框里输入评论,点击提交时,会提示“您还没登陆,请先登录”。
    评论失败的提示如图4-21所示:

    实现评论功能的关键代码如下:
    public class CommentsServlet extends HttpServlet { private static final long serialVersionUID = 1L; public CommentsServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String nid=request.getParameter("cnid"); Integer cnid=Integer.parseInt(nid); String cauthor=request.getParameter("cauthor"); String ccontent=request.getParameter("ccontent"); //添加日期的格式 Timestamp cdate=new Timestamp(System.currentTimeMillis()+8*60*60*1000); String cip=request.getRemoteAddr(); Comments comments =new Comments(cnid,ccontent,cdate,cip,cauthor); CommentsServiceImpl commentsServiceImpl=new CommentsServiceImpl(); boolean b=commentsServiceImpl.save(comments); if(b){ response.sendRedirect("NewsServlet?model=read&nid="+cnid); } }}
    5 系统的测试与评价5.1 系统测试系统测试采用黑盒测试法(Black-box Testing),黑盒测试方法,也称功能测试或数据驱动测试方法,在测试时,把程序看做一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,测试人员针对软件直接进行测试[16]。
    首先运行整个程序进入到网站首页,在网站首页显示出用户登录、新闻分类、新闻标题、新闻图片等模块,达到了预期效果。
    首页中的各项均是用超链接实现的,依次点击相应的功能按键和超链接,查看功能是否能够按照设计时的构想实现,例如,在点击“注册”,出现用户注册界面,填写用户的登录名、密码和确认密码,再点击“注册”,进入注册成功页面等等。依照此思想逐个点击各项功能和超链接,检查是否实现该功能。



    测试项目
    功能描述
    操作步骤/输入数据
    预期结果
    测试结果




    新闻浏览
    查看新闻的具体内容
    进入主界面,点击新闻标题
    跳转到新闻阅读页面,能看到新闻的详细内容。
    成功


    新闻分类
    将新闻按照分类分页显示
    点击新闻主题
    新闻按照对应的分类分页显示
    成功


    未注册的用户的权限:不能评论新闻
    对新闻进行评论
    进入新闻管理系统后不登录,直接点击一条新闻标题,在新闻内容的下方输入评论,然后点击“发表”
    评论不成功,提示“您还没登陆,请先登陆”。
    成功


    用户注册
    注册一个新用户
    进入主界面,点击注册,输入登录名:aaa,密码:aaaaaa,确认密码:aaaaaa,提交表单后跳转到注册成功页面。
    成功注册一个新用户
    成功


    普通用户登录
    普通用户登录系统
    进入主界面,登录名输入“aaa”,密码输入“aaaaaa”,点击登录。
    登录成功,跳转到个人主页,返回新闻首页后在左上角显示用户名。
    成功


    管理员登录
    管理员登录系统
    进入主界面,登录名输入“admin”,密码输入“admin”,点击登录。
    登录成功,跳转到后台管理页面,返回新闻首页后在左上角显示管理员名称。
    成功


    查看个人信息
    查看已登录用户的个人信息
    进入主界面,登录名输入“aaa”,密码输入“aaaaaa”,点击登录,跳转到个人主页后点击“查看个人信息”。
    能看到个人信息:登录名为aaa,密码为aaaaaa。
    成功


    修改密码
    修改登录密码
    进入主界面,登录名输入“aaa”,密码输入“aaaaaa”,点击登录,跳转到个人主页后点击“修改密码”,输入新密码并点击“修改”。提示密码修改成功后退出当前用户,用新密码重新登录。
    提示密码修改成功,用新密码重新登录后能正常登录。
    成功


    评论新闻
    对新闻进行评论
    用用户aaa登录系统,点击新闻标题,跳转到新闻阅读页面后在新闻内容下方写评论,并点击“发表”。
    评论发表成功,在评论列表里能看到发表的评论。
    成功


    查看用户信息
    查看注册用户的登录名和密码
    用管理员身份登录系统后选择“用户管理”。
    能查看到注册用户的登录名和密码。
    成功


    删除用户
    删除一个注册过的用户
    用管理员身份登录系统后选择用户管理,点击想要删除的用户信息后的“删除”,在弹出的确认删除对话框里点“确定”。然后退出管理员,用刚删除的那个用户的登录名和密码登陆系统。
    成功删除一条用户信息,退出管理员后,用刚删除的用户的信息登录系统,提示请先注册。
    成功


    添加新闻
    向系统里添加一条新闻
    用管理员身份登录系统后选择“添加新闻”,填写新闻的主题、标题、作者、内容,点击“提交”。返回新闻首页,点击新添加的新闻所属的主题,看新闻列表里是否有刚才添加的新闻的标题。
    成功添加一条新闻,在新闻首页的新闻列表里能看到新添加的新闻。
    成功


    编辑新闻
    修改已经发布过的新闻
    用管理员身份登录系统后选择“编辑新闻”,点击新闻标题后面的“修改”,进入到新闻修改页面,修改新闻的主题、标题、作者、内容,点击“提交”。
    成功修改一条新闻。
    成功


    查找新闻
    根据新闻标题查找想要的新闻
    用管理员身份登录系统后选择“查找新闻”,进入新闻查找页面后输入新闻标题,点击“提交”。
    在一个新页面显示出要查找的新闻的标题。
    成功


    删除新闻
    删除过时的新闻
    用管理员身份登录系统,在后台管理页面,点击新闻标题后面的“删除”,再点击弹出的确认删除对话框里的“确定”。返回新闻首页,点击新添加的新闻所属的主题,看新闻列表里是否有刚才添加的新闻的标题。
    成功删除一条新闻,在新闻首页的新闻列表里也看不到删除的那条新闻的标题。
    成功


    添加主题
    添加一个新闻分类
    用管理员身份登录系统后选择“添加主题”,输入主题名称,点击“提交”。
    返回新闻首页后可以看到新添加的新闻分类,添加新闻时主题的下拉菜单里也有新添加的主题。
    成功


    编辑主题
    修改已有的主题
    用管理员身份登录系统后选择“编辑主题”,点击主题后面的“修改”,进入到主题修改页面,输入新的主题名,点击“提交”。
    返回新闻首页后可以看到修改后的新闻分类。
    成功


    删除主题
    删除一个新闻分类
    用管理员身份登录系统后选择“编辑主题”,点击主题后面的“删除”,再点击弹出的确认删除对话框里的“确定”。
    返回新闻首页后可以看到被删除的新闻分类不再显示,添加新闻时主题的下拉菜单里也看不到新添加的主题。
    成功


    分页功能
    让新闻分页显示
    依次点击新闻列表右下角的“下一页”、“上一页”、“末页”、“首页”。
    分页功能正常实现,在不同的页面能看到不同的新闻标题。
    成功



    经过不断的“测试——修改——测试”的往复,该系统已经达到设计要求,各项功能都得到了完美的实现,达到了预期的效果。
    5.2 系统的评价通过以上各步工作,该新闻管理系统基本符合要求,在这里对本系统做一个简单的评价。
    本系统在设计开发时采用后台的方法,整个系统具有以下几个特点:
    安全性和可移植性较好
    可以在任何Windows系统平台上运行。系统根据其权限做相应的处理,保护数据安全,方便管理员维护数据。
    容错性能较好
    在系统测试阶段对系统进行过大量的实例测试,并有许多出错提示,加强了系统的稳定与容错性。
    结束语课题结合新闻管理工作的实际需求,在B/S架构中,以数据库技术和Java语言作为主要工具,最终完成了新闻管理系统。其功能基本符合新闻管理的需求,并提供部分系统维护功能,使用户方便进行新闻浏览和管理员对数据进行添加、修改和删除。
    通过对新闻管理系统的设计和实现,使我对新闻工作有了更全面的理解,同时也将学习到的软件工程的相关知识运用到实践中,学习并运用Java编程语言基本完成了既定设计任务。虽然设计和开发的系统在用户界面人性化设计、操作便捷性、功能完善性和系统运行稳定性等方面还存在一定不足,但已基本达成预期目标。在课题研发和开发工作中所学习到的分析问题和解决问题的方法,对自己以后的学习和工作将大有裨益。
    通过做这个系统,我知道,有些东西细节决定成败,无论怎样都不能忽视细节的东西。这不是毕业设计的结束,更不是人生在学习生涯中的结束,而是新环境、新学习、新挑战的开始。只有这样我们才能学无止境,以求得更大的发展。对于我们年轻人来说,我相信:挑战越多,机会越多。我会打足精神,努力开创新的成绩,勇敢的面对以后发生的一切,更好的提高自己,以便能够更好为社会服务,为人民服务,进而体现自己在社会发展中的价值。
    参考文献[1] 史济民,顾春华,郑红.软件工程:原理、方法与应用[M].3版.北京:高等教育出版社,2009,298.
    [2] Shari Lawrence Pfleeger.Software Engineering Theory and Practice [M].2nd ed.影印版.北京:高等教育出版社,2001,57.
    [3] 郑人杰,马素霞,殷人昆.软件工程概论[M].北京:机械工业出版社,2009,38.
    [4] 吴洁明.软件工程实例教程[M].北京:清华大学出版社,2010,40-42.
    [5] Roger Pressman.Software Engineering:A Practitioner’s Approach [M].6th ed.影印版.北京:清华大学出版社,2005,207.
    [6] Stephen R Schach.面向对象与传统软件工程:统一过程的理论和实践[M].韩松,等译.6版.北京:机械工业出版社,2006,180.
    [7] 张海潘.软件工程导论[M].北京:清华大学出版社,2004.
    [8] 马军.JAVA完全自学手册[M].北京:机械工业出版社,2007,186.
    [9] 明日科技.Java Web从入门到精通[M].北京:清华大学出版社,2012,97.
    [10] Jon Duckett.Web编程入门经典[M].杜静,敖福江译.北京:清华大学出版社,2010,109.
    [11] 姚卿达.数据库设计[M].北京:高等教育出版社,1989,186.
    [12] 王珊,萨师煊.数据库系统概论[M].4版.北京:高等教育出版社,2006,202-203.
    [13] 百度百科—实体关系图:http://baike.baidu.com/link?url=FjXNUBVZNYUiuwf1aTOURJE3QIwcPe7_61Vi5Gnb85NIo2pmORpoIH_lTez6M-Yt#3
    [14] 齐治昌,谭庆平,宁洪.软件工程[M].3版.北京:高等教育出版社,2012,165.
    [15] 郑人杰,殷人昆,陶永磊.实用软件工程[M].3版.北京:清华大学出版社,2010,171.
    [16] 朱少民.软件测试方法和技术[M].2版.北京:清华大学出版社,2010,38.
    2 评论 8 下载 2019-05-20 22:08:31 下载需要15点积分
  • 基于Java和Mysql的学生成绩管理系统

    一、相关技术介绍
    开发环境:Windows 10
    数据库管理系统:Mysql
    开发工具:Intel IDEA
    运行环境:Windows 10以及更高版本
    系统结构:C/S

    二、系统需求分析2.1 业务流程用户登陆到系统后,在本系统中可以选择进行考试成绩录入、补考成绩录入、重修成绩录入,或查看总评成绩单、补考通知单、补考成绩单、重修通知单、重修成绩单、优秀学生名单等…
    2.2 功能需求
    用户能够登入本系统
    用户可以在系统中录入考试成绩
    用户可以在系统中录入补考成绩
    用户可以在系统中录入重修成绩
    用户可以在系统中查看总评成绩单
    用户可以在系统中查看补考通知单
    用户可以在系统中查看补考成绩单
    用户可以在系统中查看重修通知单
    用户可以在系统中查看重修成绩单
    用户可以在系统中查看优秀学生名单

    2.3 信息需求
    进行成绩录入时不允许存在列值为空
    进行成绩录入时需保证学生学号、姓名、选课的一致性

    2.4 安全性与完整性需求数据库上信息的安全性由数据库管理系统进行保证,完整性则主要由编程语句来体现。
    2.5 数据字典


    数据项名称
    别名
    类型
    含义说明




    学号
    s_no
    Char(8)
    学生的唯一标识


    姓名
    s_name
    Char(8)
    学生的姓名


    性别
    s_sex
    Char(2)
    学生的性别


    班级
    s_class
    Char(8)
    学生的专业


    专业
    s_spec
    Char(8)
    学生的专业


    课程号
    c_no
    Char(8)
    课程的唯一标识


    课程名
    c_name
    Char(8)
    课程的名字


    课程学分
    c_point
    Smallint
    课程的学分


    上课时间
    c_time
    Smallint
    上课时间


    平时成绩
    ord_score
    Int
    学生某课程的平时成绩


    考试成绩
    exam_score
    Int
    学生某课程的考试成绩


    补考成绩
    makeup_score
    Int
    学生某课程的补考成绩


    重修成绩
    renovate_score
    Int
    学生某课程的重修成绩


    总评成绩
    final_score
    Int
    学生某课程的总评成绩



    2.6 系统结构
    各模块功能说明:

    系统登录:该系统使用时需登录
    成绩录入:用于录入各类成绩
    考试成绩录入:用于登录入考试成绩及平时成绩
    补考成绩录入:用于录入补考成绩
    重修成绩录入:用于录入重修成绩
    信息查询:用于查询各种信息
    总评成绩:用于输出总评成绩。其中:总评成绩=30%*平时成绩+70*考试成绩
    补考通知单:用于输出补考名单,即总评成绩不到60分的学生
    补考成绩单:用于输出补考学生的成绩
    重修通知单:用于输出重修名单,及总评成绩 < 60且补考成绩也 < 60的学生
    重修成绩单:用于输出重修学生的成绩
    优秀学生名单:用于输出优秀学生。及该学生每科总评成绩均大于60
    退出系统:退出系统

    三、概念模型设计E-R图

    四、逻辑结构设计学生信息表(学号,姓名,性别,班级,专业)


    主键:学号
    外键:无
    非空:学号、姓名

    选课表(学号,课程号,课程名)


    主键:无
    外键:学号、课程号
    非空:学号、课程号

    课程表(课程号,课程名,课程学分,上课时间)


    主键:课程号
    外键:无
    非空:课程号,课程名

    成绩表(学号,课程号,课程名,平时成绩,考试成绩,补考成绩,重修成绩,总评成绩)


    主键:无
    外键:学号、课程号
    非空:无

    五、物理结构设计建立数据库表
    下面使用Mysql可视化工具Navicate进行建库、建表操作。

    六、数据库连接与应用6.1 Java中通过JDBC连接数据库关键代码如下:
    static { try { if (conn == null) { Class.forName(driver).newInstance(); conn = DriverManager.getConnection(dbUrl, dbUser, dbPwd); } } catch (ClassNotFoundException e) { e.printStackTrace(); JOptionPane.showMessageDialog(null, "数据库连接异常!"); System.exit(0); } catch (Exception e) { e.printStackTrace(); }}
    6.2 数据库的运行与维护登录界面

    主界面

    选择界面

    信息查询界面

    查询的SQL语句如下:
    String sql = "select student.s_no,student.s_name,score.c_name " + "from student,score " + "where student.s_no=score.s_no and score.final_score<60";
    考试成绩录入

    录入的SQL语句如下:
    String sql = "Insert " + "into score(s_no, c_no, c_name, ord_score, exam_score, final_score) " + "values(?, ?, ?, ?, ?, ?)";
    七、收获与体会通过本次的数据库课程设计,我进一步的了解了数据库的开发和使用,与看课本学习不同的是,这次是动手实践去做,而不仅仅局限于课本上的理论知识,更加进一步加深了对数据库的理解,同时也对Java语法、JDBC使用更加熟练。
    1 评论 18 下载 2019-06-16 12:47:56 下载需要13点积分
  • 基于JAVA和SQL SERVER实现的图书信息管理系统

    1 前言该系统为图书馆书记管理系统,为高校、企业的相关书籍管理工作提供了一个方便的电子平台。该系统分为两个部分,即客户端及服务器,系统功能模块分为图书管理模块、图书信息查询模块、读者信息管理模块、借阅信息管理模块等。该系统是一套功能比较完善的图书数据管理软件,具有数据操作方便高效迅速等优点。
    该系统使用SQL Server2014、Visual Studio开发工具进行开发,可以运行于目前主流的Windows平台上,具有良好的可移植性和可操作性。
    2 数据库设计2.1 需求分析目前市场主流的图书管理系统有ALEPH500、北邮Melinets、深圳ILAS等,但是缺少一个通用的、集成的系统。根据市场这一需求,该项目开发一款可移植的、易操作的通用集成图书管理系统。
    在该系统中,管理员要为每一个读者建立一个借阅账户,用于存储读者的各种信息。读者通过已经建立的借阅账户,获得借阅图书并登记以及查询相关信息的权限,从而达到信息化管理的目的。
    借阅图书时,先登记读者的相关信息,并将借阅日期等信息登记在数据库中,供管理员进行核对。另外,读者根据相关的图书编号能够查询图书的相关信息,可以根据相关的信息进行借阅或者预约登记等操作。如果有超期或者图书损坏等情况,管理员可以进行相应的登记以供日后查询。
    归还图书时,输入相关读者的编号或者图书号即可进行图书的归还登记。另外管理员可就此次还书情况进行备注,记录相应的情况。
    图书管理员可以定期或者不定期地对图书信息进行入库、删除、修改等操作,相关标号的规定根据国家标准制定。
    为系统维护人员提供权限管理、数据备份等通用功能。
    2.2 数据流图数据流图如下所示(由于系统维护为通用功能,此处不做具体分析):

    2.3 数据词典相关数据项如下所示:

    2.4 数据库概念结构及相应Power Designer概念模型相关E-R图如以下power designer模型所示

    2.5 数据库逻辑结构及相应Power Designer物理模型
    2.6 数据库物理设计相应SQL语句包括生成创建数据库的脚本,包括数据库结构定义 ,建立索引、视图语句,存储过程(如果使用)的结构和定义,主要的查询语句等。
    相关SQL语句如下所示:
    create database Libraryuse Librarycreate table admin( ad_id int not null primary key, ad_password nvarchar(20) not null, ad_name nvarchar(20) )use Librarycreate table bookuser( user_id int not null primary key, user_name nvarchar(20), user_password nvarchar(20) not null, user_cardno nvarchar(8) not null )use Librarycreate table bookcard( card_no nvarchar(10) not null primary key, card_userno int not null)use Librarycreate table borrowmessage( card_no nvarchar(10) not null primary key, book_no nvarchar(10) not null, book_name nvarchar(20), borrow_date date, return_date date)use Librarycreate table bookmessage( book_no nvarchar(10) not null primary key, book_author nvarchar(10), book_price money, book_typecode int, book_amount int)select * from admin where ad_id = ? and ad_password = ?insert into admin (ad_id, ad_password) values (" + i + "," + password + ")select * from bookmessageselect * from bookuseronedelete from bookuserone where user_id = " + user_id + ""select * from bookcard"insert into bookmessage (book_no, book_author, book_price, book_typecode, book_amount, book_name) values (" + "'"+bookno+"'" +"," + "'"+bookauthor+"'" + "," + "'"+bookprice+"'" + "," + code + "," + amount + "," + "'"+bookname +"'"+")";select * from borrowmessageuse master backup database Library to disk = 'F:\\database_backup\\Library.bakuse master restore database Library from disk = 'F:\\database_backup\\Library.bak' with replacedelete from bookmessage where book_no = '" + book_id + "'"update bookmessage set book_author = '" + update_mes + "' where book_no = '" +update_id +"'"update bookmessage set book_price = '" + update_mes + "' where book_no = '" +update_id +"'"update bookmessage set book_typecode = " + update_mes + " where book_no = '" +update_id +"'"update bookmessage set book_amount = " + update_mes + " where book_no = '" +update_id +"'"update bookmessage set book_name = '" + update_mes + "' where book_no = '" +update_id +"'"select * from bookmessageselect * from borrowmessage where card_no = '" + borrow_id + "'"select book_amount from bookmessage where book_no = '" + borrow_book_id +"'"select * from bookmessage where book_no = '" + borrow_book_id + "'update bookmessage set book_amount = " + book_final_account + "where book_no = '" + borrow_book_id + "'";insert into borrowmessage(card_no, book_no, book_name, borrow_date) values ('" + borrowercard_id + "','" + borrow_book_id +"','" + book_name +"', getdate())"select * from bookmessage where book_no = '" + return_book_id + "'update bookmessage set book_amount = " + bookcount + "where book_no = '" + return_book_id + "'""update borrowmessage set return_date = getdate() where card_no = '" + returnercard_id + "' and book_no = '" + return_book_id + "'"select * from bookuserone where user_id = " + user_login_id"insert into bookuserone (user_id, user_password) values(" + user_logon_id + ", '" + user_logon_password + "')update bookuserone set user_cardno = '" + cardid + "' where user_id = " + useridinsert into bookcard(card_no, card_userno) values ('" + cardid +"'," + userid +")"
    3 系统功能3.1 程序的运行环境
    Windows 10
    JAVA SE 1.8
    SQL Server 2015

    3.2 系统功能模块图系统功能模块图如下所示:

    3.3 主要功能描述本系统能够执行的功能有一下几点:

    管理员注册、登陆
    管理员查询借阅、图书、借书卡、注册用户信息
    图书入库
    图书信息修改
    数据库备份、恢复
    普通用户注册、登陆
    普通用户查询图书信息
    普通用户注册借书卡并登录
    持有借书卡用户查询自己的借阅信息及图书信息
    持有借书卡用户借书、还书

    3.5 主要运行界面的截图运行界面截图如下:















    4 程序调试情况
    系统未能正确进行数据库连接,更改相关连接情况即可解决
    系统不能正确处理查询请求,修改相关数据库定义即可
    系统不能正确显示查询的结果集,使用JTable解决相关问题

    5 系统的安装使用说明
    为确保系统安装,需安装JAVA SDK 1.8并正确配置
    机器需在本地安装SQL Server2015并存有数据库文件
    打开相关JAVA文件即可进行安装、使用

    6 系统总结本系统具有操作简便、界面整洁、对用户操作友好等特点,易于上手且学习门槛低,而且运行所需资源相对较少,可以流畅运行。
    该系统还存在一些问题,例如相关信息显示界面存在问题,而且查询功能方面还不是很完善,有待改进。
    改进意见有:修复相关显示界面的bug,增加更加精确的查询功能,界面优化。
    7 课程设计总结通过做本次课程设计,让我更加深入的了解了数据库相关技术及其应用,提高了个人的编码水平和解决问题的能力。同时,通过这次课程设计,让我了解到更深入的数据库技术,同时学习到了将数据库技术和其他编程语言结合在一起的相关技术,并且在解决相关bug的时候通过不断地学习走出了一些认识误区,并且将以前学习的知识更加的深入化、细致化。
    本次课程设计让我受益匪浅,收获成果远比单单看书要来得更多。
    8 参考文献[1] 柳玲、徐玲、王成良编著,数据库原理与设计实验及课程设计教程,重庆大学出版社,2016.5
    [2] 王成良、柳玲、徐玲,数据库技术与应用,清华大学出版社,2011.11
    [3] Patrick O’ Neil, Elizabeth O’ Neil. Database: Principles, Programming and Performance, 2nd ed. (数据库——原理、编程与性能). Morgan Kaufmann Publishers. 2000 (北京:高等教育出版社.2001,5)
    2 评论 85 下载 2018-11-06 16:38:21
显示 45 到 60 ,共 15 条
eject