eclipse 创建一个springmvn+spring+mybatis+maven的项目

根据我的上一篇文章呢,创建了一个完整的基于maven的web项目,那么下一步就是搭建一个基本的ssm框架了

首先,spring:一个轻量级的Java框架;springMvc:一个基于springframeWork的后续产品;myBatis:基于Java的持久层框架。

1、前期准备工作,创建一个库,创建表

我用的电脑系统是Windows系统,官网下载的mysql。

mysql操作工具,用的mysql workbench,一款免费的mysql操作工具

创建一个库,暂定为test,创建表tb_user(user_id,user_name,user_password,user_email)

随便插入点数据,以备后面使用

2、框架包依赖的的整合

打开pom文件,修改pom文件

项目主要依赖的jar包有Spring核心包、Spring AOP包、Spring MVC包、MyBatis ORM包、MyBatis-Spring适配包、数据库连接池、JSTL、JUnit、Log4j2等,具体的pom.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.zhz.test</groupId>
	<artifactId>test</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>test Maven Webapp</name>
	<url>http://maven.apache.org</url>


	<!-- 引入包的版本号变量 -->
	<properties>
		<!-- spring版本号 -->
		<spring.version>3.2.9.RELEASE</spring.version>
		<!-- log4j日志文件管理包版本 -->
		<slf4j.version>1.6.6</slf4j.version>
		<log4j.version>1.2.12</log4j.version>
		<!-- junit版本号 -->
		<junit.version>4.11</junit.version>
		<!-- mybatis版本号 -->
		<mybatis.version>3.2.1</mybatis.version>
	</properties>




	<dependencies>
		<!-- servlet依赖 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>3.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.2</version>
			<scope>provided</scope>
		</dependency>


		<!--单元测试依赖 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- 添加Spring依赖 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>


		<!--spring单元测试依赖 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>


		<!-- 日志文件管理包 -->
		<!-- log start -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<!-- log end -->


		<!--mybatis依赖 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>


		<!-- mybatis/spring包 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.2.0</version>
		</dependency>


		<!-- mysql驱动包 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.29</version>
		</dependency>


		<!--c3p0 连接池 -->
		<dependency>
			<groupId>c3p0</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.1.2</version>
		</dependency>


		<!-- aspectJ AOP 织入器 -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.9</version>
		</dependency>


		<!--文件上传 -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>




	</dependencies>
	<build>
		<finalName>test</finalName>
	</build>
</project>

完成后,保存pom文件,可以看到eclipse开始更新项目,下载依赖包



这个时刻再看就可以发现项目已经没有了报错信息提示等,是因为导入了对应了servlet包,所以index.jsp不报错了。

3、创建配置文件

在resources目录下,创建对应的数据库连接配置文件,config.properties

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
mysql.user=root
mysql.password=123456
mysql.acquireIncrement=5
mysql.initialPoolSize=10
mysql.minPoolSize=5
mysql.maxPoolSize=20

创建spring-mybatis.xml整合mybatis

<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.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">
    
    <!-- 1.引入属性文件 -->
    <context:property-placeholder location="classpath:config.properties" />
    
    <!-- 2.自动扫描service包(自动注入) -->
    <context:component-scan base-package="com.demo.service" />
    
    <!-- ========================================配置数据源========================================= -->
    <!-- 3.配置C3P0数据源 -->  
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
        destroy-method="close">
        <!--驱动类名 -->
        <property name="driverClass" value="${mysql.driver}" />
        <!-- url -->
        <property name="jdbcUrl" value="${mysql.url}" />
        <!-- 用户名 -->
        <property name="user" value="${mysql.user}" />
        <!-- 密码 -->
        <property name="password" value="${mysql.password}" />
        <!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 -->
        <property name="acquireIncrement" value="${mysql.acquireIncrement}"></property>
        <!-- 初始连接池大小 -->
        <property name="initialPoolSize" value="${mysql.initialPoolSize}"></property>
        <!-- 连接池中连接最小个数 -->
        <property name="minPoolSize" value="${mysql.minPoolSize}"></property>
        <!-- 连接池中连接最大个数 -->
        <property name="maxPoolSize" value="${mysql.maxPoolSize}"></property>
       
    </bean>  
    
    <!-- ========================================针对myBatis的配置项============================== -->
    <!-- 4.配置sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 实例化sqlSessionFactory时需要使用上述配置好的数据源以及SQL映射文件 -->
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- sql映射文件路径 -->
        <!-- 自动扫描com/demo/mapping/目录下的所有SQL映射的xml文件, 省掉Configuration.xml里的手工配置
        value="classpath:com/demo/mapping/*.xml"指的是classpath(类路径)下com.demo.mapping包中的所有xml文件 -->
        <property name="mapperLocations" value="classpath:com/demo/mapping/*.xml" />
    </bean>
    
    <!-- 5.配置扫描器  -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 扫描com.demo.dao这个包以及它的子包下的所有映射接口类 -->
        <property name="basePackage" value="com.demo.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
    
    <!-- ========================================配置事务============================== -->
    <!-- 6.声明式事务管理 -->
    <!--定义事物管理器,由spring管理事务 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 配置数据源 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

    
