欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

[项目摘要] 发电厂安全培训管理系统摘要 MySql 授权和权限撤销操作 http://www.cnblogs.com/qlqwjy/p/8022575.html 在 windows 下注册 tomcat 服务并设置 jvm 参数

最编程 2024-04-04 20:23:08
...

第一个项目开发也有将近半年了,这也是自己的第一个比较成熟的系统,项目从刚开始的8个人到最后的三个人,开发团队的人也越来越少,系统也越来越成熟。中间开发也遇到了大量的问题,尤其在开发考试与试卷管理,由于界面交互太复杂一个JS可以上千行。17年11月中旬系统的第一次上线,我带着服务器到机房给客户安装部署好之后,客户的需求发生了很大的变化,直到18年元旦之后,系统才算正式开发完成,中间在客户的地方开发了将近20天,每天与客户沟通完需求之后进行开发,同时也要不停的修改别的代码,也真正理解到清晰的思路与清晰的代码的重要性,指不定哪天别人会修改你的代码,所以最好是将代码写的清除点,乱七八糟的代码容易暴露自己的实力。项目也逐渐成熟,直到项目后期才真正使用上git,刚开始人多只是不停的写代码,写完之后手动合并代码浪费了大量的时间。到客户的地方开发才使用上git,也理解了git的强大。

项目也学会了POI导出exceliText导出pdfjacob将word转为pdffreemarker导出带格式的word以及利用jsoup在后台解析html标签windows远程桌面访问Teamview远程桌面访问。也学会了自己封装一些常用的工具类。

 

 

一、项目描述

开发环境:Eclipse+Jdk1.7+Git+Spring3.2+struts2.3+mybatis3.2+shiro1.3+mysql 5.7

前台技术:bootstrap+Easuui的分页插件+zTree树插件+jedate日期插件+kindeditor文本编辑器插件+其他

硬件:研腾身份证识别仪、南昊判卷机、指纹识别仪、人脸识别仪

项目描述:电厂安全培训管理系统是一个用于电厂进行培训的系统,主要是考试与成绩管理。考试可以分为在线考试与线下考试,在线考试就是登录系统之后在线考试,考完之后系统自动给出成绩,线下考试是将试卷导出成pdf进行线下考试,并用判卷机进行判卷之后将成绩导入系统。辅助的功能有部门管理与人员管理、违章管理。权限管理是系统的一大难点,采用了shiro框架,对不同的用户显示不同的菜单与显示界面上不同的按钮,也就是不同的用户可以看见不同的菜单,也可以看见不同的按钮。

菜单后台主界面:(主要模块)

二、前台总结:

前台技术:bootstrap+Easuui的分页插件+zTree树插件+jedate日期插件+kindeditor文本编辑器插件+其他

