SSM框架案例学习

SSM框架:SpringMVC+Spring+MyBatis

利用SSM框架设计教务管理系统,进行信息的CRUD(Create、Retrieve、Update、Delete)

学习来源:尚硅谷

实现功能:1.页面分页

                  2.数据校验:jQuery前端校验+后端校验

                  3.使用ajax无刷新的页面更新

                  4.对信息进行增删改查操作


相关技术:1.基础框架-SSM(SpringMVC+Spring+MyBatis)

                  2.数据库-MySQL

                  3.前端框架-bootstrap快速搭建界面

                  4.项目依赖管理-Maven

                  5.分页-pagehelper

                  6.MyBatis Generator


首先进行基础环境搭建:

1、创建一个maven工程

首先在eclipse中配置maven,打开eclipse,点开 windows-preferences-maven-Installations, 将安装的 maven 添加进去并选中, 然后apply,步骤如图。

  

 说明一下,首先点击Add,然后点击Directory,找到当时安装maven的路径,点击Finish。

然后在Maven下找到 User Settings, 然后添加settings.xml文件路径设置,点击 apply。

 到此,eclipse配置maven就完成了,然后使用maven创建项目。

2、引入项目依赖的jar包

在pom.xml中引入,包括Spring,SpringMVC,MyBatis,数据库连接池,驱动包以及其他包(JSTL,servlet-api,junit)

<!-- 引入项目依赖的jar包 -->
  <!-- SpringMVC、Spring -->
  <dependencies>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.7</version>
    </dependency>
    
    <!-- Spring-Jdbc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.7</version>
    </dependency>
    
    <!-- Spring面向切面编程 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.3.7</version>
    </dependency>
    
    <!-- MyBatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.2</version>
    </dependency>
    
    <!-- MyBatis整合Spring的适配包 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    
    <!-- 数据库连接池、驱动 -->
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId> 
      <version>0.9.1</version> 
    </dependency>
    
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.41</version>
    </dependency>
    
    <!-- (JSTL,servlet-api,junit) -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
     <scope>provided</scope>
    </dependency>
    
    <!-- junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>  
    
   </dependencies>

3、引入bootstrap前端框架

首先,Bootstrap 是最受欢迎的 HTML、CSS 和 JS 框架,用于开发响应式布局、移动设备优先的 WEB 项目。可以去官网自行下载。对于bookstrap的使用方法,只需要引入Bootstrap 核心 CSS 文件 和Bootstrap 核心JavaScript文件 即可。

<!-- 引入jQuery -->
<script type="text/javascript" src="static/js/jquery-1.12.4.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
<!-- 引入js -->
<script src="static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>

注意:src中的路径对应文件所在的路径。

到此,现在就可以快速搭建较美观的界面了。

使用bookstrap搭建界面时,举个例子,要为按钮添加一个好看的样式,首先在bookstrap中文网里找到喜欢的按钮对应的代码块,复制class属性里的内容即可。

4、编写SSM整合的关键配置文件

在web.xml中配置文件,给spring,springmvc,mybatis配置文件。

(1)启动Spring的容器

 然后创建Spring的配置文件,名称为applicationContext.xml

 

提示:applicationContext.xml是Spring的配置文件,主要配置和与业务逻辑有关的。

(2)SpringMVC的前端控制器 拦截所有的请求

 然后创建SpringMVC的配置文件,名称为dispatcherServlet-servlet.xml

 (3)字符编码过滤器

注意:字符编码过滤器,一定要放在所有过滤器之前

<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceRequestEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>forceResponseEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

(4)使用Rest风格的URI

作用:将页面普通的post请求转换为指定的delete或put请求

<filter>
		<filter-name>HiddenHttpMethodFilter</filter-name>
		<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>HiddenHttpMethodFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<filter-name>HttpPutFormContentFilter</filter-name>
		<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>HttpPutFormContentFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

到此,web.xml中的关键配置文件就配置完成了,接下来在各个关键配置文件中进行详细配置。


1)SpringMVC的配置文件(包含网站跳转逻辑的控制,配置)

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

<!-- SpringMVC的配置文件,包含网站跳转逻辑的控制,配置-->