</beans>

创建spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/aop   
        http://www.springframework.org/schema/aop/spring-aop-4.3.xsd   
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd   
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-4.3.xsd   
        http://www.springframework.org/schema/mvc   
        http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd   
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-4.3.xsd" >
    
    <!-- 1.自动扫描包,实现支持注解的IOC  -->
    <!-- 自动扫描该包,使springmvc认为包下用了@Controller注解的类是控制器 -->
    <context:component-scan base-package="com.demo.controller" /> 
    
    <!-- 2.配置注解的处理器映射器和处理器适配器 -->
    <!-- <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学者
        快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与
        AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。 -->
    <mvc:annotation-driven />
    
    <!-- 3.Spring MVC不处理静态资源  -->
    <mvc:default-servlet-handler/>
    
    <!-- 4.配置内部视图解析器 -->
      <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!--5.配置文件上传解析器 -->
    <!--Spring MVC默认不能识别multipart格式的文件内容 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    </bean>
    
</beans>

修改web.xml

<web-app id="WebApp_ID" version="3.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  
  <!--  加载spring和mybatis的配置文件 --> 
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mybatis.xml</param-value>
    </context-param>
    
    <!-- 使用ContextLoaderListener初始化Spring容器 -->
    <!--若没有指定其他参数,默认查找的配置文件位置是:/WEB-INF/applicationContext.xml  -->
    <listener>
        <description>Spring容器加载监听器</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- 配置springmvc核心控制器 -->
    <!-- spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <description>spring MVC 配置文件路径</description>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
         <!-- 启动动优先级,越小越早加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- Servlet访问的路径映射,所有的访问都必须经过调度用的前置控制器 -->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!--编码过滤器 -->
    <filter>
        <description>字符集过滤器</description>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <description>字符集编码</description>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <!-- 路径映射 -->
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
  
  
</web-app>

4、完善项目结构,生成实体类

在实际开发中,因为对应的表实在太多,手写太麻烦,我们考虑使用mybatis generator来自动生成。

<!-- Mybatis Generator -->
		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>1.3.2</version>
		</dependency>

但是我又不想在项目中添加这些冗余的代码,怎么办?我思考了下,于是新建了一个本地简单的Java项目


我在项目中,导入了三个jar包,mybatis-3.21.jar、mybatis-generator-core-1.32.jar、mysql-connector-java-5.1.34.jar

然后再src下面建立一个文件generator.xml(注意配置本地mysql jar包的路径),

