Spring+SpringMVC+DButils开发账户管理信息系统

一、项目需求

1、数据库需求

  1. 需要一个名为springdb数据库
  2. 需要一个账户表,字段如下:
    Spring+SpringMVC+DButils开发账户管理信息系统_第1张图片
  • 创建数据库
create database if not exists springdb;
  • 创建表
create table if not exists account(
a_id int auto_increment comment '账户编号',
a_name varchar(32) comment '账户姓名',
a_money double comment '账户金额',
a_createdate date comment '开户日期',
constraint pk_account_aid primary key(a_id)
)engine=innodb default charset='utf8';
  • 为了查询更方便 将字段重命名为实体类对应的字段
create view jdbcview
as
select a_id aid,a_name aname,a_money money,a_createdate createDate
from account;

2、页面需求

  1. 需要完成账户的新增、修改、删除以及查询功能
  2. 效果如下:
    Spring+SpringMVC+DButils开发账户管理信息系统_第2张图片
    Spring+SpringMVC+DButils开发账户管理信息系统_第3张图片
    Spring+SpringMVC+DButils开发账户管理信息系统_第4张图片
    Spring+SpringMVC+DButils开发账户管理信息系统_第5张图片
    Spring+SpringMVC+DButils开发账户管理信息系统_第6张图片

二、开发思路及步骤

1、需要用到的技术

  • Spring 用于创建对象,对象的动态整合
  • SpringMVC 用于WEB层控制页面
  • dbutils DAO层数据的增删改查
  • Bootstrap 提供页面的CSS支持
  • jQuery 提供页面的JS支持

2、整合jar包

pom.xml的编写

  1. 初始化maven项目
	<properties>
		
		<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
		
		<maven.compiler.source>1.7maven.compiler.source>
		
		<maven.compiler.target>1.7maven.compiler.target>
	properties>
  1. Spring相关:spring-context 5.0.2、spring-webmvc、spring-test
  2. 数据库相关:mysql-connector-java 5.1.6、commons-dbutils 1.6、druid 1.1.9
  3. 单元测试:junit 4.12、与spring-test一起配合
  4. ServletAPI相关:jsp-api 2.0、servlet-api 2.5,设置provided
  5. 页面表达式:jstl 1.2、standard 1.1.2
  • 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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion>
	<groupId>com.gajgroupId>
	<artifactId>springmvc_tp2artifactId>
	<version>0.0.1-SNAPSHOTversion>
	<packaging>warpackaging>
	
	<properties>
		
		<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
		
		<maven.compiler.source>1.7maven.compiler.source>
		
		<maven.compiler.target>1.7maven.compiler.target>
	properties>
	
	<dependencies>
		
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-contextartifactId>
			<version>5.0.2.RELEASEversion>
		dependency>
		
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-webmvcartifactId>
			<version>5.0.2.RELEASEversion>
		dependency>
		
		<dependency>
			<groupId>commons-dbutilsgroupId>
			<artifactId>commons-dbutilsartifactId>
			<version>1.6version>
		dependency>
		
		<dependency>
			<groupId>com.alibabagroupId>
			<artifactId>druidartifactId>
			<version>1.1.9version>
		dependency>
		
		<dependency>
			<groupId>mysqlgroupId>
			<artifactId>mysql-connector-javaartifactId>
			<version>5.1.6version>
		dependency>
		
		<dependency>
			<groupId>junitgroupId>
			<artifactId>junitartifactId>
			<version>4.12version>
			<scope>testscope>
		dependency>
		
		<dependency>
			<groupId>javax.servletgroupId>
			<artifactId>jsp-apiartifactId>
			<version>2.0version>
			<scope>providedscope>
		dependency>
		
		<dependency>
			<groupId>javax.servletgroupId>
			<artifactId>servlet-apiartifactId>
			<version>2.5version>
			<scope>providedscope>
		dependency>
		
		<dependency>
			<groupId>jstlgroupId>
			<artifactId>jstlartifactId>
			<version>1.2version>
		dependency>
		
		<dependency>
			<groupId>taglibsgroupId>
			<artifactId>standardartifactId>
			<version>1.1.2version>
		dependency>
		
		<dependency>
			<groupId>org.springframeworkgroupId>
			<artifactId>spring-testartifactId>
			<version>5.0.2.RELEASEversion>
		dependency>
	dependencies>
