1. SSM整合
流程:
- 数据库:
- 实例:ssm?charset=utf8mb4
- 账密:ssm@localhost/ssm
- 依赖:
- mybatis/mysql-connector-java/commons-dbcp2
- spring-webmvc/spring-aspects/spring-jdbc
- log4j-core/log4j/slf4j-api/slf4j-log4j12
- lombok/junit/spring-test/mybatis-spring
- jackson-databind/jackson-annotations
- 开发log4j日志属性文件。
- 开发工具包:分页工具等。
- 开发orm实体类。
- 添加视图框架:jquery,bootstrap等。
源码: /ssm/
- src:
webapp/bootstrap337 - web:
webapp/jquery321 - res:
pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<mybatis>3.4.6</mybatis>
<spring>4.3.14.RELEASE</spring>
<mybatis-spring>1.3.0</mybatis-spring>
</properties>
<dependencies>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis}</version>
</dependency>
<!--mysql-connector-java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
<scope>runtime</scope>
</dependency>
<!--commons-dbcp2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<!--spring-webmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring}</version>
</dependency>
<!--spring-aspects-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring}</version>
</dependency>
<!--spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring}</version>
</dependency>
<!--log4j-core-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.3</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--slf4j-api-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--slf4j-log4j12-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<optional>true</optional>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--spring-test-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring}</version>
</dependency>
<!--mybatis-spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring}</version>
</dependency>
<!--jackson-annotations-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.7</version>
</dependency>
<!--jackson-databind-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.7</version>
</dependency>
</dependencies>
- res:
README.md
## url
- cli: `http://locahost:8080/ssm`
## database
- cmd: `mysql -uroot -p`
- cmd: `root`
- cmd: `create database ssm character set utf8mb4;`
- cmd: `use ssm;`
- cmd: `grant all on ssm.* to 'ssm'@'localhost' identified by 'ssm';`
- cmd: `flush privileges;`
- res:
ssm.sql
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(
`id` int(11) PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '姓名',
`age` int(3) DEFAULT NULL COMMENT '年龄',
`gender` tinyint(2) DEFAULT NULL COMMENT '性别'
) AUTO_INCREMENT = 21 COMMENT '用户表';
INSERT INTO `user`
VALUES (1, '赵四', 18, 1),
(2, '刘能', 37, 1),
(3, '赵玉田', 37, 1),
(4, '刘英', 38, 0),
(5, '王天来', 39, 1),
(6, '王云', 41, 0),
(7, '刘志', 42, 1),
(8, '王大拿', 43, 1),
(9, '王木生', 44, 1),
(10, '宋晓峰', 45, 1),
(11, '瓶底子', 46, 1),
(12, '豁牙子', 47, 1),
(13, '王小蒙', 47, 0),
(14, '王老七', 48, 1),
(15, '宋富贵', 49, 1),
(16, '谢飞机', 12, 1),
(17, '谢广坤', 45, 1),
(18, '谢永强', 47, 1),
(19, '皮长山', 22, 1),
(20, '小梁', 28, 1);
COMMIT;
- res:
classpath:mybatis/db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
jdbc.username=ssm
jdbc.password=ssm
jdbc.initialSize=0
jdbc.maxIdle=20
jdbc.minIdle=1
jdbc.maxWaitMillis=60000
- res:
classpath:log4j.properties
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
- src:
c.y.pojo.User
package com.yap.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author yap
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Integer id;
private String name;
private Integer age;
private Integer gender;
}
- src:
c.y.util.PagingUtil
package com.yap.util;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @Author Yap
*/
@Data
public class PageUtil implements Serializable {
/**
* 每页条目数,当前页,总页数,总条目数
*/
private Integer size, page, pages, total;
/**
* 页面数字排列
*/
private List<String> pageList;
/**
* 构造分页工具类时,若不指定参数,则默认为显示第1页,每页显示5条
*/
public PageUtil() {
this("1", "5");
}
/**
* 构造分页工具类时,可以指定当前页码和每页条目数,为方便控制层调用,参数皆为String类型
*
* @param page 当前显示第几页
* @param size 每页显示多少条
*/
public PageUtil(String page, String size) {
try {
int realPage = Integer.parseInt(page);
int realSize = Integer.parseInt(size);
if (realPage > 0 && realSize > 0) {
this.page = realPage;
this.size = realSize;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 构建并返回MySQL分页查询中,limit的第一个参数
*
* @return MySQL分页查询中,limit的第一个参数
*/
public int getLimitParam1() {
return (this.page - 1) * size;
}
/**
* 构建并返回MySQL分页查询中,limit的第二个参数
*
* @return MySQL分页查询中,limit的第二个参数
*/
public int getLimitParam2() {
return this.size;
}
/**
* 构建并返回MySQL分页查询中,完整的limit语句
*
* @return MySQL分页查询中,完整的limit语句
*/
public String getLimitSuffix() {
return " LIMIT " + getLimitParam1() + ", " + getLimitParam2();
}
/**
* 设置总条目数,同时计算出总页数
*
* @param total 总条目数
*/
public void buildTotalAndPages(int total) {
this.total = total;
double size = this.size;
this.pages = (int) Math.ceil(total / size);
}
/**
* 构建页面数字排列
*/
public void buildPageList() {
pageList = new ArrayList<>();
// 当总页数大于2时,前2个数字 ["1"] 和 ["2"] 是固定必有的
int constLength = 2;
// 数字排列中不确定的数字最多不超过5个
int varLength = 5;
// 数字排列中所有数字一共最多不超过7个
int maxLength = 7;
// 总页数至少为1,所以 ["1"] 一定存在
pageList.add("1");
// 总页数大于1时,["2"] 一定存在
if (pages > 1) {
pageList.add("2");
// 当前页码小于等于5时:["1"] ["2"] ["3"] ["4"] ["5"]
if (page <= varLength) {
// 生成 ["2"] 之后的数字排列,超出总页数部分不生成,且最多5个
for (int i = constLength; i < maxLength && i < pages; i++) {
pageList.add(i + 1 + "");
}
// 总页数大于7时,末尾添加 ["..."]
if (pages > maxLength) {
pageList.add("...");
}
} else {
// 当前页大于5时:["1"] ["2"] [...] ["3"] ["4"] ["5"]
pageList.add("...");
// 在当前页左右两侧各生成2个数字排列,超出总页数的部分不创建,加上自己一共5个
for (int i = -constLength; i <= constLength && page + i <= pages; i++) {
pageList.add(page + i + "");
}
// 总页数大于7,且当前页右边还有2个以上的元素的时候,生成第二个 [...]
if (pages > maxLength && page < pages - constLength) {
pageList.add("...");
}
}
}
}
}
2. 数据层
流程:
- 开发数据源属性文件。
- 开发mybatis主配文件:仅配置实体类别名。
- 开发mapper接口:分页查询,按主键查,新增,按主键修改,批量删除,查总条目数。
- 开发SQL配置文件:和mapper接口四大对应。
- 开发mapper层的spring管理文件:
- 管理
o.s.b.f.c.PropertyPlaceholderConfigurer并注入属性文件。 - 管理
o.a.c.d.BasicDataSource并注入dbcp连接池属性相关配置。 - 管理
o.m.s.SqlSessionFactoryBean并注入数据源,mybatis主配文件和SQL配置文件。 - 管理
o.m.s.m.MapperScannerConfigurer并包扫描mapper接口。
- 管理
- 测试mapper接口。
源码: /ssm/
- res:
classpath:mybatis/mybatis.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC
"-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.yap.pojo"/>
</typeAliases>
</configuration>
- res:
classpath:mybatis/mapper/UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yap.mapper.UserMapper">
<sql id="*">
`id`, `name`, `age`, `gender`
</sql>
<select id="findById" resultType="user">
SELECT
<include refid="*"/>
FROM `user`
WHERE `id` = #{id}
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into user (id, name, age, gender)
values (#{id}, #{name}, #{age}, #{gender});
</insert>
<delete id="deleteByIds">
delete
from user
where
<foreach item="e" collection="array" open=" id in (" separator="," close=")">
${e}
</foreach>
</delete>
<update id="updateById">
update user
<set>
<if test='name != null'>`name` = #{name},</if>
<if test='age != null'>`age` = #{age},</if>
<if test='gender != null'>`gender` = #{gender},</if>
</set>
<where>
id = #{id}
</where>
</update>
<select id="paging" resultType="user">
select
<include refid="*"/>
from user ${value}
</select>
<select id="count" resultType="_int">
select count('id')
from `user`
</select>
</mapper>
- res:
classpath:spring/spring-mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--注入属性文件-->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:mybatis/db.properties"/>
</bean>
<!--数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="initialSize" value="${jdbc.initialSize}"/>
<property name="maxIdle" value="${jdbc.maxIdle}"/>
<property name="minIdle" value="${jdbc.minIdle}"/>
<property name="maxWaitMillis" value="${jdbc.maxWaitMillis}"/>
</bean>
<!--Session工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis/mybatis.xml"/>
<property name="mapperLocations" value="classpath:mybatis/mapper/*Mapper.xml"/>
</bean>
<!--Mapper接口包扫描-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yap.mapper"/>
</bean>
</beans>
- src:
c.y.mapper.UserMapper
package com.yap.mapper;
import com.yap.pojo.User;
import java.util.List;
/**
* @author yap
*/
public interface UserMapper {
/**
* 根据主键查询用户信息
*
* @param id 主键
* @return 单条用户信息
*/
User findById(Integer id);
/**
* 添加一条用户信息
*
* @param user 用户实体
*/
void insert(User user);
/**
* 批量删除
*
* @param ids 主键
*/
void deleteByIds(Integer[] ids);
/**
* 通过主键修改一条信息
*
* @param user 用户实体
*/
void updateById(User user);
/**
* 分页查询用户信息
*
* @param limitSuffix SQL分页后缀
* @return 用户信息
*/
List<User> paging(String limitSuffix);
/**
* 查询一共有多少数据
*
* @return 数据数量
*/
int count();
}
- tst:
c.y.mapper.UsetMapperTest
package com.yap.mapper;
import com.yap.pojo.User;
import com.yap.util.PageUtil;
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;
/**
* @Author Yap
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring-*.xml")
public class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void findById() {
System.out.println(userMapper.findById(1));
}
@Test
public void insert() {
userMapper.insert(new User(null, "aaaa", 1, 1));
}
@Test
public void deleteById() {
Integer[] array = {23, 24};
userMapper.deleteByIds(array);
}
@Test
public void updateById() {
userMapper.updateById(new User(21, "ss", 1, 1));
}
@Test
public void paging() {
System.out.println(userMapper.paging(new PageUtil("1", "5").getLimitSuffix()));
}
@Test
public void count() {
System.out.println(userMapper.count());
}
}
3. 业务层
流程:
- 开发业务层接口和实现类,并交给spring管理。
- 开发service层的spring管理文件:
- 使用
<context:component-scan />包扫描@Component。 - 使用
<tx:annotation-driven />开启事务注解驱动并引用事务管理器。 - 管理
o.s.j.d.DataSourceTransactionManager事务管理器并注入数据源。
- 使用
- 测试service接口。
源码: /ssm/
- res:
classpath:spring/spring-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.yap.service"/>
<!--开启事务注解驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--注册事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- src:
c.y.service.UserService
package com.yap.service;
import com.yap.pojo.User;
import com.yap.util.PageUtil;
import java.util.List;
/**
* @Author Yap
*/
public interface UserService {
/**
* 根据主键查询用户信息
*
* @param id 主键
* @return 单条用户信息
*/
User findById(Integer id);
/**
* 添加一条用户信息
*
* @param user 用户实体
*/
void insert(User user);
/**
* 批量删除
*
* @param ids 主键
*/
void deleteByIds(Integer[] ids);
/**
* 通过主键修改一条信息
*
* @param user 用户实体
*/
void updateById(User user);
/**
* 分页查询
*
* @param pageUtil 分页工具类
* @return 查询集合
*/
List<User> paging(PageUtil pageUtil);
}
- src:
c.y.service.impl.UserServiceImpl
package com.yap.service.impl;
import com.yap.mapper.UserMapper;
import com.yap.pojo.User;
import com.yap.service.UserService;
import com.yap.util.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* @Author Yap
*/
@Service
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
@Autowired
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public User findById(Integer id) {
if (id < 0) {
return new User();
}
return userMapper.findById(1);
}
@Transactional(rollbackForClassName = "Exception")
@Override
public void insert(User user) {
if (user != null) {
userMapper.insert(user);
}
}
@Transactional(rollbackForClassName = "Exception")
@Override
public void deleteByIds(Integer[] ids) {
if (ids != null && ids.length != 0) {
for (Integer id : ids) {
if (id == null) {
throw new NullPointerException("ids中有元素为null");
}
// test @Transactional
// throw new RuntimeException("exception and rollback...");
}
}
userMapper.deleteByIds(ids);
}
@Transactional(rollbackForClassName = "Exception")
@Override
public void updateById(User user) {
if (user != null) {
userMapper.updateById(user);
}
}
@Override
public List<User> paging(PageUtil pageUtil) {
if (pageUtil == null) {
return new ArrayList<>();
}
if (pageUtil.getLimitSuffix() == null || "".equals(pageUtil.getLimitSuffix())) {
return new ArrayList<>();
}
pageUtil.buildTotalAndPages(userMapper.count());
pageUtil.buildPageList();
return userMapper.paging(pageUtil.getLimitSuffix());
}
}
- tst:
c.y.service.UserServiceTest
package com.yap.service;
import com.yap.pojo.User;
import com.yap.util.PageUtil;
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;
/**
* @Author Yap
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring-*.xml")
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void paging() {
PageUtil pageUtil = new PageUtil("1", "5");
System.out.println(userService.paging(pageUtil));
System.out.println(pageUtil);
}
@Test
public void findById() {
System.out.println(userService.findById(10));
}
@Test
public void insert() {
userService.insert(new User(null,"aaa",1,1));
}
@Test
public void updateById() {
userService.updateById(new User(22,"aaaaaa",1,1));
}
@Test
public void deleteById() {
Integer[] ids = {27,28};
userService.deleteByIds(ids);
}
}
4. 控制层
流程:
- 开发控制层动作类,并交给spring管理。
- 开发controller层的spring管理文件:
- 使用
<context:component-scan />包扫描@Component。 - 使用
<mvc:annotation-driven />开启注解驱动。 - 管理
o.s.w.s.v.InternalResourceViewResolver视图解析器并注入前后缀。
- 使用
- 在web.xml中配置tomcat启动信息:
- 使用
<context-param>的contextConfigLocation键配置服务启动加载spring。 - 配置
o.s.w.f.CharacterEncodingFilter过滤器。 - 配置
o.s.w.c.ContextLoaderListener监听器。 - 配置
o.s.w.s.DispatcherServlet核心控制器。
- 使用
- 测试controller路由。
源码: /ssm/
- res:
classpath:spring/spring-controller.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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--component扫描-->
<context:component-scan base-package="com.yap.controller"/>
<!--注解驱动-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/view/html/"/>
<property name="suffix" value=".html"/>
</bean>
</beans>
- src:
c.y.controller.UserController
package com.yap.controller;
import com.yap.pojo.User;
import com.yap.service.UserService;
import com.yap.util.JsonData;
import com.yap.util.PageUtil;
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.ResponseBody;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author Yap
*/
@RequestMapping("/api/user")
@Controller
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("paging")
@ResponseBody
public JsonData paging(PageUtil pageUtil) {
List<User> users = userService.paging(pageUtil);
if (users.isEmpty()) {
return new JsonData(500, "data empty!");
} else {
Map<String, Object> result = new HashMap<>(2);
result.put("users", users);
result.put("pageUtil", pageUtil);
return new JsonData(result);
}
}
@RequestMapping("find-by-id")
@ResponseBody
public JsonData findById(Integer id) {
return new JsonData(userService.findById(id));
}
@ResponseBody
@RequestMapping("insert")
public JsonData insert(User user) {
userService.insert(user);
return new JsonData(200, "ok");
}
@ResponseBody
@RequestMapping("delete-by-ids")
public JsonData deleteByIds(Integer[] ids) {
userService.deleteByIds(ids);
return new JsonData(200, "ok");
}
@ResponseBody
@RequestMapping("update-by-id")
public JsonData updateById(User user) {
userService.updateById(user);
return new JsonData(200, "ok");
}
}
5. 视图层
源码: /ssm/
- web:
view/html/user/user.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>login</title>
<base href="/z9/">
<link href="bootstrap337/css/bootstrap.min.css" rel="stylesheet">
<link href="view/style/user/user.css" rel="stylesheet">
</head>
<body>
<section class="operation-sec">
<article class="pull-left">
<button id="insert-btn" class="btn btn-info" type="button">添加</button>
<button id="delete-btn" class="btn btn-danger" type="button">批量删除</button>
</article>
<label class="pull-right">
<select id="paging-size-sel" class="form-control">
<option value="1">1条数据 / 页</option>
<option value="5">5条数据 / 页</option>
<option value="10">10条数据 / 页</option>
</select>
</label>
</section>
<section id="user-list-sec">
<form id="delete-form">
<table id="user-list-tab" class="table table-condensed table-striped table-hover">
<thead id="user-list-thead"></thead>
<tbody id="user-list-tbody"></tbody>
</table>
</form>
</section>
<section class="paging-sec">
<ol id="paging-numbers-ol" class="pagination"></ol>
</section>
<script src="jquery321/jquery-3.2.1.min.js"></script>
<script src="bootstrap337/js/bootstrap.min.js"></script>
<script src="view/script/user/user.js"></script>
</body>
</html>
- web:
view/style/user/user.js
const APP_NAME = "/z9";
let pagingSizeSel;
let pagingNumbersOl;
let page, size, total, pages, numbers;
$(() => {
pagingSizeSel = $("#paging-size-sel").change(() => changePagingSize());
$("#delete-btn").click(() => {
if (confirm("确认删除吗?")) {
deleteByIds();
}
});
$("#insert-btn").click(() => insert());
paging(1, 5);
});
function insert() {
location.href = `${APP_NAME}/view/html/user/user-insert.html`
}
function changePagingSize() {
paging(1, pagingSizeSel.val())
}
function deleteByIds() {
$.ajax({
"url": `${APP_NAME}/api/user/delete-by-ids`,
"type": "post",
"data": $("#delete-form").serialize(),
"success": response => {
alert(response["msg"]);
if (response["status"] === 200) {
location.href = `${APP_NAME}/view/html/user/user.html`;
}
}
});
}
function paging(page, size) {
$.ajax({
"url": `${APP_NAME}/api/user/paging`,
"type": "post",
"data": {"page": page, "size": size},
"success": response => {
if (response["status"] === 200) {
renderTable(response["data"]["users"]);
renderPaging(response["data"]["pageUtil"]);
} else {
alert(response["msa"]);
}
}
});
}
function renderTable(users) {
buildTHead();
let userListTbody = $("#user-list-tbody").html("");
$.each(users, (i, v) => {
let tr = $("<tr></tr>").appendTo(userListTbody);
$(`<td><label><input name="ids" type="checkbox" value='${v["id"]}'/></td></label>`).appendTo(tr);
$(`<td>${i + 1}</td>`).appendTo(tr);
$(`<td>${v["name"] !== undefined ? v["name"] : ""}</td>`).appendTo(tr);
$(`<td>${v["age"] !== undefined ? v["age"] : ""}</td>`).appendTo(tr);
$(`<td>${v["gender"] === 1 ? "男" : v["gender"] === 0 ? "女" : v["gender"] === 2 ? "保密" : ""}</td>`).appendTo(tr);
let updateTd = $(`<td></td>`).appendTo(tr);
let updateBtn = $(`<a href="javascript:" >修改</a>`);
updateBtn.click(() => {
sessionStorage.setItem("id", v["id"]);
location.href = `${APP_NAME}/view/html/user/user-update.html`;
}).appendTo(updateTd);
});
}
function buildTHead() {
let userListTHead = $("#user-list-thead").html("");
let headTr = $(`<tr></tr>`).appendTo(userListTHead);
$(`<th><label><input id="select-all-cbx" type="checkbox"/></label></th>`).appendTo(headTr);
$(`<th>序号</th>`).appendTo(headTr);
$(`<th>姓名</th>`).appendTo(headTr);
$(`<th>年龄</th>`).appendTo(headTr);
$(`<th>性别</th>`).appendTo(headTr);
$(`<th>操作</th>`).appendTo(headTr);
}
function renderPaging(pageUtil) {
page = parseInt(pageUtil["page"]);
size = parseInt(pageUtil["size"]);
pages = parseInt(pageUtil["pages"]);
total = parseInt(pageUtil["total"]);
numbers = pageUtil["pageList"];
pagingNumbersOl = $("#paging-numbers-ol").html("");
renderPrevAndFirstBtn();
renderNumbers();
renderLastAndNextBtn();
renderPagingMessage();
updatePagingSize();
}
function renderPrevAndFirstBtn() {
if (page === 1) {
$(`<li class="disabled"><a>«</a></li>`).appendTo(pagingNumbersOl);
$(`<li class="disabled"><a>首页</a></li>`).appendTo(pagingNumbersOl);
} else {
$(`<li class="item"><a>«</a></li>`).click(() => paging(page - 1, size)).appendTo(pagingNumbersOl);
$(`<li class="item"><a>首页</a></li>`).click(() => paging(1, size)).appendTo(pagingNumbersOl);
}
}
function renderLastAndNextBtn() {
if (page === pages) {
$(`<li class="disabled"><a>尾页</a></li>`).appendTo(pagingNumbersOl);
$(`<li class="disabled"><a>»</a></li>`).appendTo(pagingNumbersOl);
} else {
$(`<li class="item"><a>尾页</a></li>`).click(() => paging(pages, size)).appendTo(pagingNumbersOl);
$(`<li class="item"><a>»</a></li>`).click(() => paging(page + 1, size)).appendTo(pagingNumbersOl);
}
}
function renderNumbers() {
$.each(numbers, (i, v) => {
let li = $(`<li class="item"><a>${v}</a></li>`).appendTo(pagingNumbersOl);
if (parseInt(v) === page) {
li.addClass("active");
} else {
li.click(() => paging(parseInt(v), size));
}
});
}
function renderPagingMessage() {
$(`<li><a>当前是第 ${page} / ${pages} 页,共 ${total} 条数据</a></li>`).appendTo(pagingNumbersOl);
}
function updatePagingSize() {
pagingSizeSel.val(size);
}
- web:
view/script/user/user.css
#user-list-sec {
margin: 10px;
}
.operation-sec {
margin: 10px;
}
.paging-sec {
text-align: center;
}
- web:
view/html/user/user-insert.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>login</title>
<base href="/z9/">
<link href="bootstrap337/css/bootstrap.min.css" rel="stylesheet">
<link href="view/style/user/user-insert.css" rel="stylesheet">
</head>
<body>
<section class="user-insert-sec panel panel-info">
<article class="panel-heading">
<div class="panel-title">添加用户</div>
</article>
<form id="insert-form">
<article class="panel-body">
<label class="input-group">
<span class="input-group-addon">姓名</span>
<input id="name-ipt" name="name" autofocus="autofocus" class="form-control"/>
</label>
<label class="input-group">
<span class="input-group-addon">年龄</span>
<input id="age-ipt" name="age" class="form-control"/>
</label>
<div class="radio">
<label class="radio-inline">
<input id="female-rdo" type="radio" name="gender" value="0" checked="checked"/> 女
</label>
<label class="radio-inline">
<input id="male-rdo" type="radio" name="gender" value="1"/> 男
</label>
<label class="radio-inline">
<input id="secret-rdo" type="radio" name="gender" value="2"/> 保密
</label>
</div>
</article>
</form>
<article class="panel-footer">
<button id="submit-btn" type="button" class="btn btn-info">提交</button>
<button id="reset-btn" type="button" class="btn btn-danger">重置</button>
</article>
</section>
<script src="jquery321/jquery-3.2.1.min.js"></script>
<script src="bootstrap337/js/bootstrap.min.js"></script>
<script src="view/script/user/user-insert.js"></script>
</body>
</html>
- web:
view/style/user/user-insert.js
const APP_NAME = "/z9";
$(() => {
$("#submit-btn").click(() => submitInsertForm());
});
function submitInsertForm() {
$.ajax({
"url": `${APP_NAME}/api/user/insert`,
"type": "post",
"data": $("#insert-form").serialize(),
"success": response => {
alert(response["msg"]);
if (response["status"] === 200) {
location.href = `${APP_NAME}/view/html/user/user.html`;
}
}
});
}
- web:
view/script/user/user-insert.css
.user-insert-sec {
width: 500px;
margin: 10px auto;
}
.input-group {
margin-top: 10px;
}
- web:
view/html/user/user-update.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>login</title>
<base href="/z9/">
<link href="bootstrap337/css/bootstrap.min.css" rel="stylesheet">
<link href="view/style/user/user-update.css" rel="stylesheet">
</head>
<body>
<section class="user-insert-sec panel panel-info">
<article class="panel-heading">
<div class="panel-title">修改用户</div>
</article>
<article class="panel-body">
<form id="update-form">
<input type="hidden" id="id-ipt" name="id" value="">
<label class="input-group">
<span class="input-group-addon">姓名</span>
<input id="name-ipt" name="name" class="form-control"/>
</label>
<label class="input-group">
<span class="input-group-addon">年龄</span>
<input id="age-ipt" name="age" type="number" class="form-control"/>
</label>
<div class="radio">
<label class="radio-inline">
<input id="rdo-0" type="radio" name="gender" value="0"/> 女
</label>
<label class="radio-inline">
<input id="rdo-1" type="radio" name="gender" value="1"/> 男
</label>
<label class="radio-inline">
<input id="rdo-2" type="radio" name="gender" value="2"/> 保密
</label>
</div>
</form>
</article>
<article class="panel-footer">
<button id="submit-btn" type="button" class="btn btn-info">提交</button>
<button id="reset-btn" type="button" class="btn btn-danger">重置</button>
</article>
</section>
<script src="jquery321/jquery-3.2.1.min.js"></script>
<script src="bootstrap337/js/bootstrap.min.js"></script>
<script src="view/script/user/user-update.js"></script>
</body>
</html>
- web:
view/style/user/user-update.js
const APP_NAME = "/z9";
$(() => {
let id = sessionStorage.getItem("id");
selectById(id);
$("#submit-btn").click(() => submitUpdateForm());
});
function selectById(id) {
$.ajax({
"url": `${APP_NAME}/api/user/find-by-id`,
"data": {"id": id},
"success": response => {
if (response["status"] === 200) {
renderUser(response["data"]);
} else {
alert(response["msg"]);
}
}
});
}
function renderUser(user) {
$("#id-ipt").val(user["id"]);
$("#name-ipt").val(user["name"]);
$("#age-ipt").val(user["age"]);
$(`#rdo-${user["gender"]}`).attr("checked", "checked");
}
function submitUpdateForm() {
$.ajax({
"url": `${APP_NAME}/api/user/update-by-id`,
"data": $("#update-form").serialize(),
"success": response => {
console.log(response);
alert(response["msg"]);
if (response["status"] === 200) {
location.href = `${APP_NAME}/view/html/user/user.html`;
}
}
});
}
- web:
view/script/user/user-update.css
.user-insert-sec {
width: 500px;
margin: 10px auto;
}
.input-group {
margin-top: 10px;
}
6 PageHelper
- res:
pom.xml
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
概念: 在<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 下创建
- res:
spring-mapping.xml
<!-- 注意其他配置 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
helperDialect=mysql
pageSizeZero=true
reasonable=true
</value>
</property>
</bean>
</array>
</property>
- src:
c.y.mapper.UserMapper
/**
* 查询所有用户信息
*
* @return 全部用户信息
*/
List<User> selectAll();
- res:
classpath:mybatis/mapper/UserMapper.xml
<select id="selectAll" resultType="user">
select
<include refid="*"/>
from user
</select>
- src:
c.y.service.UserService
/**
* 分页查询用户信息
*
* @param pageNum 显示第几页
* @param pageSize 每页显示几条
* @return 部分用户信息
*/
PageInfo<User> paging(Integer pageNum, Integer pageSize);
- src:
c.y.service.UserService.impl
@Override
public PageInfo<User> paging(Integer pageNum, Integer pageSize) {
if (pageNum == null || pageSize == null) {
return new PageInfo<>();
}
PageHelper.startPage(pageNum, pageSize);
return new PageInfo<>(userMapper.selectAll());
}
- src:
c.y.controller.UserController
@ResponseBody
@RequestMapping("paging")
public JsonData paging(Integer pageNum, Integer pageSize) {
PageInfo<User> users = userService.paging(pageNum, pageSize);
return new JsonData(users);
}
- web:
view/style/user/user.js
const APP_NAME = "/z9";
let pageSizeSel, navigatePageNumsOl;
let pageNum, pageSize, total, pages, navigatePageNums;
$(() => {
pageSizeSel = $("#paging-size-sel").change(() => changePageSize());
$("#delete-btn").click(() => deleteByIds());
$("#insert-btn").click(() => insert());
paging(1, 5);
});
function insert() {
location.href = `${APP_NAME}/view/html/user/user-insert.html`
}
function changePageSize() {
paging(1, pageSizeSel.val())
}
function deleteByIds() {
if (confirm("确认删除吗?")) {
$.ajax({
"url": `${APP_NAME}/api/user/delete-by-ids`,
"type": "post",
"data": $("#delete-form").serialize(),
"success": response => {
alert(response["msg"]);
if (response["status"] === 200) {
location.href = `${APP_NAME}/view/html/user/user.html`;
}
}
});
}
}
function paging(pageNum, pageSize) {
$.ajax({
"url": `${APP_NAME}/api/user/paging`,
"type": "post",
"data": {"pageNum": pageNum, "pageSize": pageSize},
"success": response => {
if (response["status"] === 200) {
renderTable(response["data"]["list"]);
renderPaging(response["data"]);
} else {
alert(response["msg"]);
}
}
});
}
function renderTable(users) {
let userListTHead = $("#user-list-thead").html("");
let headTr = $(`<tr></tr>`).appendTo(userListTHead);
$(`<th><label><input id="select-all-cbx" type="checkbox"/></label></th>`).appendTo(headTr);
$(`<th>序号</th><th>姓名</th><th>年龄</th><th>性别</th><th>操作</th>`).appendTo(headTr);
let userListTbody = $("#user-list-tbody").html("");
$.each(users, (i, v) => {
let tr = $("<tr></tr>").appendTo(userListTbody);
$(`<td><label><input name="ids" type="checkbox" value='${v["id"]}'/></td></label>`).appendTo(tr);
$(`<td>${i + 1}</td>`).appendTo(tr);
$(`<td>${v["name"] !== undefined ? v["name"] : ""}</td>`).appendTo(tr);
$(`<td>${v["age"] !== undefined ? v["age"] : ""}</td>`).appendTo(tr);
$(`<td>${v["gender"] === 1 ? "男" : v["gender"] === 0 ? "女" : v["gender"] === 2 ? "保密" : ""}</td>`).appendTo(tr);
let updateTd = $(`<td></td>`).appendTo(tr);
let updateBtn = $(`<a href="javascript:" >修改</a>`);
updateBtn.click(() => {
sessionStorage.setItem("id", v["id"]);
location.href = `${APP_NAME}/view/html/user/user-update.html`;
}).appendTo(updateTd);
});
}
function renderPaging(pageInfo) {
pageNum = pageInfo["pageNum"];
pageSize = pageInfo["pageSize"];
pages = pageInfo["pages"];
total = pageInfo["total"];
navigatePageNums = pageInfo["navigatepageNums"];
navigatePageNumsOl = $("#paging-numbers-ol").html("");
renderPrevAndFirstBtn();
renderNavigatePageNums();
renderLastAndNextBtn();
renderPagingMessage();
updatePagingSize();
function renderPrevAndFirstBtn() {
if (pageNum === 1) {
$(`<li class="disabled"><a>«</a></li>`).appendTo(navigatePageNumsOl);
$(`<li class="disabled"><a>首页</a></li>`).appendTo(navigatePageNumsOl);
} else {
$(`<li class="item"><a>«</a></li>`).click(() => paging(pageNum - 1, pageSize)).appendTo(navigatePageNumsOl);
$(`<li class="item"><a>首页</a></li>`).click(() => paging(1, pageSize)).appendTo(navigatePageNumsOl);
}
}
function renderNavigatePageNums() {
$.each(navigatePageNums, (i, v) => {
let li = $(`<li class="item"><a>${v}</a></li>`).appendTo(navigatePageNumsOl);
if (v === pageNum) {
li.addClass("active");
} else {
li.click(() => paging(v, pageSize));
}
});
}
function renderLastAndNextBtn() {
if (pageNum === pages) {
$(`<li class="disabled"><a>尾页</a></li>`).appendTo(navigatePageNumsOl);
$(`<li class="disabled"><a>»</a></li>`).appendTo(navigatePageNumsOl);
} else {
$(`<li class="item"><a>尾页</a></li>`).click(() => paging(pages, pageSize)).appendTo(navigatePageNumsOl);
$(`<li class="item"><a>»</a></li>`).click(() => paging(pageNum + 1, pageSize)).appendTo(navigatePageNumsOl);
}
}
function renderPagingMessage() {
$(`<li><a>当前是第 ${pageNum} / ${pages} 页,共 ${total} 条数据</a></li>`).appendTo(navigatePageNumsOl);
}
function updatePagingSize() {
pageSizeSel.val(pageSize);
}
}