<?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>  
    <!-- 数据库驱动 -->  
    <classPathEntry location="D:\java_workspaces\mybatis-generator\mysql-connector-java-5.1.34.jar" />  
    <context id="DB2Tables" targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true" />  
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->  
            <property name="suppressAllComments" value="true" />  
        </commentGenerator>  
        <!--数据库链接URL,用户名、密码 -->  
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"  
            connectionURL="jdbc:mysql://localhost:3306/test"   
            userId="root" password="123456">  
        </jdbcConnection>  
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false" />  
        </javaTypeResolver>  
        <!-- 生成模型的包名和位置 -->  
        <javaModelGenerator targetPackage="com.demo.model"  
            targetProject="src">  
            <property name="enableSubPackages" value="true" />  
            <property name="trimStrings" value="true" />  
        </javaModelGenerator>  
        <!-- 生成映射文件的包名和位置 -->  
        <sqlMapGenerator targetPackage="com.demo.mapping"  
            targetProject="src">  
            <property name="enableSubPackages" value="true" />  
        </sqlMapGenerator>  
        <!-- 生成DAO的包名和位置 -->  
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.demo.dao"   
             targetProject="src">  
             <property name="enableSubPackages" value="true" />  
        </javaClientGenerator>  
        <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名 -->  
        <table tableName="tb_user" domainObjectName="User"  
            enableCountByExample="fasle" enableUpdateByExample="false"  
            enableDeleteByExample="false" enableSelectByExample="false"  
            selectByExampleQueryId="false" >  
        </table>
    </context>  
</generatorConfiguration>    

建立一个包名字叫com.demo.test,里面建立个类

package com.demo.test;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
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.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

public class MybatisGeneratorTest {
	
	public static void main(String[] args)
			throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
			List<String> warnings = new ArrayList<String>();
			boolean overwrite = true;
			//读取配置文件generatorConfig.xml
			File configFile = new File("src/generator.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);
			for (String s : warnings) {
			System.out.println(s);
			}
			}

}

在xml里面配置好对应的生成包的路径,然后运行main方法,发现生成了对应的代码,很完美的不开了在开发项目中添加这些冗余的代码,对不对,我所做的只需要添加一个copy的工作。然后在此基础上做一些个性化的操作,比如分页查询等

/**
     * 查询用户信息并分页
     * @param skip
     * @param size
     * @return
     */
    public List<User> queryUserPager(@Param("skip") int skip,@Param("size") int size);
    
    /**
     * 查询用户总数
     * @return
     */
    public int queryUserCount();
    
    /**
     * 删除多个用户
     * @param userIds
     * @return
     */
    public int deleteUsers(int[] userIds);
<!--查询用户信息并分页 -->
    <select id="queryUserPager" resultMap="BaseResultMap">
        select t.user_id,t.user_name,t.user_sex,date_format(t.user_birthday,'%Y-%m-%d')user_birthday,
        t.user_email,t.user_edu,t.user_telephone,t.user_address,p.codedesc as user_sex_desc,
        p1.codedesc as user_edu_desc
        from tb_user t inner join tb_dict p on t.user_sex=p.code and p.field='SEX' 
        inner join tb_dict p1 on t.user_edu = p1.code and p1.field = 'EDU'
        order by t.create_time desc
        limit #{skip},#{size}
    </select>

    <!--查询用户总数 -->
    <select id="queryUserCount" resultType="int">
        select count(*) from tb_user
    </select>
    
    <!--删除多个用户 -->
    <delete id="deleteUsers" parameterType="java.util.List">
       delete from tb_user where user_id in
       <!-- <foreach>标签有循环的功能,可以用来生成有规律的SQL语句,主要属性有:
        item:表示集合每一个元素进行迭代时的别名
        index:表示在迭代过程中,每次迭代到的位置
        open:表示该语句以什么开始
        separator:表示每次迭代之间以什么符号作为分隔
        close:表示该语句以什么结束
        collection:要循环的集合 -->
       <foreach item="item" index="index" collection="array" open="(" separator="," close=")">
           #{item}
         </foreach>
    </delete>

5、完善服务层

写上对应的服务接口,实现等。注意服务接口要写在配置的xml文件对应的包里面


6、完善控制层

参考:https://www.cnblogs.com/xiaoxi/p/6260628.html

控制层实现一个简单的查询列表方法

package com.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.demo.service.IUserService;

@Controller
@RequestMapping("/user")
public class UserController {
	
	/** 
     * 日志打印器
     */
    private static final Logger  LOGGER = LoggerFactory.getLogger(UserController.class);
	