project>

3、实体类

package com.gaj.pojo;

import java.util.Date;

/**
 * Account实体类
 * JavaBean
 * 对应springdb数据库的account表
 * 数据库字段:a_id,a_name,a_money,a_createdate
 * @author Jan
 *
 */
public class Account {
     
	
	private Integer aid;		// 账户ID
	private String aname;		// 账户姓名
	private Double money;		// 账户余额
	private Date createDate;	// 开户日期
	
	public Integer getAid() {
     
		return aid;
	}
	public void setAid(Integer aid) {
     
		this.aid = aid;
	}
	public String getAname() {
     
		return aname;
	}
	public void setAname(String aname) {
     
		this.aname = aname;
	}
	public Double getMoney() {
     
		return money;
	}
	public void setMoney(Double money) {
     
		this.money = money;
	}
	public Date getCreateDate() {
     
		return createDate;
	}
	public void setCreateDate(Date createDate) {
     
		this.createDate = createDate;
	}
	
	@Override
	public String toString() {
     
		return "Account [aid=" + aid + ", aname=" + aname + ", money=" + money + ", createDate=" + createDate + "]";
	}
}

4、DAO层

  • 接口
package com.gaj.dao;

import java.sql.SQLException;
import java.util.List;

import com.gaj.pojo.Account;

/**
 * Account数据操作层接口
 * @author Jan
 *
 */
public interface AccountDAO {
     

	public int insertAccount(Account account) throws SQLException;
	
	public int updateAccount(Account account) throws SQLException;
	
	public int deleteAccount(Account account) throws SQLException;
	
	public Account findAccountById(Integer aid) throws SQLException;
	
	public List<Account> findAccountsByPage(Integer start, Integer size) throws SQLException;
	
	public int accountTotalCount() throws SQLException;
}

  • 实现类
package com.gaj.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.gaj.dao.AccountDAO;
import com.gaj.pojo.Account;

/**
 * Account数据操作层实现类
 * @author Jan
 *
 */
@Repository
public class AccountDAOImpl implements AccountDAO {
     
	@Autowired
	private QueryRunner qr;

	@Override
	public int insertAccount(Account account) throws SQLException {
     
		// 设置返回值
		int count = 0;
		// 编写sql语句
		String sql = "insert into account values(null,?,?,?)";
		// 占位符赋值
		Object[] params = {
     account.getAname(), account.getMoney(), account.getCreateDate()};
		// 执行sql
		count = qr.update(sql, params);
		// 返回
		return count;
	}

	@Override
	public int updateAccount(Account account) throws SQLException {
     
		// 设置返回值
		int count = 0;
		// 编写sql语句
		String sql = "update account set a_name=?,a_money=?,a_createdate=? where a_id=?";
		// 占位符赋值
		Object[] params = {
     account.getAname(), account.getMoney(), account.getCreateDate(), account.getAid()};
		// 执行sql
		count = qr.update(sql, params);
		// 返回
		return count;
	}

	@Override
	public int deleteAccount(Account account) throws SQLException {
     
		// 设置返回值
		int count;
		// 编写sql语句
		String sql = "delete from account where a_id=?";
		// 占位符赋值
		Object param = account.getAid();
		// 执行sql
		count = qr.update(sql, param);
		// 返回
		return count;
	}

	@Override
	public Account findAccountById(Integer aid) throws SQLException {
     
		// 设置返回值
		Account account = null;
		// 编写sql语句
		String sql = "select * from jdbcview where aid=?";
		// 占位符赋值
		Object param = aid;
		// 执行sql
		account = qr.query(sql, new BeanHandler<Account>(Account.class), param);
		// 返回
		return account;
	}