前台主要是bootstrap,分页统一用的是EasyUi的分页插件(使用参考:http://www.cnblogs.com/qlqwjy/p/7816707.html),树用的zTree插件(使用参考:http://www.cnblogs.com/qlqwjy/p/7351604.html),编辑器用的是kindeditor(使用参考:http://www.cnblogs.com/qlqwjy/p/7637386.html)。日期插件用的jeDate的日期插件。

前台学到最多的是jQuery的使用以及ajax的使用,项目中大量的使用异步请求数据,使用了jQuery封装的三种ajax:

  前台学到的主要开发思想:打开模态框之前清除之前的废旧数据,分页点击的时候带着条件去查询(将当前页与页大小存到页面的隐藏域),有时候reset按钮不能清空隐藏域,最可靠的办法就是将需要被清空的东西加个特殊的class,点击清除的时候清空所有的带class的。

 

--------------------jQuery封装的三种ajax:---------------------------------

第一种:    $.ajax

    $.ajax({
        url : contextPath + '/exam_getEmployeeIns4Exam.action',
        data : $("#queryInnerForm").serialize(),
        type : 'POST',
        dataType : 'json',
        success : showEmployeeInModal,
        error : function() {
            alert("查询内部员工出错!!!")
        }
    });

 

第二种:$.post

        $.post(baseurl + '/distribute_getUnitInfoByBigIdAndUnitId.action', {
            "unitId" : unitId,
            "bigId" : bigId
        }, function(response) {
            var unit = response.unitInfo;
            $("#unitTbody").html("");
            $("#unitTbody").append(
                    '<tr><td>' + treeNode.name + '</td><td>' + unit.manager
                            + '</td><td>' + unit.managerPhone + '</td><td>'
                            + unit.secure + '</dh><td>' + unit.securePhone
                            + '</td><td>' + unit.projectNames + '</td><td>'
                            + unit.perNum + '</td><td>' + unit.unitMinisMum
                            + '</td></tr>');
            $("#unitInfoDiv").css("display", "block");
        }, 'json')

 

 第三种:  $.get

    $.get(
            "/Ajax/ajaxServlet2",    //请求地址
            //"name=qlq&password=qlq",   //请求参数
            {"name":"qlq","password":"nicai"},  //请求传递的参数,也可以是JSON
            function(data){     //data表示传递回来的数据,只有在成功的时候才有
                alert(data);
                },
                "json"         //表示返回内容的格式,json会将传回来的自动解析成json对象
    );

 

 参考:http://www.cnblogs.com/qlqwjy/p/7357073.html

 

------------常用的jQuery的选择器=---------------------------------

参考:http://www.cnblogs.com/qlqwjy/p/7491721.html

 

三、后台总结:

 后台技术:Eclipse+Jdk1.7+Git+Spring3.2+struts2.3+mybatis3.2+shiro1.3+mysql 5.7

后台用的技术主要就是SSM框架+Shiro,项目刚开始的时候是分模块开发,也没有使用上git,都是手工的合称代码。直到项目的后期才使用上git,也真正了解到git的作用(git 的使用参考:http://www.cnblogs.com/qlqwjy/p/7577381.html)

。spring主要用到了spring的IOC和AOP,IOC主要用来管理项目的对象,AOP用在事务管理。IOC主要使用基于注解方式的配置,AOP采用XML配置。(spring事务配置参考:http://www.cnblogs.com/qlqwjy/p/7296493.html)。struts采用页面跳转与json结合的方式,struts与json结合主要是struts的package继承json-default。剩下的json转换交给struts。mybatis开发采用动态代理的方式,简单的写一下接口然后在xml中实现即可。spring与struts整合主要是将struts创建对象的一个常量配置为spring:<constant name="struts.objectFactory" value="spring"></constant>,剩下的配置spring扫描struts的包就行了,struts的配置只用写类名(第一个字母小写)。后台在Action层对异常的捕捉以及对日志的记录非常重要,在部署之后可以通过日志查看错误信息

0.dp.properties

;;;;;;;;;;;;;;;;;;;;
;DataBaseConnection;
;;;;;;;;;;;;;;;;;;;;

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/exam9
jdbc.username=root
jdbc.password=123456
jdbc.initialPoolSize=10 
jdbc.minPoolSize=5  
jdbc.maxPoolSize=30  
jdbc.maxIdleTime=200  
jdbc.maxStatementsPerConnection=50

 

 1.Spring框架的配置:

大致的配置过程:

配置数据库配置文件存放位置、将连接池放入spring容器(数据源)、配置mybatis会话工厂、配置mybatis扫描的基本包、配置事务管理器、配置事务模板对象、配置事务通知、将通知织入切面、配置扫描service与Action的包

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">

    <!-- 0.连接池属性设置读取指定的properties文件 -->
    <context:property-placeholder location="classpath:db.properties" />

    <!-- 1.将连接池放入spring容器 -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
        <property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
        <property name="maxIdleTime" value="${jdbc.maxIdleTime}"></property>
        <property name="maxStatementsPerConnection" value="${jdbc.maxStatementsPerConnection}"></property>
    </bean>



    <!--2. 配置 Mybatis的会话工厂 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 配置Mybatis的核心 配置文件所在位置 -->
        <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
    </bean>



    <!-- 3.1 mapper代理配置方法一 这种方法需要大量重复的配置代理对象 MapperFactoryBean:根绝mapper接口生成代理对象 
        <bean id="selectUser" class="org.mybatis.spring.mapper.MapperFactoryBean"> 
        <property name="mapperInterface" value="cn.qlq.core.dao.SelectUser"></property> 
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> -->




    <!-- 3.2通过MapperScannerConfigurer扫描进行批量生成代理对象 遵循规范:mapper.java和mapper.xml名字一样且在同一个目录下 
        自动扫描出来的代理对象的id为mapper类类名(首字母小写) -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 指定扫描的包名,如果有多个,用半角逗号分隔 -->
        <property name="basePackage" value="cn.xm.exam.mapper"></property>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>


    <!-- 4.配置事务管理器 -->
    <!-- 事务核心管理器,封装了事务操作,依赖于连接池 -->
    <bean name="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 5.开启注解管理aop事务 -->
    <tx:annotation-driven />



    <!-- 事务模板对象,依赖于事务核心管理器 -->
    <bean name="transactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>

    <!-- ················开始使用XML管理事务························ -->
    <!-- 配置事务通知(无论哪种方式都要用到事务的核心管理器) -->
    <tx:advice transaction-manager="transactionManager" id="firstTx">
        <tx:attributes>
            <!--以方法为单位,指定方法应用事务什么属性 isolation:隔离级别 read-only:只读属性 propagation:传播行为 -->
            <!-- 企业中运用通配符命名规则。两套增删改查(8种) -->
            <tx:method name="save*" isolation="DEFAULT" read-only="false"
                propagation="REQUIRED" />
            <tx:method name="add*" isolation="DEFAULT" read-only="false"
                propagation="REQUIRED" />
            <tx:method name="delete*" isolation="DEFAULT" read-only="false"
                propagation="REQUIRED" />
            <tx:method name="remove*" isolation="DEFAULT" read-only="false"
                propagation="REQUIRED" />
            <tx:method name="update*" isolation="DEFAULT" read-only="false"
                propagation="REQUIRED" />
            <tx:method name="modify*" isolation="DEFAULT" read-only="false"
                propagation="REQUIRED" />
            <tx:method name="get*" isolation="DEFAULT" read-only="true"
                propagation="REQUIRED" />
            <tx:method name="find*" isolation="DEFAULT" read-only="true"
                propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置织入 -->
    <aop:config>
        <!-- 配置切点表达式 -->

        <aop:pointcut
            expression="execution(* cn.xm.exam.service.impl.*.*ServiceImpl.*(..))"
            id="texPc" />
        <!-- 配置切面:切点+通知 advice-ref:通知名称 pointcut-ref:切点名称 -->
        <aop:advisor advice-ref="firstTx" pointcut-ref="texPc" />
    </aop:config>

    <aop:config>
        <!-- 配置切点表达式 -->
        <aop:pointcut
            expression="execution(* cn.xm.exam.service.impl.*.*.*ServiceImpl.*(..))"
            id="secondPc" />
        <!-- 配置切面:切点+通知 advice-ref:通知名称 pointcut-ref:切点名称 -->
        <aop:advisor advice-ref="firstTx" pointcut-ref="secondPc" />
    </aop:config>

        <!-- 5.开启组件自动扫描,也就是启用注解。前提是导入spring-context-3.2.xsd约束和引入新的命名空间 -->
    <context:component-scan base-package="cn.xm.exam.service"></context:component-scan>
   
        <!-- 6与struts2整合的配置 -->
    <!-- 扫描Action基本包 -->
    <context:component-scan base-package="cn.xm.exam.action"></context:component-scan>
    


</beans>

 

 

2.mybatis配置:

SqlMapConfig.xml(主配置)开启二级缓存与配置别名

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true" />
    </settings>
    <!-- 只需要定义个别名,这个应该有 -->
    <typeAliases>
        <package name="cn.xm.exam.bean.common" />
        <package name="cn.xm.exam.bean.employee" />
        <package name="cn.xm.exam.bean.employee.in" />
        <package name="cn.xm.exam.bean.employee.out" />
        <package name="cn.xm.exam.bean.exam" />
        <package name="cn.xm.exam.bean.grade" />
        <package name="cn.xm.exam.bean.question" />
        <package name="cn.xm.exam.bean.system" />
        <package name="cn.xm.exam.bean.trainContent" />
    </typeAliases>
</configuration>

 

 与接口对应的mapper(开启二级缓存)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.xm.exam.mapper.exam.custom.ExampaperCustomMapper">
    <!-- 开启二级缓存 -->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache" />
    <!-- S 分页查询试卷基本信息 -->
    <!-- SELECT COUNT(paperId) FROM exampaper WHERE title LIKE '%阳城%' AND LEVEL=1 -->
    <select id="getPaperTotalByCondition" parameterType="hashmap"
        resultType="int">
        SELECT COUNT(paperId) FROM exampaper
        <where>
            <include refid="query_papaer_where"></include>
        </where>
    </select>
    <select id="findPapersByCondition" parameterType="hashmap"
        resultType="cn.xm.exam.bean.exam.Exampaper">
        SELECT * FROM exampaper
        <where>
            <include refid="query_papaer_where"></include>
        </where>
        ORDER BY MAKETIME DESC
        <include refid="query_paper_limit"></include>
    </select>

    <!--S 查询条件 -->
    <!-- 查询试卷条件 -->
    <sql id="query_papaer_where">
        <if test="title!=null">
            and title like '%${title}%'
        </if>
        <if test="departmentId != null">
            AND departmentId=#{departmentId}
        </if>
        <if test="level!=null">
            and level=#{level}
        </if>
    </sql>
    <!--分页条件 -->
    <sql id="query_paper_limit">
        <if test="index!=null">
            LIMIT #{index},#{currentCount}
        </if>
    </sql>
    <!--E 查询条件 -->

    <!--E 分页查询试卷基本信息 -->


    <!-- S 查询一份试卷完整信息 -->
    <!-- 试卷映射map -->
    <resultMap type="cn.xm.exam.bean.exam.Exampaper" id="paperAllInfo">
        <!-- 试卷基本信息 -->
        <id column="paperId" property="paperid" />
        <result column="paperScore" property="paperscore" />
        <result column="maketime" property="maketime" />
        <result column="level" property="level" />
        <result column="employeename" property="employeename" />
        <result column="title" property="title" />
        <result column="usetimes" property="usetimes" />
        <result column="description" property="description" />
        <!-- 大题 -->
        <collection property="bigQuestions" ofType="cn.xm.exam.bean.exam.Bigquestion">
            <id column="bigquertionid" property="bigquertionid" />
            <result column="paperid" property="paperid" />
            <result column="bigquestionname" property="bigquestionname" />
            <result column="bigquestionsequence" property="bigquestionsequence" />
            <!---->
            <collection property="questions"
                ofType="cn.xm.exam.bean.exam.Exampaperquestion">
                <id column="questionid" property="questionid" />
                <result column="paperid" property="paperid"></result>
                <result column="bigquertionid" property="bigquertionid"></result>
                <result column="questioncontent" property="questioncontent"></result>
                <result column="questionsequence" property="questionsequence"></result>
                <result column="type" property="type"></result>
                <result column="answer" property="answer"></result>
                <result column="analysis" property="analysis"></result>
                <result column="score" property="score"></result>
                <result column="questionsource" property="questionsource"></result
						

上一篇: 数据结构与算法] 归并排序(详情:递归和非递归归并排序 | Free: 泡泡排序和选择排序)

下一篇: 基于 B/S 架构的在线考试系统的设计与实施