<!-- 包扫描机制,扫描相应的控制器 -->
<context:component-scan base-package="com.atrjxy.crud.controller"></context:component-scan>

<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>

<!-- 两个标准配置 -->
<!-- 将SpringMVC不能处理的请求交给tomcat -->
<mvc:default-servlet-handler/>
<!-- 能支持SpringMVC一些高级的功能,如JSR303校验,快捷的ajax等映射动态请求 -->
<mvc:annotation-driven/>
</beans>

到此,SpringMVC的配置文件就完成了。

2)Spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	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.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    
   <!-- 包扫描机制,扫描除控制器外的所有包 -->
   <context:component-scan base-package="com.atrjxy">
      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
   </context:component-scan>
   
    <!-- Spring的配置文件,主要配置和与业务逻辑有关的 -->
    <!-- Srping配置文件的核心点(数据源、和mybatis的整合、事务控制) -->
    
    
    <!-- 数据源的配置-->
    <context:property-placeholder location="classpath:dbconfig.properties"/>
    <bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
       <property name="driverClass" value="${jdbc.driverClass}"></property>
       <property name="user" value="${jdbc.user}"></property>
       <property name="password" value="${jdbc.password}"></property>
    </bean>
    
    
    
    <!-- 配置和MyBatis的整合 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <!-- 指定mybatis全局配置文件的位置 -->
       <property name="configLocation" value="classpath:mybatis-config.xml"></property>
       <property name="dataSource" ref="pooledDataSource"></property>
       <!-- 指定mybatis的mapper映射文件的位置 -->
       <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
    </bean>
    
    <!-- 配置扫描器,将mybatis接口的实现加入到ioc容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <!-- 扫描所有dao接口的实现,加入到ioc容器中 -->
       <property name="basePackage" value="com.atrjxy.crud.dao"></property>
    </bean>
    
    
    
    
    
    <!-- 事务控制的配置 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 控制住数据源的开启关闭等操作 -->
        <property name="dataSource" ref="pooledDataSource"></property>
    </bean>
    
    <!-- 开启基于注解的事务,使用xml配置形式的事务(主要的都是使用配置式) -->
    <aop:config>
        <!-- 切入点表达式 -->
        <aop:pointcut expression="execution(* com.atrjxy.crud.service..*(..))" id="txPoint"/>
        <!-- 配置事务增强 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>
    
    <!-- 配置事务增强,即事务如何切入 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 所有方法都是事务方法 -->
            <tx:method name="*"/>
            <!-- 以get开始的所有方法 -->
            <tx:method name="get*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
</beans>

在数据源的配置中,这里创建一个文件dbconfig.properties文件,将jdbc相关信息提取出来,单独放在一个文件中。

 

 到此,Spring的配置就完成了。

 3)MyBatis的配置文件(使用mybatis的逆向工程生成对应的bean和mapper)

首先在pom.xml中引入,mybatis generator的jar包。

<!-- mybatis generator -->
  <dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.3.5</version>
  </dependency>

然后创建一个xml文件,名称为mbg.xml。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

  <context id="DB2Tables" targetRuntime="MyBatis3">
  <!-- 用于删除生成文件的所有注释 -->
    <commentGenerator>
      <property name="suppressAllComments" value="true" />
    </commentGenerator>
  
  <!-- 配置数据库连接 -->
    <jdbcConnection 
        driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/ssm_crud"
        userId="root"
        password="123456">
    </jdbcConnection>

    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>

 <!-- 指定JavaBean生成的位置 -->
    <javaModelGenerator 
       targetPackage="com.atrjxy.crud.bean" 
       targetProject=".\src\main\java">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>

 <!-- 指定sql映射文件生成的位置 -->
    <sqlMapGenerator 
       targetPackage="mapper"  
       targetProject=".\src\main\resources">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>

 <!-- 指定dao接口生成的位置,mapper接口 -->
    <javaClientGenerator type="XMLMAPPER" 
       targetPackage="com.atrjxy.crud.dao"  
       targetProject=".\src\main\java">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

 <!-- table指定每个表的生成策略 -->
    <table tableName="tbl_stu" domainObjectName="Student"></table>
    <table tableName="tbl_dept" domainObjectName="Department"></table>
  </context>