	@Override
	public List<Account> findAccountsByPage(Integer start, Integer size) throws SQLException {
     
		// 设置返回值
		List<Account> list = null;
		// 编写sql语句
		String sql = "select * from jdbcview limit ?,?";
		// 占位符赋值
		Object[] params = {
     start, size};
		// 执行sql
		list = qr.query(sql, new BeanListHandler<Account>(Account.class), params);
		// 返回
		return list;
	}

	@Override
	public int accountTotalCount() throws SQLException {
     
		// 设置返回值
		int totalCount = 0;
		// 编写sql语句
		String sql = "select count(a_id) from account";
		// 执行sql
		Number num = qr.query(sql, new ScalarHandler<Number>(1));
		// 转换
		totalCount = num.intValue();
		// 返回
		return totalCount;
	}

}

5、Service层

  • 接口
package com.gaj.service;

import java.sql.SQLException;
import java.util.List;

import com.gaj.pojo.Account;

/**
 * Account逻辑业务层接口
 * @author Jan
 *
 */
public interface AccountService {
     

	public int insertAccount(Account account) throws SQLException;
	
	public int updateAccount(Account account) throws SQLException;
	
	public int deleteAccount(Account account) throws SQLException;
	
	public Account findAccountById(Integer aid) throws SQLException;
	
	public List<Account> findAccountsByPage(Integer pageIndex, Integer pageSize) throws SQLException;
	
	public int accountTotalCount() throws SQLException;
}

  • 实现类
package com.gaj.service.impl;

import java.sql.SQLException;
import java.util.List;

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

import com.gaj.dao.AccountDAO;
import com.gaj.pojo.Account;
import com.gaj.service.AccountService;
/**
 * Account业务逻辑层实现类
 * @author Jan
 *
 */
@Service
public class AccountServiceImpl implements AccountService {
     

	@Autowired
	private AccountDAO accountDAO;
	
	@Override
	public int insertAccount(Account account) throws SQLException {
     
		return accountDAO.insertAccount(account);
	}

	@Override
	public int updateAccount(Account account) throws SQLException {
     
		return accountDAO.updateAccount(account);
	}

	@Override
	public int deleteAccount(Account account) throws SQLException {
     
		return accountDAO.deleteAccount(account);
	}

	@Override
	public Account findAccountById(Integer aid) throws SQLException {
     
		return accountDAO.findAccountById(aid);
	}

	@Override
	public List<Account> findAccountsByPage(Integer pageIndex, Integer pageSize) throws SQLException {
     
		// 设置返回值
		List<Account> list = null;
		// 边界判断
		if(pageIndex != null && pageSize != null){
     
			if(pageIndex > 0 && pageSize > 0){
     
				// 计算起始页
				int start = (pageIndex - 1) * pageSize;
				int size = pageSize;
				list = accountDAO.findAccountsByPage(start, size);
			}
		}
		// 返回
		return list;
	}

	@Override
	public int accountTotalCount() throws SQLException {
     
		return accountDAO.accountTotalCount();
	}

}

6、Spring配置文件的编写

  • applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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.xsd">

	
	<context:component-scan base-package="com.gaj.dao" />
	<context:component-scan base-package="com.gaj.service" />
	
	
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/springdb?characterEncoding=utf-8" />
		<property name="username" value="root" />
		<property name="password" value="root" />
		
		
		<property name="filters" value="stat" />
		
	bean>
	
	
	<bean id="qr" class="org.apache.commons.dbutils.QueryRunner">
		<constructor-arg name="ds" ref="dataSource" />
	bean>

beans>

7、测试类

  • 查看DAO层和Service层能否进行CURD
package com.gaj.test;

import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

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.gaj.pojo.Account;
import com.gaj.service.AccountService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
     "classpath:applicationContext.xml"})
public class AccountTest {
     

	@Autowired
	private AccountService service;
	Random random = new Random();
	Scanner scanner = new Scanner(System.in);
	