	@Autowired
	private IUserService userService;
	/**
	 * 查询用户信息
	 * @param model
	 * @param pageNO
	 */
	@RequestMapping("/list")
	public void list(Model model,@RequestParam(required=false,defaultValue="1") int pageNO){
		try {
			LOGGER.info("查询用户列表信息,入参pageNo:{0}",pageNO);
			int size=5;
			model.addAttribute("success",true);
	        model.addAttribute("size",size);
	        model.addAttribute("pageNO",pageNO);
	        model.addAttribute("count",userService.queryUserCount());
	        model.addAttribute("userList", userService.queryUserPager(pageNO, size));
	        LOGGER.info("查询用户列表信息完成");
		} catch (Exception e) {
			// TODO: handle exception
			LOGGER.info("查询用户列表信息异常,"+e.getMessage());
			model.addAttribute("success", false);
			model.addAttribute("errorMsg", "查询列表失败");
			
		}
		
	}

}

然后完善对应的页面,我们在webapp下面新建文件夹view/user,在文件夹下面新建list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="<c:url value="/styles/main.css"/>"  type="text/css" rel="stylesheet" />
<title>用户管理</title>
</head>
<body>
    <div class="main">
        <h2 class="title"><span>用户管理</span></h2>
        <form action="deleteUsers" method="post">
        <table border="1" width="100%" class="tab">
            <tr>
                <th><input type="checkbox" id="chkAll"></th>
                <th>姓名</th>
                <th>性别</th>
                <th>出生日期</th>
                <th>邮箱</th>
                <th>学历</th>
                <th>联系方式</th>
                <th>家庭住址</th>
                <th>操作</th>
            </tr>
            <c:forEach var="entity" items="${userList}">
                <tr>
                    <th><input type="checkbox" name="user_id" value="${entity.user_id}"></th>
                    <td>${entity.user_name}</td>
                    <td>${entity.user_sex_desc}</td>
                    <td>${entity.user_birthday}</td>
                    <td>${entity.user_email}</td>
                    <td>${entity.user_edu_desc}</td>
                    <td>${entity.user_telephone}</td>
                    <td>${entity.user_address}</td>
                    <td>
                    <a href="edit/${entity.user_id}" class="abtn">编辑</a>
                    <a href="deleteUserById/${entity.user_id}" class="abtn">删除</a>
                    </td>
                </tr>
            </c:forEach>
        </table>
        <div id="pager"></div>
        <p>
            <a href="add" class="abtn out">添加</a>
            <input type="submit"  value="批量删除" class="btn out" οnclick="return submitForm();"/>
        </p>
        <p style="color: red">${message}</p>
        <!--分页 -->
        <script type="text/javascript" src="<c:url value="/scripts/jQuery1.11.3/jquery-1.11.3.min.js"/>" ></script>
        <link href="<c:url value="/scripts/pagination22/pagination.css"/>"  type="text/css" rel="stylesheet" />
        <script type="text/javascript" src="<c:url value="/scripts/pagination22/jquery.pagination2.2.js"/>" ></script>
        <script type="text/javascript">
            
            $(document).ready(function(){
                //全选/取消全选
                $("#chkAll").click(function(){
                    var checked=$("#chkAll").prop("checked");
                    $("input[name='user_id']").prop("checked",checked);
                })
            })
        
           //初始化分页组件
           var count=${count};
           var size=${size};
           var pageNO=${pageNO};
           $("#pager").pagination(count, {
              items_per_page:size,
               current_page:pageNO-1,
               next_text:"下一页",
               prev_text:"上一页",
               num_edge_entries:2,
               load_first_page:false,
              callback:handlePaginationClick
            });
           
           //回调方法
           function handlePaginationClick(new_page_index, pagination_container){
               location.href="list?pageNO="+(new_page_index+1);
           }
           
           function submitForm(){
               if($("input[name='user_id']:checked").length==0){
                   alert("请选择要删除的记录!");
                   return false;
               }
               return true;
           }
        </script>
    </form>
    </div>
</body>
</html>

然后开始测试,测试所用的是Tomcat,但是发现从eclipse中打开无法访问。