</generatorConfiguration>

接下来编写一个测试类来生成对应的bean和mapper文件.

package com.atrjxy.crud.test;

import java.io.File;

import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;

import org.mybatis.generator.internal.DefaultShellCallback;

public class MBGTest {
	public static void main(String[] args) throws Exception {
		   List<String> warnings = new ArrayList<String>();
		   boolean overwrite = true;
		   File configFile = new File("mbg.xml");
		   ConfigurationParser cp = new ConfigurationParser(warnings);
		   Configuration config = cp.parseConfiguration(configFile);
		   DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		   MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
		   myBatisGenerator.generate(null);
	}
}

这里需要创建对应的数据库表(学生信息表、班级信息表)

学生信息表:

 班级信息表:

创建完表后,运行代码,就生成了对应的bean和mapper文件。

 接下来,就要进行修改生成的mapper文件了(对于查询学生信息的同时也查询对应所在的班级信息,所以对StudentMapper.xml文件中添加此查询方法)。

<?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="com.atrjxy.crud.dao.StudentMapper">
  <resultMap id="BaseResultMap" type="com.atrjxy.crud.bean.Student">
    <id column="s_id" jdbcType="INTEGER" property="sId" />
    <result column="s_name" jdbcType="VARCHAR" property="sName" />
    <result column="s_sex" jdbcType="CHAR" property="sSex" />
    <result column="s_sno" jdbcType="VARCHAR" property="sSno" />
    <result column="d_id" jdbcType="INTEGER" property="dId" />
  </resultMap>
  <resultMap type="com.atrjxy.crud.bean.Student" id="WithDeptResultMap">
    <id column="s_id" jdbcType="INTEGER" property="sId" />
    <result column="s_name" jdbcType="VARCHAR" property="sName" />
    <result column="s_sex" jdbcType="CHAR" property="sSex" />
    <result column="s_sno" jdbcType="VARCHAR" property="sSno" />
    <result column="d_id" jdbcType="INTEGER" property="dId" />
    <association property="deptment" javaType="com.atrjxy.crud.bean.Deptment">
      <id column="dept_id" property="deptId" />
      <result column="dept_name" property="deptName" />
    </association>
  </resultMap>
  <sql id="Example_Where_Clause">
    <where>
      <foreach collection="oredCriteria" item="criteria" separator="or">
        <if test="criteria.valid">
          <trim prefix="(" prefixOverrides="and" suffix=")">
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
                <when test="criterion.noValue">
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue">
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue">
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue">
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Update_By_Example_Where_Clause">
    <where>
      <foreach collection="example.oredCriteria" item="criteria" separator="or">
        <if test="criteria.valid">
          <trim prefix="(" prefixOverrides="and" suffix=")">
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
                <when test="criterion.noValue">
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue">
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue">
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue">
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Base_Column_List">
    s_id, s_name, s_sex, s_sno, d_id
  </sql>
  <sql id="WithDept_Column_List">
    s.s_id, s.s_name, s.s_sex, s.s_sno, s.d_id,d.dept_id,d.dept_name
  </sql>
  
  <!-- 查询学生信息时带班级信息 -->
  <select id="selectByExampleWithDept" resultMap="WithDeptResultMap">
    select
    <if test="distinct">
      distinct
    </if>
    <include refid="WithDept_Column_List" />
    from tbl_stu s
    left join tbl_dept d on s.`d_id`=d.`dept_id`
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
      order by ${orderByClause}
    </if>
  </select>
  <select id="selectByPrimaryKeyWithDept" resultMap="WithDeptResultMap">
    select 
    <include refid="WithDept_Column_List" />
    from tbl_stu s
    left join tbl_dept d on s.`d_id`=d.`dept_id`
    where s.s_id = #{sId,jdbcType=INTEGER}
  </select>
  
  <!-- 查询学生信息时不带班级信息 -->
  <select id="selectByExample" parameterType="com.atrjxy.crud.bean.StudentExample" resultMap="BaseResultMap">
    select
    <if test="distinct">
      distinct
    </if>
    <include refid="Base_Column_List" />
    from tbl_stu
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
      order by ${orderByClause}
    </if>
  </select>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from tbl_stu
    where s_id = #{sId,jdbcType=INTEGER}
  </select>
  
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from tbl_stu
    where s_id = #{sId,jdbcType=INTEGER}
  </delete>
  <delete id="deleteByExample" parameterType="com.atrjxy.crud.bean.StudentExample">
    delete from tbl_stu
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
  </delete>
  <insert id="insert" parameterType="com.atrjxy.crud.bean.Student">
    insert into tbl_stu (s_id, s_name, s_sex, 
      s_sno, d_id)
    values (#{sId,jdbcType=INTEGER}, #{sName,jdbcType=VARCHAR}, #{sSex,jdbcType=CHAR}, 
      #{sSno,jdbcType=VARCHAR}, #{dId,jdbcType=INTEGER})
  </insert>
  <insert id="insertSelective" parameterType="com.atrjxy.crud.bean.Student">
    insert into tbl_stu
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="sId != null">
        s_id,
      </if>
      <if test="sName != null">
        s_name,
      </if>
      <if test="sSex != null">
        s_sex,
      </if>
      <if test="sSno != null">
        s_sno,
      </if>
      <if test="dId != null">
        d_id,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="sId != null">
        #{sId,jdbcType=INTEGER},
      </if>
      <if test="sName != null">
        #{sName,jdbcType=VARCHAR},
      </if>
      <if test="sSex != null">
        #{sSex,jdbcType=CHAR},
      </if>
      <if test="sSno != null">
        #{sSno,jdbcType=VARCHAR},
      </if>
      <if test="dId != null">
        #{dId,jdbcType=INTEGER},
      </if>
    </trim>
  </insert>
  <select id="countByExample" parameterType="com.atrjxy.crud.bean.StudentExample" resultType="java.lang.Long">
    select count(*) from tbl_stu
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
  </select>
  <update id="updateByExampleSelective" parameterType="map">
    update tbl_stu
    <set>
      <if test="record.sId != null">
        s_id = #{record.sId,jdbcType=INTEGER},
      </if>
      <if test="record.sName != null">
        s_name = #{record.sName,jdbcType=VARCHAR},
      </if>
      <if test="record.sSex != null">
        s_sex = #{record.sSex,jdbcType=CHAR},
      </if>
      <if test="record.sSno != null">
        s_sno = #{record.sSno,jdbcType=VARCHAR},
      </if>
      <if test="record.dId != null">
        d_id = #{record.dId,jdbcType=INTEGER},
      </if>
    </set>
    <if test="_parameter != null">
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByExample" parameterType="map">
    update tbl_stu
    set s_id = #{record.sId,jdbcType=INTEGER},
      s_name = #{record.sName,jdbcType=VARCHAR},
      s_sex = #{record.sSex,jdbcType=CHAR},
      s_sno = #{record.sSno,jdbcType=VARCHAR},
      d_id = #{record.dId,jdbcType=INTEGER}
    <if test="_parameter != null">
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByPrimaryKeySelective" parameterType="com.atrjxy.crud.bean.Student">
    update tbl_stu
    <set>
      <if test="sName != null">
        s_name = #{sName,jdbcType=VARCHAR},
      </if>
      <if test="sSex != null">
        s_sex = #{sSex,jdbcType=CHAR},
      </if>
      <if test="sSno != null">
        s_sno = #{sSno,jdbcType=VARCHAR},
      </if>
      <if test="dId != null">
        d_id = #{dId,jdbcType=INTEGER},
      </if>
    </set>
    where s_id = #{sId,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.atrjxy.crud.bean.Student">
    update tbl_stu
    set s_name = #{sName,jdbcType=VARCHAR},
      s_sex = #{sSex,jdbcType=CHAR},
      s_sno = #{sSno,jdbcType=VARCHAR},
      d_id = #{dId,jdbcType=INTEGER}
    where s_id = #{sId,jdbcType=INTEGER}
  </update>
</mapper>

4)进行Spring单元测试环境