	@Test
	public void addBatchTest() throws SQLException{
     
		Account account = null;
		System.out.println("请输入需要添加的记录数:");
		int num = scanner.nextInt();
		System.out.println("开始批量添加数据...");
		for(int i = 1; i <= num; i++){
     
			account = new Account();
			account.setAname("测试数据" + i);
			account.setMoney(random.nextInt(10000) + 0D);
			account.setCreateDate(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * random.nextInt(366)));
			
			int count = service.insertAccount(account);
			System.out.println(count > 0 ? i +" Insert OK!" : i + " Insert Failed!");
		}
		System.out.println("批量添加完成!");
	}
	
	@Test
	public void addTest() throws SQLException, ParseException{
     
		System.out.println("开始添加数据...");
		Account account = new Account();
		System.out.println("请输入账户姓名:");
		account.setAname(scanner.next());
		System.out.println("请输入账户金额:");
		account.setMoney(scanner.nextDouble());
		System.out.println("请输入开户日期:");
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		account.setCreateDate(df.parse(scanner.next()));
		
		int count = service.insertAccount(account);
		System.out.println(count > 0 ? "Insert OK!" : "Insert Failed!");
	}
	
	@Test
	public void updateTest() throws SQLException, ParseException{
     
		System.out.println("请输入需要更新的账户编号:");
		int aid = scanner.nextInt();
		Account account = service.findAccountById(aid);
		if(account != null){
     
			System.out.println("开始更新账户信息...");
			System.out.println("请输入账户姓名:");
			account.setAname(scanner.next());
			System.out.println("请输入账户金额:");
			account.setMoney(scanner.nextDouble());
			System.out.println("请输入开户日期:");
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			account.setCreateDate(df.parse(scanner.next()));
			
			int count = service.updateAccount(account);
			System.out.println(count > 0 ? "Update OK!" : "Update Failed!");
		}else{
     
			System.out.println("抱歉,没有找到这个编号的账户...");
		}
	}
	
	@Test
	public void deleteTest() throws SQLException{
     
		System.out.println("请输入需要删除的账户编号:");
		int aid = scanner.nextInt();
		Account account = service.findAccountById(aid);
		if(account != null){
     
			System.out.println("开始删除账户...");
			int count = service.deleteAccount(account);
			System.out.println(count > 0 ? "Delete OK!" : "Delete Failed!");
		}else{
     
			System.out.println("抱歉,没有找到这个编号的账户...");
		}
	}
	
	@Test
	public void query() throws SQLException{
     
		int pageSize = 10;		// 页容量
		int totalCount = 0;		// 总记录数
		int totalPage = 0;		// 总页数
		int pageIndex = 0;		// 页码
		
		totalCount = service.accountTotalCount();
		totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
		
		for(int i = 1; i <= totalPage; i++){
     
			pageIndex = i;
			System.out.println("总记录数:" + totalCount + "\t\t总页数:" + totalPage + "\t\t页容量:" + pageSize + "\t\t当前页:" + pageIndex);
			List<Account> accounts = service.findAccountsByPage(pageIndex, pageSize);
			for (Account account : accounts) {
     
				System.out.println(account);
			}
		}
	}
	
}

8、jsp文件的编写

  • index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>账户信息管理系统-首页title>
<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath }/css/bootstrap.min.css" />
<script type="text/javascript"
	src="${pageContext.request.contextPath }/js/jquery-1.9.1.js">script>
<script type="text/javascript"
	src="${pageContext.request.contextPath }/js/bootstrap.min.js">script>

head>
<body>
	<div class="jumbotron">
		<div class="container">
			<h1>欢迎使用账户信息管理系统!h1>
			<p>请选择一些功能吧...p>
			<p>
				<a class="btn btn-primary btn-lg" role="button" href="showAccountsAction?pi=1">显示账户信息a>
				
				<a class="btn btn-success btn-lg" role="button" href="account_add.jsp">添加新账户a>
			p>
		div>
	div>
body>
html>
  • account_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"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="f" %>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>账户信息管理系统-展示title>