检查原因,发现项目没有发布

然后网上查询,发现是eclipse重定向了,导致的,参考文档:

https://blog.csdn.net/new_clumsybird/article/details/51881754

修改对应的eclipse配置Tomcat


这个时候重新测试发现网页打开有问题,后台日志输出也不详细,考虑服务层有问题,然后打算写一个测试类。

6、测试类的编写


在test/java下面新建一个包,然后建立一个基础测试类叫SpringTestCase.java,一个用户测试类。

package com.demo.service.test;

import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//指定bean注入的配置文件  
@ContextConfiguration(locations = { "classpath:spring-mybatis.xml" })  
//使用标准的JUnit @RunWith注释来告诉JUnit使用Spring TestRunner  
@RunWith(SpringJUnit4ClassRunner.class)  
public class SpringTestCase  extends AbstractJUnit4SpringContextTests {
	protected Logger logger = LoggerFactory.getLogger(getClass());  
	
}
package com.demo.service.test;

import java.util.List;

import org.junit.Test;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.demo.dao.UserMapper;
import com.demo.model.User;
import com.demo.service.IUserService;

public class UserServiceImplTest extends SpringTestCase {
	
	@Autowired  
    private IUserService userService;  
	
	@Test
	public void queryUserPager(){
		// TODO Auto-generated method stub
		try {
			List<User> list=  userService.queryUserPager(1, 10);
			logger.debug("查询到的用户信息如下:"+list);
		} catch (Exception e) {
			// TODO: handle exception
			logger.debug("查询到的用户信息报错:"+e);
		}
		
	}
	
	@Test
	public void queryUserCount() {
		// TODO Auto-generated method stub
		int count = userService.queryUserCount();
		logger.debug("查询用户总数:"+count);
	}

}

然后右击测试类方法,选择debug——junit Test。控制台打印出结果,这个时候发现了一些问题存在。

java.lang.Exception: DEBUG STACK TRACE for PoolBackedDataSource.close().  
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.close(AbstractPoolBackedDataSource.java:417)  
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
    ......  
java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE  
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:566)  
    at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)  
    .....  

报这个错误,查询得知,这种情况,一种是对应的服务没有注入。检查得知注入了。另一种呢,就是DataSource配置文件有问题

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

这句话,Spring在读取这个配置文件以后,需要根据这些信息来实例化一些类,然后内部再根据中间的那些配置信息来实际

构造数据源。可是来了个问题。不能保证这里的ComboPooledDataSource数据源一定是可用的,

也不能保证close方法一定能关闭连接,对吧?Spring本身不能检查这个类是否 真实有效,毫无Bug。

实际上呢,也检查不了。同样的,close方法是否有效,也需要进行检查。

那么干掉destroy-method这个参数,然后再次测试,又发生了点别的小问题,对应的对象类,缺少两个参数,从mapping配置文件里面,我添加的sql中对应的字段找不到,这是个小问题,在对象中添加好就可以啦。OK,现在测试通过,再进行网页测试,重新测试通过。


,然后在控制器中添加对应的编辑,保存方法

/**
	 * 添加用户
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping("/add")
	public void add(Model model) {
		try {
			// 与form绑定的模型
			model.addAttribute("user", new User());
			// 用于生成“性别”下拉列表
			model.addAttribute("sexList", dictService.getDictByField("SEX"));
			// 用于生成“学历”下拉列表
			model.addAttribute("eduList", dictService.getDictByField("EDU"));
			LOGGER.info("查询用户性别,学历信息列表");
		} catch (Exception e) {
			// TODO: handle exception
			LOGGER.info("查询用户性别,学历信息列表," + e.getMessage());
			model.addAttribute("success", false);
			model.addAttribute("errorMsg", "查询性别,学历列表失败");
		}

	}

	/**
	 * 添加用户保存
	 * 
	 * @param model
	 * @param entity
	 * @param bindingResult
	 * @return
	 */
	@RequestMapping("/addSave")
	public String addSave(Model model,@ModelAttribute("user") @Valid User user,BindingResult bindingResult) {
		try {
			// 如果模型中存在错误
			if (!bindingResult.hasErrors()) {
				if (userService.insertUser(user) > 0) {
					return "redirect:/user/list";
				}
			}
			model.addAttribute("user", user);
			// 用于生成“性别”下拉列表
			model.addAttribute("sexList", dictService.getDictByField("SEX"));
			// 用于生成“学历”下拉列表
			model.addAttribute("eduList", dictService.getDictByField("EDU"));
			return "";
		} catch (Exception e) {
			// TODO: handle exception
			return "user/add";
		}
	}