首先创建一个名称为MapperTest的测试类,来测试dao层的工作,需要先导入SpringTest模块,所以在pom.xml中引入jar包。

<!-- Spring-test -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.3.7.RELEASE</version>
    </dependency>

然后在测试类上方编写@ContextConfiguration来指定Spring配置文件的位置,以及上方再编写一个@RunWith(SpringJUnit4ClassRunner.class)然后直接autowired注入需要的组件即可。下面测试了插入几个班级信息,插入学生信息,以及批量插入学生信息的操作。这里需要说明一下,对于进行批量操作时,需要在Spring配置文件中配置一个可以执行批量操作的sqlSession。配置代码如下:

<!-- 配置一个可以执行批量操作的sqlSession -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
       <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" ></constructor-arg>
       <constructor-arg name="executorType" value="BATCH" ></constructor-arg>
    </bean>

接下来在测试类里编写相应的测试方法。

package com.atrjxy.crud.test;

import java.util.UUID;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.atrjxy.crud.bean.Deptment;
import com.atrjxy.crud.bean.Student;
import com.atrjxy.crud.dao.DeptmentMapper;
import com.atrjxy.crud.dao.StudentMapper;


//测试dao层的工作
//Spring的项目可以使用Spring的单元测试,可以自动注入需要的组件
/**1、导入SpringTest模块
 * 2、@ContextConfiguration指定Spring配置文件的位置
 * 3、直接autowired注入需要的组件即可
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MapperTest {
	
	@Autowired
	DeptmentMapper deptmentmapper;
	
	@Autowired
	StudentMapper studentmapper;
	
	@Autowired
	SqlSession sqlSession;
	
	//测试DeptmentMapper
	@Test
	public void testCRUD() {
		System.out.println(deptmentmapper);
		
		/**插入几个班级信息
		deptmentmapper.insertSelective(new Deptment(null, "软件1901班"));
		deptmentmapper.insertSelective(new Deptment(null, "软件1902班"));
		*/
		
		//插入学生信息
		//studentmapper.insertSelective(new Student(null, "fengrui", "男", "20191610000", 1));
		
		//批量插入多个学生信息
		StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
		for(int i=0;i<3;i++) {
			String name = UUID.randomUUID().toString().substring(0, 5);
			mapper.insertSelective(new Student(null, name, "男", "123123", 1));
		}
		
	}
}