<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath }/css/bootstrap.min.css" />
<script type="text/javascript"
	src="${pageContext.request.contextPath }/js/jquery-1.9.1.js">script>
<script type="text/javascript"
	src="${pageContext.request.contextPath }/js/bootstrap.min.js">script>
	
<style type="text/css">
	h1,th,tr {
      
		text-align: center;
	}
style>

<script type="text/javascript">
	function goIndex(pi){
      
		window.location.href="showAccountsAction?pi=" + pi;
	}
script>
head>
<body>
	<div>
		<h1 onclick="javascript:location.href='index.jsp'">展示账户信息h1>
		<table class="table table-hover">
			<tr class="active">
				<th colspan="5">
					总条数:<span style="color: red; font-size: 20px;">${totalCount }span>
					总页数:<span style="color: red; font-size: 20px;">${totalPage }span>
					页容量:<span style="color: red; font-size: 20px;">${pageSize }span>
					当前页:<span style="color: red; font-size: 20px;">${pageIndex }span>
				th>
			tr>
			<tr class="info">
				<th>账户编号th>
				<th>账户姓名th>
				<th>账户金额th>
				<th>开户日期th>
				<th>操作th>
			tr>
			<c:forEach var="account" items="${accounts }">
				<tr class="warning">
					<td>${account.aid }td>
					<td>${account.aname }td>
					<td>
						<f:formatNumber type="currency" value="${account.money }" />
					td>
					<td>
						<f:formatDate pattern="yyyy年MM月dd日" value="${account.createDate }"/>
					td>
					<td>
						<button class="btn btn-warning" type="button" onclick="javascript:location.href='findAccountAction?pi=${account.aid}'">更新button>
						<button class="btn btn-danger" type="button" onclick="javascript:location.href='deleteAccountAction?pi=${account.aid}'">删除button>
					td>
				tr>
			c:forEach>
			<tr>
				<th colspan="5">
					<button class="btn btn-default" type="button" onclick="goIndex(1);">首页button>
					<c:choose>
						<c:when test="${pageIndex > 1 }">
							<button class="btn btn-default" type="button" onclick="goIndex(${pageIndex - 1});">上一页button>
						c:when>
						<c:otherwise>
							<button class="btn btn-default" type="button" disabled="disabled" onclick="goIndex(${pageIndex - 1});">上一页button>
						c:otherwise>
					c:choose> <c:choose>
						<c:when test="${totalPage > pageIndex }">
							<button class="btn btn-default" type="button" onclick="goIndex(${pageIndex + 1})">下一页button>
						c:when>
						<c:otherwise>
							<button class="btn btn-default" type="button" disabled="disabled" onclick="goIndex(${pageIndex + 1})">下一页button>
						c:otherwise>
					c:choose>
					<button class="btn btn-default" type="button" onclick="goIndex(${totalPage});">尾页button>
				th>
			tr>
		table>
	div>
body>
html>
  • account_add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>账户信息管理系统-添加title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/css/bootstrap.min.css" />
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.1.9.1.js">script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/bootstrap.min.js">script>
<style type="text/css">
	th{
      
		font-size: large;
		color: fuchsia;
	}
style>
head>
<body>
	<div>
		<h1 style="text-align: center; color:purple;" onclick="javascript:location.href='index.jsp'" >添加账户信息h1>
		<form action="insertAccountAction" method="post">
			<table class="table table-hover">
				<tr class="info">
					<th>账户姓名:th>
					<td>
						<input class="form-control" type="text" name="aname" required="required" placeholder="请输入账户姓名..." />
					td>
				tr>
				<tr class="danger">
					<th>账户金额th>
					<td>
						<input class="form-control" type="number" name="money" min="0.0" max="9999999.99" step="0.1" required="required" placeholder="请输入账户金额..." />
					td>
				tr>
				<tr class="warning">
					<th>开户日期th>
					<td>
						<input class="form-control" type="date" name="createDate" required="required" />
					td>
				tr>
				<tr class="active">
					<th colspan="2" style="text-align:center;">
						<button class="btn btn-success" type="submit">添加button>
						
						<button class="btn btn-danger" type="reset">取消button>
					th>
				tr>
			table>
		form>
	div>