这里有一个问题是因为使用了JSR303校验,当保存对象是需要在参数前注解@ModelAttribute("entity") @Valid,用于激活校验,否则页面将不会有错误展示。

为了配合Bean Validation,定义的User Bean需要注解,内容如下:

public class User {
    private Integer userId;
    
    @NotEmpty(message="{用户名称不能为空}")
    private String userName;

    @NotEmpty(message="{用户性别不能为空}")
    private String userSex;

    @NotEmpty(message="{用户出生日期不能为空}")
    private Date userBirthday;

    @NotEmpty(message="{用户邮箱不能为空}")
    private String userEmail;

    @NotEmpty(message="{用户学历不能为空}")
    private String userEdu;

    @NotEmpty(message="{用户电话号码不能为空}")
    private String userTelephone;

添加对应的add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<link href="<c:url value="/styles/main.css" />" type="text/css" rel="stylesheet" />
<script language="javascript" type="text/javascript" 
    src="<c:url value="/scripts/My97DatePicker/WdatePicker.js" />"></script>
<title>新增用户</title>
</head>
<body>
    <div class="main">
        <h2 class="title"><span>新增用户</span></h2>
        <form:form action="addSave" method="post" modelAttribute="user">
        <fieldset>
            <legend>用户</legend>
            <table cellpadding="5" cellspacing="8"> 
                <tr>
                    <td><label for="userName">姓名:</label></td>
                    <td><form:input path="userName" size="40"/></td>
                    <td><form:errors path="userName" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="userSex">性别:</label></td>
                    <td>
                        <form:select path="userSex" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${sexList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="userSex" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="userBirthday">出生日期:</label></td>
                    <td><form:input path="userBirthday" size="40" class="Wdate" onClick="WdatePicker()"/></td>
                    <td><form:errors path="userBirthday" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_email">邮箱:</label></td>
                    <td><form:input path="userEmail" size="40"/></td>
                    <td><form:errors path="userEmail" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="userEdu">学历:</label></td>
                    <td>
                         <form:select path="userEdu" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${eduList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="userEdu" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="userTelephone">联系方式:</label></td>
                    <td><form:input path="userTelephone" size="40"/></td>
                    <td><form:errors path="userTelephone" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="userAddress">家庭住址:</label></td>
                    <td><form:input path="userAddress" size="40"/></td>
                    <td><form:errors path="userAddress" cssClass="error"></form:errors></td>
                </tr>
            </table>
            <p>
              <input type="submit" value="保存" class="btn out">
            </p>
        </fieldset>
        <!--<form:errors path="*"></form:errors> -->
        </form:form>
        <p style="color: red">${message}</p>
        <p>
            <a href="<c:url value="/user/list" />"  class="abtn out">返回列表</a>
        </p>
    </div>
</body>
</html>

完善编辑功能

/**
	  * 编辑用户
	  * @param model
	  * @param user_id
	  * @return
	  */
	 @RequestMapping("/edit/{user_id}")
	 public String edit(Model model,@PathVariable int user_id){
	 
		try {
			model.addAttribute("user", userService.queryUserById(user_id));
		    // 用于生成“性别”下拉列表
		    model.addAttribute("sexList",dictService.getDictByField("SEX"));
		    // 用于生成“学历”下拉列表
		    model.addAttribute("eduList",dictService.getDictByField("EDU"));
		} catch (Exception e) {
			// TODO: handle exception
		}
	    
	    return "user/edit";
	}

	/**
	 * 修改用户并保存
	 * @param model
	 * @param user
	 * @param bindingResult
	 * @return
	 */
	@RequestMapping("/editSave")
	public String editSave(Model model,@ModelAttribute("user") @Valid User user,BindingResult bindingResult){
		try {
			//如果模型中存在错误
		    if(!bindingResult.hasErrors()){
		        if(userService.updateUser(user)>0)
		        {
		            return "redirect:list";    
		        }
		    }
		    model.addAttribute("user", user);
		    model.addAttribute("sexList",dictService.getDictByField("SEX"));
		    model.addAttribute("eduList",dictService.getDictByField("EDU"));
		} catch (Exception e) {
			// TODO: handle exception
		}
	    
	    return "/user/edit";
	}

添加对应的编辑页面。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<link href="<c:url value="/styles/main.css" />" type="text/css" rel="stylesheet" />
<script language="javascript" type="text/javascript" 
    src="<c:url value="/scripts/My97DatePicker/WdatePicker.js" />"></script>
<title>编辑用户</title>
<base href="<%=basePath %>" />
</head>
<body>
    <div class="main">
        <h2 class="title"><span>编辑用户</span></h2>
        <form:form action="user/editSave" method="post" modelAttribute="user">
        <fieldset>
            <legend>用户</legend>
            <table cellpadding="5" cellspacing="8"> 
                <tr>
                    <td><label for="user_name">姓名:</label></td>
                    <td><form:input path="user_name" size="40"/></td>
                    <td><form:errors path="user_name" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_sex">性别:</label></td>
                    <td>
                        <form:select path="user_sex" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${sexList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="user_sex" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_birthday">出生日期:</label></td>
                    <td><form:input path="user_birthday" size="40" class="Wdate" onClick="WdatePicker()"/></td>
                    <td><form:errors path="user_birthday" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_email">邮箱:</label></td>
                    <td><form:input path="user_email" size="40"/></td>
                    <td><form:errors path="user_email" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_edu">学历:</label></td>
                    <td>
                         <form:select path="user_edu" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${eduList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="user_edu" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_telephone">联系方式:</label></td>
                    <td><form:input path="user_telephone" size="40"/></td>
                    <td><form:errors path="user_telephone" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_address">家庭住址:</label></td>
                    <td><form:input path="user_address" size="40"/></td>
                    <td><form:errors path="user_address" cssClass="error"></form:errors></td>
                </tr>
            </table>
            <p>
                <form:hidden path="user_id" />
                <input type="submit" value="保存" class="btn out">
            </p>
        </fieldset>
        <!--<form:errors path="*"></form:errors> -->
        </form:form>
        <p style="color: red">${message}</p>
        <p>
            <a href="<c:url value="/user/list" />"  class="abtn out">返回列表</a>
        </p>
    </div>
</body>
</html>

添加删除用户代码

/**
 * 根据用户id删除用户
 * @param model
 * @param user_id
 * @param pageNO
 * @param redirectAttributes
 * @return
 */
@RequestMapping("/deleteUserById/{user_id}")
public String deleteUserById(Model model,@PathVariable int user_id,@RequestParam(required=false,defaultValue="1") int pageNO,
        RedirectAttributes redirectAttributes){

    if(userService.deleteUserById(user_id)>0){
        redirectAttributes.addFlashAttribute("message", "删除成功!");
    }else{
        redirectAttributes.addFlashAttribute("message", "删除失败!");
    }
    return "redirect:/user/list?pageNO="+pageNO;
}

/**
 * 删除多个用户
 * @param model
 * @param userIds
 * @param pageNO
 * @param redirectAttributes
 * @return
 */
@RequestMapping("/deleteUsers")
public String deleteUsers(Model model,@RequestParam int[] user_id,@RequestParam(required=false,defaultValue="1") int pageNO,
        RedirectAttributes redirectAttributes){

    if(userService.deleteUsers(user_id)>0){
        redirectAttributes.addFlashAttribute("message", "删除成功!");
    }else{
        redirectAttributes.addFlashAttribute("message", "删除失败!");
    }
    return "redirect:/user/list?pageNO="+pageNO;
}
OK,基础的代码完成了。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值