测试之后,打开数据库表里就有了增加的学生和班级信息了,到此,就测试完成了。接下来开始增删改查的操作了。


进行CRUD相关操作:

1.查询

 具体流程:1、访问首页面index.jsp

                   2、index.jsp页面发送查询学生信息列表的请求

                   3、控制器StudentController接收并处理请求,查询学生信息

                   4、结果页面list.jsp显示学生信息

因为要实现一个分页查询信息的功能,所以需要在pom.xml中引入PageHelper分页插件,具体代码如下:

<!-- 引入PageHelper分页插件 -->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.0.0</version>
    </dependency> 

具体的使用方法:然后在控制器类StudentController中使用,在查询前先调用方法PageHelper.startPage(pn, 5);这里的传入参数分别是:页码,以及每页的大小。然后可以使用PageInfo包装查询后的结果,只需要将这个PageInfo交给页面就可以,PageInfo封装了详细的分页信息和查询出来的结果。最后将PageInfo添加到model中,在页面进行显示。(可以参考PageHelper网站有具体的使用方法)。

控制器类中需要使用@Autowired注解进行依赖注入,调用Service层的方法查询学生信息,同样的,Service层使用@Autowired注解自动注入,调用dao层来返回数据。Seivice层代码如下:

package com.atrjxy.crud.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.atrjxy.crud.bean.Student;
import com.atrjxy.crud.dao.StudentMapper;

//业务逻辑组件
@Service
public class StudentService {
	
	@Autowired
	StudentMapper studentMapper;

	//查询所有学生信息
	public List<Student> getAll() {
		// TODO Auto-generated method stub
		return studentMapper.selectByExampleWithDept(null);
	}

}

查询学生信息的控制器类StudentController具体代码如下:

package com.atrjxy.crud.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.atrjxy.crud.bean.Student;
import com.atrjxy.crud.service.StudentService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/*
 * 处理学生信息CRUD请求
 */
@Controller
public class StudentController {
	
	@Autowired
	StudentService studentService;
	
	//查询学生信息(分页查询)
	@RequestMapping("/stus")
	public String getStus(@RequestParam(value = "pn",defaultValue = "1")Integer pn,Model model) {
		
		//引入PageHelper分页插件
		//在查询前只需要调用,传入参数:页码,以及每页的大小
		PageHelper.startPage(pn, 5);
		
		//startPage后面紧跟的这个查询就是分页查询
		List<Student> stus = studentService.getAll();
		
		//使用PageInfo包装查询后的结果,只需要将PageInfo交给页面就可以,PageInfo封装了详细的分页信息和查询出来的结果
		//5:代表显示的页数量
		PageInfo page = new PageInfo(stus,5);
		
		//将PageInfo添加到model中,在页面进行显示
		model.addAttribute("pageInfo", page);
		return "list";
	}
}

这样,后台代码就完成了,接下来搭建bootstrap分页页面。(具体使用方法可以参考bootstrap网站)

显示分页数据的页面list.jsp代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>学生信息</title>
<%
  pageContext.setAttribute("A_PATH",request.getContextPath());