body>
html>
  • account_update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>账户信息管理系统-更新title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/css/bootstrap.min.css" />
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.1.9.1.js">script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/bootstrap.min.js">script>
<style type="text/css">
	th{
      
		font-size: large;
		color: fuchsia;
	}
style>
head>
<body>
	<div>
		<h1 style="text-align: center; color:purple;" onclick="javascript:location.href='index.jsp'" >更新账户信息h1>
		<form action="updateAccountAction" method="post">
			<input type="hidden" name="aid" value="${account.aid }" />
			<table class="table table-hover">
				<tr class="info">
					<th>账户姓名:th>
					<td>
						<input class="form-control" type="text" name="aname" value="${account.aname }" required="required" placeholder="请输入账户姓名..." />
					td>
				tr>
				<tr class="danger">
					<th>账户金额th>
					<td>
						<input class="form-control" type="number" name="money" value="${account.money }" min="0.0" max="9999999.99" step="0.1" required="required" placeholder="请输入账户金额..." />
					td>
				tr>
				<tr class="warning">
					<th>开户日期th>
					<td>
						<input class="form-control" type="date" name="createDate" value="${account.createDate }" required="required" />
					td>
				tr>
				<tr class="active">
					<th colspan="2" style="text-align:center;">
						<button class="btn btn-success" type="submit">更新button>
						
						<button class="btn btn-danger" type="reset">取消button>
					th>
				tr>
			table>
		form>
	div>
body>
html>
  • error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>账户信息管理系统-错误title>
<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath }/css/bootstrap.min.css" />
<script type="text/javascript"
	src="${pageContext.request.contextPath }/js/jquery-1.9.1.js">script>
<script type="text/javascript"
	src="${pageContext.request.contextPath }/js/bootstrap.min.js">script>

head>
<body>
	<div class="jumbotron">
		<div class="container">
			<h1>ERRORh1>
			<p style="color: red; font-size: 30px;">
				${msg }
			p>
			<p>
				<a class="btn btn-info btn-lg" role="button" href="index.jsp">返回首页a>
			p>
		div>
	div>
body>
html>

9、后端控制器的编写

  • 分页查询
package com.gaj.web;

import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.gaj.pojo.Account;
import com.gaj.service.AccountService;

@Controller
public class AccountViewAction {
     
	
	@Autowired
	private AccountService service;

	@RequestMapping("/showAccountsAction")
	public ModelAndView showAccountsAction(
			@RequestParam(value = "pi", required = false, defaultValue = "1") Integer pageIndex) throws SQLException {
     
		// 创建方法的返回值
		ModelAndView mv = new ModelAndView();
		// 定义页容量大小
		int pageSize = 10; 
		// 计算记录总条数
		int totalCount = service.accountTotalCount();
		// 计算总页数
		int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
		// 判断索引边界值
		if(pageIndex < 1){
     
			pageIndex = 1; 
		}
		if(pageIndex > totalPage){
     
			pageIndex = totalPage;
		}
		// 获取分页数据
		List<Account> accounts = service.findAccountsByPage(pageIndex, pageSize);
		// 保存数据
		mv.addObject("pageSize", pageSize);
		mv.addObject("totalCount", totalCount);
		mv.addObject("totalPage", totalPage);
		mv.addObject("pageIndex", pageIndex);
		mv.addObject("accounts", accounts);
		// 转发到下一页
		mv.setViewName("forward:/account_list.jsp");
		// 返回
		return mv;
	}

}

  • 增删改操作
package com.gaj.web;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.gaj.pojo.Account;
import com.gaj.service.AccountService;

@Controller
public class AccountOperationAction {
     

	@Autowired
	private AccountService service;
	
	// 时间类型需要进行转换
	@InitBinder
	public void dateBinder(WebDataBinder binder){
     
		binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
	}
	
