9.SSD框架整合开发
9.1 业务需求
-
账户数据电子化管理小程序的开发
-
背景 : 公司决定对账户信息进行电子化管理,所以现在需要开发一个小程序用来管理用户信息
-
假设:
- 有springdb数据库一个,账户表一张,表结构如下:
- 账户表(account)
9.2 SQL初始化
SQL :
CREATE TABLE `account` (
`a_id` int(8) NOT NULL AUTO_INCREMENT,
`a_name` varchar(32) DEFAULT NULL,
`a_money` double DEFAULT NULL,
`a_createdate` date DEFAULT NULL,
PRIMARY KEY (`a_id`)
)
CREATE VIEW v1 AS
select a_id aid,a_name aname,a_money money,a_createdate createDate from account
- 要求:
-
一期项目 : 需要完成账户表的分页查询功能
-
二期项目 : 需要完成账户表的添加功能,删除功能
-
三期项目 : 需要完成账户表的修改功能
-
9.3 思路分析
根据我们编程的指导思想可知,如果你想完成表数据去页面展示及操作的愿望,那么你必须要明确的是:
- 首先你得有一个mavenweb项目
- 整理需要导入相应的jar包 (spring jar springmvc jar dbutils jar …)
- 根据需求整理相应的页面 (list.jsp add.jsp update.jsp)
- 根据需求完成相关功能的开发 (DAO SERVICE WEB)
- 配置配置文件整合框架完成功能(spring整合dbutils spring整合springmvc)
- 整体测试
9.4 UML例图
9.5 思维导图
9.6 初期:SSM整合
步奏 :
9.6.0 涉及技术
- Spring 5.0.2 --> 创建对象 对象的动态整合 (IOC DI) AOP (声明式事务) junit
- dbutis 1.6 --> DAO层数据的增 删 改 查 c3p0 mysql jar
- SpringMVC 5.0.2 --> WEB层页面控制 servlet jsp jstl
- bootstrap 3.3.5 --> 页面提供CSS支持
- jquery 1.9.1 --> 对页面的JS支持
1-5的技术知识点 其实都不强
9.6.1 maven项目的 pom.xml
记住 在导入jar包之前需要先设定好我们maven项目的初始化工作
<properties>
<!-- maven项目整体编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 项目编译的时候,源码(.java)使用哪个版本JDK -->
<maven.compiler.source>1.7</maven.compiler.source>
<!-- 项目编译的时候,可执行文件(.class)使用哪个版本JDK -->
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
涉及到的jar包 (以模块名展示):
1) Spring相关的
1. spring-context : Spring容器 (强大的团队 导入一个包 maven会把跟它相关联的包全部导入项目)
2. spring-webmvc : SpringMVC
-
SQL操作相关的
- dbutis
-
连接池相关
druid :
Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。
Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。 -
单元测试相关的
junit : 单元测试,与spring-test放一起做单元测试 -
ServletAPI相关的
jsp-api : jsp页面使用request等对象
servlet-api : java文件使用request等对象 -
数据库相关的
mysql-connector-java : mysql的数据库驱动包 -
页面表达式
JSTL : JSTL标签库必须jar包 基础功能
standard : JSTL标签库的必须jar包 进阶功能
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
9.6.2 实体类 Account
package com.hnxy.entity;
- 实体类 : 需要注意字段与属性不对称的问题
以后 实体类的包 会有以下几种命名规则
com.xxx.domain --> 域;定义域
com.xxx.pojo --> POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。
com.xxx.entity --> 实体; 实际存在物; 本质;
package com.hnxy.entity;
import java.util.Date;
/**
* 账户信息表
* 表对应类 字段对应属性
* 避开关键字命名
* @author My
*
*/
public class Account {
// 私有属性
private Integer aid; // 主键
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 + "]";
}
}
9.6.3 DAO 接口
DAO
package com.hnxy.dao;
import java.util.List;
import com.hnxy.entity.Account;
/**
* 账户表的SQL操作接口
* @author My
*
*/
public interface AccountDAO {
/**
* 添加
* @param account
* @return
* @throws Exception
*/
public int insertAccount(Account account)throws Exception;
/**
* 更新
* @param account
* @return
* @throws Exception
*/
public int updateAccount(Account account)throws Exception;
/**
* 删除
* @param account
* @return
* @throws Exception
*/
public int deleteAccount(Account account)throws Exception;
/**
* 根据ID查询
* @param id
* @return
* @throws Exception
*/
public Account findAccountByID(Integer id)throws Exception;
/**
* 分页
* @param start 每页的起始值 service (pageIndex-1)*pageSize pageIndex=页码 pageSize=页容量
* @param size 每页展示多少条 = service层的pageSize
* @return
* @throws Exception
*/
public List<Account> findAccountsByPage(Integer start,Integer size)throws Exception;
/**
* 获取总条数
* @return
* @throws Exception
*/
public int findAccountsByPageCount()throws Exception;
}
9.6.4 DAO impl实现类
package com.hnxy.dao.impl;
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.hnxy.dao.AccountDAO;
import com.hnxy.entity.Account;
@Repository
public class AccountDAOImpl implements AccountDAO {
@Autowired
private QueryRunner qr;
@Override
public int insertAccount(Account account) throws Exception {
// 创建方法的返回值
int count = 0;
// 创建SQL语句
String sql = "insert into account values (null,?,?,?)";
// 占位符赋值
Object[] params = {account.getAname(),account.getMoney(),account.getCreateDate()};
// 执行
count = qr.update(sql,params);
// 返回
return count;
}
@Override
public int updateAccount(Account account) throws Exception {
// 创建方法的返回值
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()};
// 执行
count = qr.update(sql,params);
// 返回
return count;
}
@Override
public int deleteAccount(Account account) throws Exception {
int count = 0;
String sql = "delete from account where a_id = ?";
Object[] params = {account.getAid()};
count = qr.update(sql, params);
return count;
}
@Override
public Account findAccountByID(Integer id) throws Exception {
// 创建方法的返回值
Account account = null;
// 编写SQL语句
String sql = "select * from v1 where aid = ?";
// 占位符赋值
Object[] params = {aid};
// 执行
account = qr.query(sql, new BeanHandler<Account>(Account.class),params);
// 返回
return account;
}
@Override
public List<Account> findAccountsByPage(Integer start, Integer size) throws Exception {
// 创建方法的返回值
List<Account> list = null;
// 编写SQL语句
String sql = "select * from v1 limit ?,?";
// 占位符赋值
Object[] params = {start,size};
// 执行
list = qr.query(sql, new BeanListHandler<Account>(Account.class),params);
// 返回
return list;
}
@Override
public int findAccountsByPageCount() throws Exception {
// 创建方法的返回值
int totalCount = 0;
// 编写SQL语句
String sql = "select count(*) from v1";
// 占位符赋值
// 执行
Number num = qr.query(sql, new ScalarHandler<Number>(1));
// 处理返回值
totalCount = num.intValue();
// 返回
return totalCount;
}
}
9.6.5 Service 接口
package com.hnxy.service;
import java.util.List;
import com.hnxy.entity.Account;
public interface AccountService {
/**
* 添加
* @param account
* @return
* @throws Exception
*/
public int insertAccount(Account account)throws Exception;
/**
* 更新
* @param account
* @return
* @throws Exception
*/
public int updateAccount(Account account)throws Exception;
/**
* 删除
* @param account
* @return
* @throws Exception
*/
public int deleteAccount(Account account)throws Exception;
/**
* 根据ID查询
* @param id
* @return
* @throws Exception
*/
public Account findAccountByID(Integer id)throws Exception;
/**
* 分页
* @param pageIndex 页码 第N页
* @param pageSize 页容量 每页展示N条数据
* @return
* @throws Exception
*/
public List<Account> findAccountsByPage(Integer pageIndex,Integer pageSize)throws Exception;
/**
* 获取总条数
* @return
* @throws Exception
*/
public int findAccountsByPageCount()throws Exception;
}
9.6.6 Service impl实现类
package com.hnxy.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import com.hnxy.dao.AccountDAO;
import com.hnxy.entity.Account;
import com.hnxy.service.AccountService;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDAO accountDAO;
@Override
public int insertAccount(Account account) throws Exception {
return accountDAO.insertAccount(account);
}
@Override
public int updateAccount(Account account) throws Exception {
return accountDAO.updateAccount(account);
}
@Override
public int deleteAccount(Account account) throws Exception {
return accountDAO.deleteAccount(account);
}
@Override
public Account findAccountByID(Integer id) throws Exception {
return accountDAO.findAccountByID(id);
}
@Override
public List<Account> findAccountsByPage(Integer pageIndex, Integer pageSize) throws Exception {
// 创建方法的返回值
List<Account> accounts = null;
// 业务判断 页码 页容量 必须不为空并且值必须大于0
if(null != pageIndex && null != pageSize){
if(pageIndex > 0 && pageSize > 0){
accounts = accountDAO.findAccountsByPage((pageIndex-1)*pageSize, pageSize);
}
}
// 返回
return accounts;
}
@Override
public int findAccountsByPageCount() throws Exception {
return accountDAO.findAccountsByPageCount();
}
}
9.6.7 Spring配置文件 applicatioContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
">
<!-- 1.配置注解Bean的包扫描器 -->
<context:component-scan base-package="*.*.dao" />
<context:component-scan base-package="*.*.service" />
<!-- 2.需要一个数据源对象 -->
<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" />
</bean>
<!-- 3.创建SQL的执行对象 -->
<bean id="qr" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<!-- 构造函数创建对象 -->
<constructor-arg name="ds" ref="dataSource" />
</bean>
</beans>
测试
在完成spring搭建后要及时进行连接性测试,确保底层ok在进行页面的搭建
package com.hnxy.test;
import java.util.Date;
import java.util.List;
import java.util.Random;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hnxy.entity.Account;
import com.hnxy.service.AccountService;
public class AccountTest {
// 1. 加载spring的配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 获取accountService
AccountService service = context.getBean(AccountService.class);
public void addTest()throws Exception{
// 为了分页 批量添加数据 100个
Account account = null;
Random random = new Random();
int count = 0;
for (int i = 1; i <= 100; i++) {
account = new Account();
account.setAname("账户"+i);
account.setMoney(random.nextInt(50000)+0D);
account.setCreateDate(new Date());
// 执行添加
count = service.insertAccount(account);
System.out.println(count);
}
}
public void updateTest()throws Exception{
// 修改id为8的用户 金额为当前金额+1000
// 先查询
Account account = service.findAccountByID(8);
// 再更新
if(null != account){
account.setMoney(account.getMoney()+1000);
int count = service.updateAccount(account);
System.out.println(count);
}
}
public void deleteTest()throws Exception{
// 删除ID为81的用户信息
// 先查询
Account account = service.findAccountByID(81);
// 再删除
if(null != account){
int count = service.deleteAccount(account);
System.out.println(count);
}
}
@Test
public void queryTest()throws Exception{
// 分页测试 展示第一页的数据 每页展示10条
int pageIndex = 2;
int pageSize = 10;
int totalCount = service.findAccountsByPageCount();
int totalPage = totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1;
System.out.println("一共查询出"+totalCount+"条数据");
System.out.println("每页展示" + pageSize + "条");
System.out.println("一共分" + totalPage + "页");
System.out.println("当前为第"+pageIndex+"页");
// 获取分页数据
List<Account> accounts = service.findAccountsByPage(pageIndex, pageSize);
// 循环
for (Account account : accounts) {
System.out.println(account);
}
}
}
9.6.7 SpringMVC配置文件 spring-core.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 配置注解bean的包扫描器 -->
<context:component-scan base-package="*.*.web" />
<!-- 开启SpringMVC的注解配置 -->
<mvc:annotation-driven />
</beans>
9.6.8 web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 配置欢迎页面 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 加载Spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置SpringWEB监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 中文乱码过滤器 -->
<filter>
<filter-name>EncodingFilter</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>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- druid过滤器 -->
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- SpringMVC的核心Servlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!-- 拦截规则是/匹配所有的请求,过滤器是/* -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- druid的核心Servlet -->
<!-- 配置 Druid 监控信息显示页面 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>admin123</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
</web-app>
别看WEB.xml中配置的东西比较多,但是都是固定配置,以后用的时候直接复制粘贴即可,也就是以后我们有三个配置文件是以素材的形式提供给大家,不用大家记忆的
- spring配置文件applicationContext.xml
- springMVC配置文件 spring-mvc.xml
- web项目配置文件 web.xml
监听器:
监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。
监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。
ContextLoaderListener
作用:在启动Web 容器时,自动装配Spring applicationContext.xml 的配置信息。
因为它实现了ServletContextListener 这个接口,在web.xml 配置这个监听器,启动容器时,就会默认执行它实现的方法。
在ContextLoaderListener 中关联了ContextLoader 这个类,所以整个加载配置过程由ContextLoader 来完成;
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
9.7 SSD框架功能实现
9.7.1 系统首页
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>账户信息管理系统-系统首页</title>
<!-- 引入 CSS样式 和 JS脚本 -->
<!-- 引入bootstrap的样式 -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
<!-- 引入JS JS的引入一定是双标签 并且 不管写什么 jquery肯定是第一个引入 -->
<script src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<script type="text/javascript">
function showPage(){
// JS中发起request请求
window.location.href = "${pageContext.request.contextPath}/findAccountByPage";
}
function goAdd(){
// JS中发起request请求
window.location.href = "${pageContext.request.contextPath}/account_add.jsp";
}
</script>
</head>
<body>
<div class="jumbotron">
<div class="container">
<h1>欢迎使用账户信息管理系统!</h1>
<p>请选择您要操作的功能 : </p>
<p>
<a class="btn btn-primary btn-lg" role="button" onclick="showPage();">查询账户信息</a>
<a class="btn btn-success btn-lg" role="button" onclick="goAdd();">添加新账户</a>
</p>
</div>
</div>
</body>
</html>
没有样式,看下控制台
没有样式的原因是SpringMVC把我们请求CSS和JS的URL当成了request请求,这时我们又没有能够处理这些个请求的后端控制器(为啥没有,因为这根本就不是业务请求啊)
所以此时如果你希望能正常访问你的这些个CSS和JS文件,你就需要告诉SpringMVC 这些呀都是静态文件,不是业务请求的URL,那么问题来了你怎么告诉SpringMVC呢?
在springMVC的配置文件里加入
<!-- 设置哪些请求是在请求静态文件不需要后端控制器处理 -->
<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/a/b;
该配置的作用是:DispatcherServlet不会拦截以/static开头的所有请求路径,并当作静态资源
交由Servlet处理。
从新启动服务器观察页面效果
js/jquery/jquery-1.9.1.js /js/** js文件夹以及子文件夹的所有请求
js/jquery-1.9.1.js /js/* js文件中的所有文件
后端控制器中findAccountsByPage部分
首页效果完成之后我们根据首页的显示账户信息的URL请求编写后端控制器代码
@RequestMapping("/findAccountsByPage")
public ModelAndView findAccountsByPage(@RequestParam(value="pageIndex",required=false,defaultValue="1") Integer pageIndex)throws Exception{
// 创建方法的返回值 又能存储数据 又能设定转发与重定向
ModelAndView mv = new ModelAndView();
// 定义其他三个变量
int pageSize = 10;
int totalCount = service.findAccountsByPageCount();
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("pageIndex", pageIndex);
mv.addObject("pageSize",pageSize);
mv.addObject("totalCount", totalCount);
mv.addObject("totalPage", totalPage);
mv.addObject("accounts", accounts);
// 设定转发
mv.setViewName("forward:/account_list.jsp");
// 返回
return mv;
}
分页页面
<%@ 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="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>展示数据</title>
<!-- 引入CSS与JS样式 -->
<link rel="stylesheet" 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>
<h1>展示账户信息</h1>
<table class="table table-hover">
<tr class="active">
<td colspan="5">
一共查询出${totalCount}条数据,每页展示${pageSize}条,一共有${totalPage}页,当前为第${pageIndex}页
</td>
</tr>
<tr class="info">
<th>账户编号</th>
<th>账户姓名</th>
<th>账户余额</th>
<th>开户时间</th>
<th>操作</th>
</tr>
<c:forEach var="a" items="${accounts}">
<tr>
<td>${a.aid}</td>
<td>${a.aname}</td>
<td>
<fmt:formatNumber type="currency" value="${a.money}" />
</td>
<td>
<fmt:formatDate value="${a.createDate}" pattern="yyyy-MM-dd"/>
</td>
<td>
<button class="btn btn-warning" type="button" onclick="goUpdate(${a.aid})">更新</button>
<button class="btn btn-danger" type="button" onclick="goDelete(${a.aid})">删除</button>
</td>
</tr>
</c:forEach>
<tr>
<th colspan="5" style="text-align: center;">
<button type="button" class="btn btn-default" onclick="goPage(1);">首页</button>
<!-- 业务 第一页 不能点击上一页 最后一页不能点击下一页 -->
<c:choose>
<c:when test="${pageIndex > 1}">
<button type="button" class="btn btn-default" onclick="goPage(${pageIndex-1});">上一页</button>
</c:when>
<c:otherwise>
<button type="button" class="btn btn-default" disabled="disabled">上一页</button>
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${totalPage > pageIndex}">
<button type="button" class="btn btn-default" onclick="goPage(${pageIndex+1});">下一页</button>
</c:when>
<c:otherwise>
<button type="button" class="btn btn-default" disabled="disabled">下一页</button>
</c:otherwise>
</c:choose>
<button type="button" class="btn btn-default" onclick="goPage(${totalPage});">末页</button>
</th>
</tr>
</table>
</div>
</body>
</html>
分页JS
<script type="text/javascript">
// 分页方法
function goPage(pageIndex){
window.location.href = "${pageContext.request.contextPath}/findAccountsByPage?pageIndex="+pageIndex;
}
</script>
9.7.2 页面添加
添加页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>系统首页</title>
<!-- 引入CSS与JS样式 -->
<link rel="stylesheet" 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>
<h1>添加新账户</h1>
<form action="insertAccount">
<table class="table table-hover">
<tr>
<td>请输入账户名称:</td>
<td>
<input type="text" class="form-control" required="required" placeholder="请输入账户姓名..." name="aname" />
</td>
</tr>
<tr>
<td>请输入账户余额:</td>
<td>
<input type="number" class="form-control" required="required" placeholder="请输入账户余额..." name="money" />
</td>
</tr>
<tr>
<td>请选择开户日期:</td>
<td>
<input type="date" class="form-control" required="required" name="createDate" />
</td>
</tr>
<tr>
<th colspan="2" style="text-align: center;">
<button type="submit" class="btn btn-success">确定</button>
<button type="reset" class="btn btn-danger" onclick="javascript:history.go(-1);">取消</button>
</th>
</tr>
</table>
</form>
</div>
</body>
</html>
后端控制器
package com.hnxy.web;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.annotation.Scope;
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.servlet.ModelAndView;
import com.hnxy.entity.Account;
import com.hnxy.service.AccountService;
/**
* 专门做添加 修改 删除的处理
* @author My
*
*/
@Controller
public class AccountOperateAction {
@Autowired
private AccountService service;
@RequestMapping("/insertAccount")
public ModelAndView insertAccount(Account account)throws Exception{
// 创建方法的返回值
ModelAndView mv = new ModelAndView();
// 调用SERVICE
int count = service.insertAccount(account);
// 根据执行结果进行页面的操作
if(count > 0){
// 重新刷新分页集合
mv.setViewName("redirect:/findAccountsByPage");
}else{
mv.addObject("errormsg", "很遗憾,添加失败了!");
mv.setViewName("forward:/error.jsp");
}
// 返回
return mv;
}
}
时间类型转换
@InitBinder
public void dateBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); //true:允许输入空值,false:不能为空值
}
注意,我们每次修改java文件后一定要重启一下tomcat服务器,要不然会出现不编译的情况;
编写错误提示页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>系统首页</title>
<!-- 引入CSS与JS样式 -->
<link rel="stylesheet" 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 style="color: red;">${errormsg}</p>
<p><a class="btn btn-primary btn-lg" role="button" href="${pageContext.request.contextPath}/index.jsp">返回首页</a></p>
</div>
</div>
</body>
</html>
9.7.3 页面删除
页面的JS
// 删除功能
function goDelete(id){
var con = window.confirm("确定要删除这条数据么?");
if(con){
window.location.href = "${pageContext.request.contextPath}/deleteAccount?id="+id;
}
}
执行的方法
@RequestMapping("/deleteAccount")
public ModelAndView deleteAccount(Integer id)throws Exception{
// 创建方法的返回值
ModelAndView mv = new ModelAndView();
Account account = service.findAccountByID(id);
if(null != account){
// 调用SERVICE
int count = service.deleteAccount(account);
// 根据执行结果进行页面的操作
if(count > 0){
// 重新刷新分页集合
mv.setViewName("redirect:/findAccountsByPage");
}else{
mv.addObject("errormsg", "很遗憾,删除失败了!");
mv.setViewName("forward:/error.jsp");
}
}else{
mv.addObject("errormsg", "很遗憾,没有找到要删除数据!");
mv.setViewName("forward:/error.jsp");
}
// 返回
return mv;
}
9.7.4 页面更新
更新JS
// 更新账户信息
function goUpdate(id){
window.location.href = "${pageContext.request.contextPath}/findAccountByID?id="+id;
}
后端控制器
@RequestMapping("/findAccountByID")
public ModelAndView findAccountByID(Integer id)throws Exception{
// 创建方法的返回值
ModelAndView mv = new ModelAndView();
// 获取数据
Account account = service.findAccountByID(id);
// 保存数据
mv.addObject("a", account);
// 设置转发地址
mv.setViewName("forward:/account_update.jsp");
// 返回
return mv;
}
更新页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>系统首页</title>
<!-- 引入CSS与JS样式 -->
<link rel="stylesheet" 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>
<h1>更新账户信息</h1>
<form action="updateAccount" method="post">
<input type="hidden" value="${a.aid}" name="aid" />
<table class="table table-hover">
<tr>
<td>请输入账户名称:</td>
<td>
<input type="text" value="${a.aname}" class="form-control" required="required" placeholder="请输入账户姓名..." name="aname" />
</td>
</tr>
<tr>
<td>请输入账户余额:</td>
<td>
<input type="number" value="${a.money}" class="form-control" required="required" placeholder="请输入账户余额..." name="money" />
</td>
</tr>
<tr>
<td>请选择开户日期:</td>
<td>
<input type="date" value="${a.createDate}" class="form-control" required="required" name="createDate" />
</td>
</tr>
<tr>
<th colspan="2" style="text-align: center;">
<button type="submit" class="btn btn-success">确定</button>
<button type="reset" class="btn btn-danger" onclick="javascript:history.go(-1);">取消</button>
</th>
</tr>
</table>
</form>
</div>
</body>
</html>
执行方法
@RequestMapping("/updateAccount")
public ModelAndView updateAccount(Account account) throws Exception {
// 创建方法的返回值
ModelAndView mv = new ModelAndView();
// 如果页面通过特殊编译技术拼接一些没有ID或者ID不存在的数据我们就不让它修改了
Account a = service.findAccountByID(account.getAid());
if (null != a) {
// 正常更新
// 调用SERVICE
int count = service.updateAccount(account);
// 根据执行结果进行页面的操作
if (count > 0) {
// 重新刷新分页集合
mv.setViewName("redirect:/findAccountsByPage");
} else {
mv.addObject("errormsg", "很遗憾,更新失败了!");
mv.setViewName("forward:/error.jsp");
}
} else {
mv.addObject("errormsg", "很遗憾,没有找到要更新数据!");
mv.setViewName("forward:/error.jsp");
}
// 返回
return mv;
}
到此SSD的整合开发完成!