%>
<!-- web路径
以/开始的路径,找资源,以服务器的路径为准(http://local:3306),需要加上项目名称
(http://local:3306/ssm-crud)
 -->
<script type="text/javascript" src="${A_PATH }/static/js/jquery-1.12.4.min.js"></script>
<link rel="stylesheet" href="${A_PATH }/static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="${A_PATH }/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
</head>
<body>
    <!-- 搭建显示页面 -->
    <div class="container">
        <!-- 显示标题 -->
       <div class="row">
          <div class="col-md-6"><h2>学生信息管理系统</h2></div>
        </div>
        <div class="row">
          <div class="col-md-6">
            <div class="input-group">
             <input type="text" class="form-control" placeholder="Search for...">
             <span class="input-group-btn">
               <button class="btn btn-default" type="button">Go</button>
             </span>
            </div>
          </div>
       </div>
        <!-- 显示按钮 -->
       <div class="row">
          <div class="col-md-4 col-md-offset-8">
            <button class="btn btn-success btn-sm">添加信息</button>
            <button class="btn btn-danger btn-sm">删除信息</button>
          </div>
       </div>
       <!-- 显示表格信息 -->
       <div class="row">
          <div class="col-md-12">
           <div class="panel panel-default">
            <div class="panel-heading">学生信息列表</div>
             <table class="table table-hover">
                <tr>
                    <th>#</th>
                    <th>姓名</th>
                    <th>性别</th>
                    <th>学号</th>
                    <th>班级</th>
                    <th>操作</th>
                </tr>
                <c:forEach items="${pageInfo.list }" var="stu">
                   <tr>
                    <th>${stu.sId }</th>
                    <th>${stu.sName }</th>
                    <th>${stu.sSex }</th>
                    <th>${stu.sSno }</th>
                    <th>${stu.deptment.deptName }</th>
                    <th>
                       <button class="btn btn-success btn-sm">
                        <span class="glyphicon glyphicon-edit" aria-hidden="true"></span>          
                                             编辑</button>
                       <button class="btn btn-danger btn-sm">
                        <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
                                             删除</button>
                    </th>
                </tr>
                </c:forEach>
                
             </table>
          </div>
          </div>
       </div>
       <!-- 显示分页信息 -->
       <div class="row">
         <!-- 分页文字信息 -->
         <div class="col-md-6">
                    当前第${pageInfo.pageNum}页,共${pageInfo.pages}页,共${pageInfo.total}条记录
         </div>
         <!-- 分页条信息 -->
         <div class="col-md-6">
           <nav aria-label="Page navigation">
  				<ul class="pagination">
  				<li><a href="${A_PATH }/stus?pn=1">首页</a></li>
  				
  				<c:if test="${pageInfo.hasPreviousPage }">
  				   <li>
     					<a href="${A_PATH }/stus?pn=${pageInfo.pageNum-1 }" aria-label="Previous">
        				<span aria-hidden="true">&laquo;</span>
      					</a>
   					 </li>
  				</c:if> 
  				
   					 <c:forEach items="${pageInfo.navigatepageNums }" var="page_Num">
   					   <c:if test="${page_Num == pageInfo.pageNum }">
   					    <li class="active"><a href="#">${page_Num }</a></li>
   					   </c:if>
   					   <c:if test="${page_Num != pageInfo.pageNum }">
   					    <li><a href="${A_PATH }/stus?pn=${page_Num }">${page_Num }</a></li>
   					   </c:if>
   					 </c:forEach>
   					 
   					 <c:if test="${pageInfo.hasNextPage }">
   					    <li>
      					   <a href="${A_PATH }/stus?pn=${pageInfo.pageNum+1 }" aria-label="Next">
        				   <span aria-hidden="true">&raquo;</span>
      					</a>
    				</li>
   					 </c:if>
   					 
    				<li><a href="${A_PATH }/stus?pn=${pageInfo.pages }">末页</a></li>
  				</ul>
			</nav>
         </div>
       </div>
    </div>
</body>
</html>

到此,显示分页查询数据就完成了。

为了实现客户端的无关性,接下来使用ajax让index.jsp页面直接发送ajax请求进行员工分页数据的查询,然后服务器将查询出的数据,以json字符串的格式返回给浏览器。浏览器收到json字符串,可以使用js对json字符串进行解析,使用js通过dom对页面数据进行增删改查。

在使用json字符串返回数据的时候,@ResponseBody注解可以自动将返回对象转换为json字符串,并且需要导入jackson包,所以在pom.xml添加依赖,具体代码如下:

<!-- 返回json字符串的支持 -->
   <dependency>
	 <groupId>com.fasterxml.jackson.core</groupId>
	 <artifactId>jackson-databind</artifactId>
	 <version>2.8.8</version>
   </dependency>

为了进行增删改查后是否操作成功,定义一个json通用的返回的类名称为Msg,包含状态码,提示信息以及用户返回给浏览器的数据,并且含有它们的get和set方法,处理成功和处理失败的方法,以及add方法(主要用于添加pageInfo分页对象)。然后在StudentController控制器中,对查询学生信息的方法getStusWithJson的返回类型为Msg类型。类Msg的代码如下:

package com.atrjxy.crud.bean;

import java.util.HashMap;
import java.util.Map;

//json通用的返回的类
public class Msg {
	//状态码 例如100-成功 200-失败
	private int code;
	
	//提示信息
	private String msg;
	
	//用户返回给浏览器的数据
	private Map<String, Object> extend = new HashMap<String, Object>();
	
	public static Msg success() {
		Msg result = new Msg();
		result.setCode(100);
		result.setMsg("处理成功");
		return result;
	}
	
	public static Msg fail() {
		Msg result = new Msg();
		result.setCode(200);
		result.setMsg("处理失败");
		return result;
	}
	
	public Msg add(String key,Object value) {
		this.getExtend().put(key, value);
		return this;
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public Map<String, Object> getExtend() {
		return extend;
	}

	public void setExtend(Map<String, Object> extend) {
		this.extend = extend;
	}
	
	
}

控制器类StudentCotroller相关代码如下:

//@ResponseBody注解可以自动将返回对象转换为json字符串,并且需要导入jackson包
	@RequestMapping("/stus")
	@ResponseBody
	public Msg getStusWithJson(@RequestParam(value = "pn",defaultValue = "1")Integer pn) {
		//引入PageHelper分页插件
				//在查询前只需要调用,传入参数:页码,以及每页的大小
				PageHelper.startPage(pn, 5);
				
				//startPage后面紧跟的这个查询就是分页查询
				List<Student> stus = studentService.getAll();
				
				//使用PageInfo包装查询后的结果,只需要将PageInfo交给页面就可以,PageInfo封装了详细的分页信息和查询出来的结果
				//5:代表显示的每页大小
				PageInfo page = new PageInfo(stus,5);
				return Msg.success().add("pageInfo", page);
	}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值