	@RequestMapping("/insertAccountAction")
	public ModelAndView insertAccountAction(Account account) throws SQLException{
     
		// 设置返回值
		ModelAndView mv = new ModelAndView();
		// 执行 需保证表单name与实体bean的属性一致
		int count = service.insertAccount(account);
		// 判断
		if (count > 0) {
     
			// 添加成功,重定向到showAccountsAction
			mv.setViewName("redirect:/showAccountsAction");
		} else {
     
			// 添加失败,将错误信息转发到error.jsp
			mv.addObject("msg", "很遗憾,添加失败了...");
			mv.setViewName("forward:/error.jsp");
		}
		// 返回
		return mv;
	}

	@RequestMapping("/deleteAccountAction")
	public ModelAndView deleteAccountAction(@RequestParam(value = "pi", required = true) Integer pageIndex)
			throws SQLException {
     
		// 设置返回值
		ModelAndView mv = new ModelAndView();
		// 查询是否有该数据
		Account account = service.findAccountById(pageIndex);
		// 判断
		if (account != null) {
     
			// 找到了该记录
			int count = service.deleteAccount(account);
			if (count > 0) {
     
				// 删除成功,重定向到showAccountsAction
				mv.setViewName("redirect:/showAccountsAction");
			} else {
     
				// 删除失败,将错误信息转发到error.jsp
				mv.addObject("msg", "很遗憾,删除失败了...");
				mv.setViewName("forward:/error.jsp");
			}
		} else {
     
			// 没找到记录
			// 删除失败,将错误信息转发到error.jsp
			mv.addObject("msg", "很遗憾,没有找到aid为" + pageIndex + "的记录...");
			mv.setViewName("forward:/error.jsp");
		}
		// 返回
		return mv;
	}
	
	@RequestMapping("/findAccountAction")
	public ModelAndView findAccountAction(
			@RequestParam(value = "pi", required = true)Integer pageIndex) throws SQLException{
     
		// 设置返回值
		ModelAndView mv = new ModelAndView();
		// 定位到这条数据
		Account account = service.findAccountById(pageIndex);
		// 判断
		if(account != null){
     
			// 保存对象
			mv.addObject("account", account);
			// 跳转到更新页面
			mv.setViewName("forward:/account_update.jsp");
		}else{
     
			// 没找到记录
			// 更新失败,将错误信息转发到error.jsp
			mv.addObject("msg", "很遗憾,没有找到aid为" + pageIndex + "的记录...");
			mv.setViewName("forward:/error.jsp");
		}
		// 返回
		return mv;
	}
	
	@RequestMapping("/updateAccountAction")
	public ModelAndView updateAccountAction(Account account) throws SQLException{
     
		// 设置返回值
		ModelAndView mv = new ModelAndView();
		// 执行
		int count = service.updateAccount(account);
		// 判断
		if(count > 0){
     
			// 更新成功
			mv.setViewName("redirect:/showAccountsAction");
		}else{
     
			// 更新失败
			mv.addObject("msg","很遗憾,更新失败了...");
			mv.setViewName("forward:/error.jsp");
		}
		// 返回
		return mv;
	}

}

10、前端控制器的编写

  • spring-mvc.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	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.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	
	<context:component-scan base-package="com.gaj.web" />

	
	<mvc:annotation-driven />
	
	
	<mvc:resources location="/js/" mapping="/js/**" />
	<mvc:resources location="/fonts/" mapping="/fonts/**" />
	<mvc:resources location="/css/" mapping="/css/**" />

beans>

11、web.xml的配置


