基于SSM的CRUD以及pageHelper的使用
经过了一段时间的学习,对ssm已经有了初步的认识,然后也坎坷的做出了增删改查,实际上放假都是在休息或者游戏,所以憋了2天才写出来。
我觉得一个简单的增删改查是满足不了大家的,所以我会尽可能地详细的讲,也会让大家注意我踩的坑,跟着这篇文章,我相信你能快速的搭建ssm框架并且完成相应的业务需求。
业务没有设计maven,所以我们创建xml等操作都是手动完成。
1.准备jar包,ssm的包以及jstl,还有分页插件pagehelper以及sql解释jar。
注意:jar包没有截图全部,具体的jar下载直接在文章末尾的github上直接下载
2.创建我们的web工程,目录结构如下
注释:
action:springmvc控制开发
mapping:mybaties映射接口和文件
pojo:业务实体类
service:业务实现类
创建spring,springmvc,mybaties,数据库连接文件,日志文件
spring:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd ">
<!--读取数据库配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 数据库连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.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="maxActive" value="10" />
<property name="maxIdle" value="5" />
</bean>
<!-- Mybatis的工厂 -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 1) 核心配置文件的位置 -->
<property name="configLocation" value="classpath:mybaties.config.xml"/>
<!-- 2)扫描指定目录下的所有Mapper.xml -->
<property name="mapperLocations" value="classpath:com/ssmall/mapping/*.xml"></property>
</bean>
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com">
<!-- 扫描时跳过 @Controller 注解的JAVA类(控制器) -->
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 注解事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
springmvc:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 配置自定扫描的包 -->
<context:component-scan base-package="com" />
<mvc:annotation-driven />
<!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置 MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>
myabites:
<?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">
<!-- 类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余 -->
<typeAliases>
<typeAlias alias="User" type="com.ssmall.pojo.Userpojo" />
</typeAliases>
<!-- 配置分页插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 设置数据库类型Oracle,MySQL,MarinDBName,SQLite,PostareSQL六种数据库 -->
<property name="dialect" value="mysql" />
</plugin>
</plugins>
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sys?characterEncoding=utf-8
jdbc.username=root
jdbc.password=swq891012
web.xml:
<!--?xml version="1.0" encoding="UTF-8"?-->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 1.spring容器 listener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 2.springmvc servlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 3.spring 中文乱码 filter -->
<!-- 编码过滤器,解决中文乱码 -->
<filter>
<filter-name>SpringEncoding</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>SpringEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file>index.jsp</welcome-file>
3.开发mybaties映射接口和mybaties映射xml
接口(所属包mapping):
package com.ssmall.mapping;
import java.util.List;
import com.ssmall.pojo.Userpojo;
public interface UserMapping {
public List<Userpojo> getAll();
public Userpojo getUser(Integer id);
public boolean deleteById(Integer id);
public boolean add(Userpojo user);
public boolean update(Userpojo user);
}
mybaites映射
<?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
例如namespace="me.gacl.mapping.userMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml文件去除后缀) -->
<!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复 使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
resultType="me.gacl.domain.User"就表示将查询结果封装成一个User类的对象返回 User类就是users表所对应的实体类 -->
<!-- 根据id查询得到一个user对象 -->
<select id="getUser" parameterType="int" resultType="com.ssmall.pojo.Userpojo">
select * from t_user where id=#{id}
</select>
<select id="getAll" resultType="com.ssmall.pojo.Userpojo">
select * from t_user
</select>
<delete id="deleteById" parameterType="int">
delete from t_user where id=#{id}
</delete>
<insert id="add">
insert into t_user(username,password,account) values
(#{username},#{password},#{account})
</insert>
<update id="update">
update t_user set username=#{username},password=#{password},account=#{account} where id=#{id}
</update>
注意:这边的查询语句由于使用了分页插件pageHelper,所以无需做变化
1)id要与接口的方法名对应上,并且放在一个包下,命名空间namespace是唯一的,所以建议写映射包名+类名的写法(写的是接口)
2)mybaties映射xml文件名和映射接口文件名要一样,后缀不同即可
4.开发dao层,service层
dao层(接口省略):
package com.ssmall.dao;
import java.util.List;
import javax.annotation.Resource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssmall.mapping.UserMapping;
import com.ssmall.pojo.Userpojo;
@Repository
public class IPublicDaoImpl extends SqlSessionDaoSupport implements PublicDao{
/*super.setSqlSessionFactory(sessionFactory):调用父类方法,将sqlsessionfactory注入进去*/
@Resource
public void setSessionFactory(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
/**
* 公共dao层方法
*/
public Userpojo get(int id) {
UserMapping mapper = this.getSqlSession().getMapper(UserMapping.class);
Userpojo user = mapper.getUser(id);
return user;
}
//查询数量
public static final int PAGE_SHOW_NUMBER=5;
@Override
public PageInfo<Userpojo> getAll(Integer index) {
UserMapping mapper = this.getSqlSession().getMapper(UserMapping.class);
PageHelper.startPage(index, PAGE_SHOW_NUMBER);
List<Userpojo> all =mapper.getAll();
//用PageInfo对结果进行包装
PageInfo<Userpojo> pageInfo = new PageInfo<Userpojo>(all);
return pageInfo;
}
//查询数据的总页数
@Override
public boolean deleteById(Integer id) {
UserMapping mapper = this.getSqlSession().getMapper(UserMapping.class);
return mapper.deleteById(id);
}
@Override
public boolean addUser(Userpojo user) {
UserMapping mapper = this.getSqlSession().getMapper(UserMapping.class);
return mapper.add(user);
}
@Override
public boolean updateUser(Userpojo user) {
UserMapping mapper = this.getSqlSession().getMapper(UserMapping.class);
return mapper.update(user);
}
}
注意:在我们的查询方法中,返回的不是List集合,而是分页插件提供的类PageInfo,我们通过映射接口取得list可以通过PageInfo的方法转换进行包装,在PageInfo类中有许多我们常用的方法,比如数据库的分页页数,长度等等,非常有利于我们开发,所以在查询的这个方法中我们定义了常量,这个常量就是一页显示多少条,第一个参数index,是第几页
service层:
package com.ssmall.service;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssmall.dao.PublicDao;
import com.ssmall.pojo.Userpojo;
@Service
public class IUserServiceImpl implements UserService {
@Resource
private PublicDao dao;
//根据ID查询单条
public Userpojo get(Integer id) {
return this.dao.get(id);
}
//查询全部
public PageInfo<Userpojo> getAll(Integer pageNum) {
return this.dao.getAll(pageNum);
}
//删除单条
public boolean deleteById(Integer id) {
return this.dao.deleteById(id);
}
@Override
public boolean addUser(Userpojo user) {
return this.dao.addUser(user);
}
@Override
public boolean updateUser(Userpojo user) {
return this.dao.updateUser(user);
}
}
action层:
package com.ssmall.action;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.github.pagehelper.PageInfo;
import com.ssmall.pojo.Userpojo;
import com.ssmall.service.UserService;
@Controller
public class UserAction {
@Resource
private UserService userService;
/**
* 查询所有信息
*
* @param null
* @return
*/
@RequestMapping("/user/all/{index}")
public ModelAndView getUserAll(@PathVariable("index") Integer index) {
ModelAndView model = new ModelAndView("list");
PageInfo<Userpojo> all = userService.getAll(index);
List<Userpojo> list = all.getList();
model.addObject("allList", list);
//存储当前索引在域中
model.addObject("index", index);
//计算能分多少页
int pages = all.getPages();
model.addObject("lastnum", pages);
return model;
}
/**
* 根据id查询单条信息
*
* @param id
* @return
*/
@RequestMapping("/user/get/{id}")
public String getUserById(@PathVariable("id") Integer id) {
Userpojo userpojo = userService.get(id);
return "success";
}
/**
* 根据id删除
*
* @param id
* @return
*/
@RequestMapping("/deleteById")
public String DeleteById(@RequestParam("id") Integer id) {
// 执行删除
boolean deleteById = userService.deleteById(id);
// 删除成功后查询
return "redirect:/user/all/1";
}
/**
* 新增用户
*
* @param user
* @return
*/
@RequestMapping("/user/addUser")
public String addUser(Userpojo user) {
userService.addUser(user);
return "redirect:/user/all";
}
// 新增用户的跳转方法
@RequestMapping("/user/addready")
public String addReady(Model model) {
model.addAttribute("itemForm", "form");
// 添加用户之后,在请求域中添加一个判断添加或者修改页面的依据
// 根据这个依据,可以通过jstl共用form.jsp页面
return "form";
}
/**
* 修改用户
*
* @param user
* @return
*/
@RequestMapping("/update")
public String update(Userpojo user){
userService.updateUser(user);
return "redirect:/user/all/1";
}
@RequestMapping("/updateById")
public String updateReady(@RequestParam("id") Integer id,Model model) {
Userpojo userpojo = userService.get(id);
model.addAttribute("userlist", userpojo);
return "form";
}
}
注意:
主要难点还是查询的方法,只要理解了查询的方法,其他的增删改都是非常之简单。
主要的是我们的jsp页面,我们大量的用到了jsp页面,在WEB-INF/views下很多jsp,其中我们的增加的表单和修改的表单都是form.jsp,我们通过action设置的请求域值来区分当前是增加操作还是修改操作。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<base href="<%=basePath%>">
<title>My JSP 'form.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<c:if test="${itemForm != null}">
<form action="user/addUser" method="post">
</c:if>
<c:if test="${itemForm == null}">
<form action="update" method="post">
</c:if>
<input type="hidden" name="id" value="${userlist.id}">
用户名:<input type="text" name="username" value="${userlist.username}">
<br>
密码:<input type="password" name="password" value="${userlist.password}">
<br>
详情:<input type="text" name="account" value="${userlist.account}">
<br>
<c:if test="${itemForm != null}">
<input type="submit" value="添加">
</c:if>
<c:if test="${itemForm == null}">
<input type="submit" value="修改">
</c:if>
</form>
下面就是我们的list展示页面,上一页和下一页,都是利用el表达式来编码,也巧妙地用了if判断,来在首页隐藏上一页,末页隐藏下一页避免了逻辑错误
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<a href="user/addready">添加用户</a>
<table>
<thead>
<tr>
<th>id</th>
<th>用户</th>
<th>密码</th>
<th>详情</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${requestScope.allList}" var="list">
<tr>
<c:if test="${requestScope.allList==''}">
<td>暂无记录</td>
</c:if>
<td>${list.id}</td>
<td>${list.username}</td>
<td>${list.password}</td>
<td>${list.account}</td>
<td><a href="deleteById?id=${list.id}">删除</a></td>
<td><a href="updateById?id=${list.id}">修改</a></td>
</tr>
</c:forEach>
</tbody>
</table>
<a href="user/all/1">首页</a>
<c:if test="${index != 1}">
<a href="user/all/${index-1}">上一页</a>
</c:if>
<c:if test="${index != lastnum}">
<a href="user/all/${index+1}">下一页</a>
</c:if>
<a href="user/all/${lastnum}">末页</a>
好了,我们的整个整合就结束了:
源码下载地址,bug都测试完了,没有任何问题,欢迎下载demo: