java选修结课作业:ssm项目-人事管理系统-经验记录

前端框架:Layui,jquery

数据库:MySQL

数据库连接池:c3p0

J2EE:Tomcat, Servlet, JSP, Filter

视图框架:Spring MVC

ORM框架:MyBatis

日志:SLF4J 1.7、Log4j

前言

这是笔者(有一点javaSE的基础)第一次接触javaweb和三大框架,并在一周时间内粗略速通以上知识点并完成一个MVC+ORM框架的java项目。所以接下来记录的很多操作仅作为第一次经验的总结,没啥水平←

完成日志

05/22 新建springmvc项目并配置好相关xml文件、java项目部署到tomcat、基本字段的设计、JDBC成功连接mysql、完成login.jsp页。

05/28 重新用Maven新建了ssm项目,添加了其所需要的jar包,配置好了spring/springmvc/mybatis的相关配置信息,xml方式配置好了数据库以及日志,引入并配置好了mybatis逆向工程。

06/01-06/05完成项目代码。

过程中遇到的问题和操作记录

连接mysql

导入jar包,提前在mysql里创建要用的数据库和表,启动服务

package com.tjpu.dao;

import java.sql.*;

public class JdbcTest {
    //jdbc驱动名以及数据库url
    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    //数据库ip地址 数据库名 batch批量执行
    static final String DB_URL = "jdbc:mysql://localhost:3306/ssm_system?characterEncoding=utf-8&rewriteBatchedStatement=true";
    // 数据库的用户名与密码,需要根据自己的设置
    static final String USER = "root";
    static final String PASS = "*******";
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try{
            // 注册 JDBC 驱动 Class.forName()作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
            Class.forName(JDBC_DRIVER);

            // 打开链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL,USER,PASS);//获取数据库连接

            // 执行查询
            System.out.println(" 实例化Statement对象...");
            //获得执行sql语句的对象
            stmt = conn.createStatement();//创建一个Statement对象将SQL语句发送到数据库
            String sql;
            //编写sql语句
            sql = "SELECT * FROM emp";
            /*要用statement类的executeQuery()方法来下达select指令以查询数据库,
            executeQuery()方法会把数据库响应的查询结果存放在ResultSet类对象中供我们使用*/
            //执行sql
            ResultSet rs = stmt.executeQuery(sql);

            // 展开结果集数据库 遍历结果集
            while(rs.next()){
                // 通过字段检索
                int empno = rs.getInt("empno");
                String ename = rs.getString("ename");
                int eage = rs.getInt("eage");

                // 输出数据
                System.out.print("工号: " + empno);
                System.out.print(", 姓名: " + ename);
                System.out.print(", 年龄: " + eage);
                System.out.print(" ");
            }
            // 完成后关闭 释放资源
            rs.close();
            stmt.close();
            conn.close();
        }catch(SQLException se){
            // 处理 JDBC 错误
            se.printStackTrace();
        }catch(Exception e){
            // 处理 Class.forName 错误
            e.printStackTrace();
        }finally{
            // 关闭资源
            try{
                if(stmt!=null) stmt.close();
            }catch(SQLException se2){
            }// 什么都不做
            try{
                if(conn!=null) conn.close();
            }catch(SQLException se){
                se.printStackTrace();
            }
        }
        System.out.println("连接数据库结束!");
    }
}

利用ul li完成上浮气泡效果

        /*每一个li都是一个气泡*/
        .wrap ul li:nth-child(1) {
            left: 0;
            animation-duration: 10s;
            -moz-animation-duration: 10s;
            -o-animation-duration: 10s;
            -webkit-animation-duration: 10s;
        }
        .wrap ul li:nth-child(2) {
            width: 40px;
            height: 40px;
            left: 10%;
            animation-duration: 15s;
            -moz-animation-duration: 15s;
            -o-animation-duration: 15s;
            -webkit-animation-duration: 11s;
        }
        .wrap ul li:nth-child(3) {
            left: 20%;
            width: 25px;
            height: 25px;
            animation-duration: 12s;
            -moz-animation-duration: 12s;
            -o-animation-duration: 12s;
            -webkit-animation-duration: 12s;
        }
        .wrap ul li:nth-child(4) {
            width: 50px;
            height: 50px;
            left: 30%;
            -webkit-animation-delay: 3s;
            -moz-animation-delay: 3s;
            -o-animation-delay: 3s;
            animation-delay: 3s;
            animation-duration: 12s;
            -moz-animation-duration: 12s;
            -o-animation-duration: 12s;
            -webkit-animation-duration: 12s;
        }
        .wrap ul li:nth-child(5) {
            width: 60px;
            height: 60px;
            left: 40%;
            animation-duration: 10s;
            -moz-animation-duration: 10s;
            -o-animation-duration: 10s;
            -webkit-animation-duration: 10s;
        }
        .wrap ul li:nth-child(6) {
            width: 75px;
            height: 75px;
            left: 50%;
            -webkit-animation-delay: 7s;
            -moz-animation-delay: 7s;
            -o-animation-delay: 7s;
            animation-delay: 7s;
        }
        .wrap ul li:nth-child(7) {
            left: 60%;
            width: 30px;
            height: 30px;
            animation-duration: 8s;
            -moz-animation-duration: 8s;
            -o-animation-duration: 8s;
            -webkit-animation-duration: 8s;
        }
        .wrap ul li:nth-child(8) {
            width: 90px;
            height: 90px;
            left: 70%;
            -webkit-animation-delay: 4s;
            -moz-animation-delay: 4s;
            -o-animation-delay: 4s;
            animation-delay: 4s;
        }
        .wrap ul li:nth-child(9) {
            width: 50px;
            height: 50px;
            left: 80%;
            animation-duration: 20s;
            -moz-animation-duration: 20s;
            -o-animation-duration: 20s;
            -webkit-animation-duration: 20s;
        }
        .wrap ul li:nth-child(10) {
            width: 75px;
            height: 75px;
            left: 90%;
            -webkit-animation-delay: 6s;
            -moz-animation-delay: 6s;
            -o-animation-delay: 6s;
            animation-delay: 6s;
            animation-duration: 30s;
            -moz-animation-duration: 30s;
            -o-animation-duration: 30s;
            -webkit-animation-duration: 30s;
        }
        /*创建动画*/
        @keyframes square {
            0% {

                -webkit-transform: translateY(0);
                transform: translateY(0)
            }
            100% {
                bottom: 400px;
                -webkit-transform: translateY(-500);//沿y轴方向平移
                transform: translateY(-500)
            }
        }
        @-webkit-keyframes square {
            0% {
                -webkit-transform: translateY(0);
                transform: translateY(0)
            }
            100% {
                bottom: 400px;
                -webkit-transform: translateY(-500);
                transform: translateY(-500)
            }
        }
        .container ul {
            list-style-type: none;
        }
        .container li {
            display: inline-block;
            margin: 10px 0;
        }

css3 inset属性

inset这个属性是用来简化left/right/bottom/top这几个属性。除了4个偏移值,inset()函数还有一个可选的参数,用于指定矩形的圆角。它的语法格式和border-radius属性相同。如果要指定圆角,必须带上round关键字。

box-shadow: none | inset(可选值,不设置,为外投影,设置,为内投影)

css3 属性选择器

a[attribute=value]选中带有指定属性和值的a标签

a[attribute]选中带有指定的属性的a标签

Mybatis逆向工程

mybatis是持久层框架的一种,而mybatis逆向工程可以根据我们设计好的数据库文件自动生成实体类、Mapper(接口)以及Mapper.xml(映射),无需程序员再书写常规的增删改查sql语句。

配置过程:

1.在pom.xml中引入相应的插件:

      
        org.mybatis.generator
        mybatis-generator-maven-plugin
        1.3.2
      

2.在resource文件夹下配置generatorConfig.xml





    
    

    

        
        
            
            
        

        
        
        

        
            
        

        
        

        
        

        
        

        
        

注意驱动配置和数据源配置以及表名等需要根据自己的情况书写。

3.刷新maven,双击执行执行mybatis-generator:generate

java选修结课作业:ssm项目-人事管理系统-经验记录_第1张图片

得到相应结果:

java选修结课作业:ssm项目-人事管理系统-经验记录_第2张图片

Layui框架下去掉底部固定的空白页脚部分

ctrl+f找到.laydui-body,注释掉padding-bottom

模态窗口

模态窗口是什么?就是在主界面作为环境显示的背景下,会有一个新的子界面弹出,而模态和非模态的区别就是模态窗口垄断了用户的输入,当一个模态窗口打开时,用户只能与该窗口进行交互,其他用户界面对象则无法交互,在用户完成或取消操作后才能返回主界面,而非模态窗口则允许用户依然操作其他窗口。

应用的场景比如在一些弹出的窗口中需要用户输入数据或者仅仅是广告。

可以自己手写一个或者用bootstrap的模态框model/JS的showmodaldialog/layUI的layer模块等等。

layer弹出层是一个dom元素时,该元素要放在body外层↓

切割页面的方法

比如像以下一个简单的系统管理页

java选修结课作业:ssm项目-人事管理系统-经验记录_第3张图片

想要实现的效果是,无论我们点击左侧导航栏的哪一个按钮,地址栏地址都不会发生改变,只有红色区域框内的页面是跳转到其他前端页面。

实现方法基本上是两种:

java选修结课作业:ssm项目-人事管理系统-经验记录_第4张图片

第二种方法更为主流,例如以下案例:layui-body切割出红色框的区域,iframe用来显示页面,同时标注好name,左侧导航栏的列表项a标签用href跳转页面,同时注明target属性和先前设置的name值一致。

java选修结课作业:ssm项目-人事管理系统-经验记录_第5张图片

java选修结课作业:ssm项目-人事管理系统-经验记录_第6张图片

layUI用jquery

java选修结课作业:ssm项目-人事管理系统-经验记录_第7张图片

jquery重置表单

JQuery中没有reset方法,需要通过调用DOM中的reset方法来重置表单.

$('#aaa')[0].reset();

SSM项目静态资源配置

spring在web.xml配置中拦截了所有的请求,如下

  
    SpringMVC
    
    /
  

这样会导致放在webapp下非WEB-INF下的js,css等静态资源无法访问【WEB-INF下的文件受保护,无法直接访问。

因此需要在spring-mvc.xml中配置忽略对静态资源请求的拦截。

    

    

按理说被我注释掉的那行就可以实现效果,但我实际运行项目不行,因此还是写了第二行。这样就会忽略webapp下对static目录下所有资源的请求拦截。(一个*是一层目录,两个就是以下所有层

java选修结课作业:ssm项目-人事管理系统-经验记录_第8张图片

MVC框架模式的理解

MVC:模型(Model)、视图(View)、控制器(Control),最典型的MVC就是JSP + servlet + javabean的模式。

M即model模型是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。

V即View视图是指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操作的方式。

C即controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。

JSP四大作用域的差异

过滤器和拦截器

摘以下别人的关系图:

java选修结课作业:ssm项目-人事管理系统-经验记录_第9张图片

报错大全

1.Could not get JDBC Connection,Connections could not be acquired from the underlying database! (*)

首先检查db.properties数据源配置,url、用户名和密码是否正确。

当时的情况是测试连接成功,但是运行项目却报错显示无法连接数据库。

java选修结课作业:ssm项目-人事管理系统-经验记录_第10张图片

解决方法:后来发现可能是因为mysql版本和驱动版本不兼容。

mysql-connector-java 是MySQL提供的JDBC驱动包,用JDBC连接MySQL数据库时必须使用该jar包,用于连接数据库,发送sql语句和处理结果。

现在主流mysql主要有mysql5和mysql8,分别使用不同的jar包来连接数据库。mysql5.0+版本要使用mysql-connector-5.0+ jar包,mysql8.0+版本使用mysql-connector-8.0+的jar包。而我本地的mysql是mysql8。

6.0以前的驱动都要写成

jdbc.driver=com.mysql.jdbc.Driver

在6.0以上之后,就多了个cj:

jdbc.driver=com.mysql.cj.jdbc.Driver

同时URL中需要添加serverTimezone属性来设置时区值。

2.Could not find parameter map

解决方法:把mapper的xml里方法中的parameterMap换成parameterType

3.Mybatis报错: or DELIMITER expected, got 'id'

其实不影响代码运行……只是会报红

java选修结课作业:ssm项目-人事管理系统-经验记录_第11张图片

解决方法:如图找到以上页面后,把红框里的sql删了

4.check the manual that corresponds to your MySQL server version for the right syntax to use

原因:字段名和SQL关键字冲突 我的数据库表中字段名用了character

方法:更改字段名或者冲突字段前后加 反引号`符号

5.Unnamed bean definition specifies neither 'class' nor 'parent' nor 'factory-bean' - can't generate bean name

有一个 里面没有id也没写class

6.此处不允许使用元素 mvc:exclude-mapping

查看xml文件引入的mvc的xsd文件,发现IDEA自动引入的是3.0的xsd,改为引入3.2的xsd

java选修结课作业:ssm项目-人事管理系统-经验记录_第12张图片

7.java控制器返回json数据出现中文乱码

解决方法:给@RequestMapping加一个produces属性,设置它的返回类型,以及编码格式为utf-8 produces 指定响应体返回类型和编码

@RequestMapping(value = "", produces = "application/json;charset=utf-8")

8.Request processing failed; nested exceptionis java.lang.NullPointerException

写漏autowired

9.java.sql.SQLIntegrityConstraintViolationException: Column 'empno' cannot be null

写其中一个页面提交表单时一直报错这个,然后同样的代码写另一个页面就能够过。不是报这个错就是请求报400或者请求状态被取消。当时在网上怎么搜都说是前端页面表单name的值和实体类属性值不对应,但是检查了很多回都发现是一样的。最后我发现是因为我表单需要提交一个date型的数据,而前端传的参数类型与后台接收参数的实体类的属性类型不一致。(因为我用的layui表单提交的数据会自动封装成实体类传到后端,可能没办法转成date型数据...((总之当我试着删掉date型字段之后,请求都发的出去了……

解决方法应该是,可以写个类型转换的工具类,或者直接在controller里手动转换成date型后在封装到实体类,也可以直接在实体类上添加注解

你可能感兴趣的:(java,spring,intellij-idea)