<web-app 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_2_5.xsd"
	version="2.5">
	
	<display-name>springmvc_tp2display-name>
	
	
	<welcome-file-list>
		<welcome-file>index.jspwelcome-file>
	welcome-file-list>

	
	<context-param>
		<param-name>contextConfigLocationparam-name>
		<param-value>classpath:applicationContext.xmlparam-value>
	context-param>

	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
	listener>

	
	<servlet>
		<servlet-name>DispatcherServletservlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
		
		<init-param>
			<param-name>contextConfigLocationparam-name>
			<param-value>classpath:spring-mvc.xmlparam-value>
		init-param>
	servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServletservlet-name>
		
		<url-pattern>/url-pattern>
	servlet-mapping>

	
	<filter>
		<filter-name>EncodingFilterfilter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
		<init-param>
			<param-name>encodingparam-name>
			<param-value>UTF-8param-value>
		init-param>
	filter>
	<filter-mapping>
		<filter-name>EncodingFilterfilter-name>
		<url-pattern>/*url-pattern>
	filter-mapping>

	
	<filter>
		<filter-name>DruidWebStatFilterfilter-name>
		<filter-class>com.alibaba.druid.support.http.WebStatFilterfilter-class>
	filter>
	<filter-mapping>
		<filter-name>DruidWebStatFilterfilter-name>
		<url-pattern>/*url-pattern>
	filter-mapping>
	
	
	<servlet>
		<servlet-name>DruidStatViewservlet-name>
		<servlet-class>com.alibaba.druid.support.http.StatViewServletservlet-class>
		
		<init-param>
			
			<param-name>loginUsernameparam-name>
			<param-value>adminparam-value>
		init-param>
		<init-param>
			
			<param-name>loginPasswordparam-name>
			<param-value>adminparam-value>
		init-param>
	servlet>
	<servlet-mapping>
		<servlet-name>DruidStatViewservlet-name>
		<url-pattern>/druid/*url-pattern>
	servlet-mapping>

web-app>

三、知识点及总结

1、实体类包名的表示方式

com.xxx.domain:域;定义域
com.xxx.pojo:(Plain Ordinary Java Object)简单的java对象
com.xxx.entity:实体

2、监听器的配置

监听器是一个专门用于对其他对象身上发生的事件或状态的改变进行监听和相应处理的对象,当被监视的对象发生改变时就立即采取相应的行动。

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
	listener>
  • 监听器专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。
  • ContextLoaderListener的作用:在启动Web容器时,自动装配Spring applicationContext.xml的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。
  • 在ContextLoderListenner中关联了ContextLoader类,因此整个加载配置过程由ContextLoader来完成。

3、开启druid web监控

  • web.xml
	
	<servlet>
		<servlet-name>DruidStatViewservlet-name>
		<servlet-class>com.alibaba.druid.support.http.StatViewServletservlet-class>
		<init-param>
			
			<param-name>loginUsernameparam-name>
			<param-value>adminparam-value>
		init-param>
		<init-param>
			
			<param-name>loginPasswordparam-name>
			<param-value>adminparam-value>
		init-param>
	servlet>
	<servlet-mapping>
		<servlet-name>DruidStatViewservlet-name>
		<url-pattern>/druid/*url-pattern>
	servlet-mapping>
  • application.xml
    需要设置filters属性的值为stat
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/springdb?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="filters" value="stat" />
    bean>

4、引用Bootstrap样式没有显示

  • 原因:SpringMVC将请求CSS和JS的URL当成了request请求,这时没有能够处理这些个请求的后端控制器。
  • 解决:在SpringMVC配置静态文件,无需后端控制器处理

配置作用:DispatcherServlet不会拦截以/static开头的所有请求路径,并当作静态资源交由Servlet处理

	
	<mvc:resources location="/js/" mapping="/js/**" />
	<mvc:resources location="/fonts/" mapping="/fonts/**" />
	<mvc:resources location="/css/" mapping="/css/**" />

location元素表示webapp目录下的static包下的所有文件
mapping元素表示以/static开头的所有请求路径,如/static/a或/static/b

5、时间处理

jsp中date类型 -> http中string类型 -> java中date类型
需要在后端控制器中绑定自定义的格式

@InitBinder  
public void dateBinder(WebDataBinder binder) {
       
    binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));   //true:允许输入空值,false:不能为空值
}

6、属性对应

后端控制器中使用对象时,对象的属性需要与jsp中表单name一致,否则拿不到数据。

你可能感兴趣的:(小项目,Spring,JavaWeb,过滤器,java,spring)