文章目录
- 概述
- Step1.新建Maven web项目
-
- step1.1 基本结构
- Step1.2 pom.xml
- Step1.3 web.xml
- Step1.4 pom.xml中添加web的支持
- Step1.5 添加页面用于验证搭建的web项目是否OK
- Step2.集成Spring和Spring MVC
-
- Step2.1 添加Spring项目清单用于管理Spring依赖
- Step2.2 添加Spring依赖
- Step2.3 添加Spring MVC依赖
- Step2.4 添加Spring XML配置文件
- Step2.5 添加Spring MVC配置文件
- Step2.6 配置web.xml
- Step2.7 验证集成的Spring 以及SpringMVC是否OK
- Step3.集成MyBatis
-
- Step3.1 添加mybatis-spring依赖
- Step3.2 配置 SqlSessionFactoryBean
- Step3.3 配置MapperScannerConfigurer
- 3.4applicationContext.xml其他配置AOP和事务
- Step4.示例测试
-
- step4.0数据准备
- step4.1 实体类
- step4.2 开发Mapper层(Dao层)
-
- 4.2.1 根据配置文件中的扫描路径新建包(接口用)或目录(xml用)
- 4.2.2DictMapper接口
- 4.2.3 DictMapper.xml
- step4.3开发业务层(Service层)
- step4.4开发控制层(Controller层)
- step4.5开发视图层(View层)
- step4.6部署运行应用
- Step5.代码地址及总结
概述
通过半个多月的梳理,MyBatis我们已经能够使用,下面我们来说下SSM的整合。
整合SSM,需要用到MyBatis-Spring。
MyBatis-Spring可以将MyBatis代码无缝整合到Spring中,使用这个类库中的类,Spring将会加载必要的MyBatis工厂类和Session类。 这个类库也提供了一种简单的方式将MyBatis数据映射器和SqlSession注入到业务层的bean中,而且也可以处理事务,翻译MyBatis的异常到Spring的DataAcessException数据访问异常中。
MyBatis-Spring项目地址: https://github.com/mybatis/spring
接下来,我们从新建一个Maven项目开始,逐步集成Spring、Spring MVC 和MyBatis。
Step1.新建Maven web项目
如果不熟悉,请查考之前的博文总结 Maven-EclipseEE使用Maven构建Java web项目从0到1,这里简单说下重点,不赘述细节了。
step1.1 基本结构
Step1.2 pom.xml
正创建Maven Web项目的时候,输入对应的Group Id 、 Artifact Id 、 Version ,web项目 packing 为 war。
Step1.3 web.xml
代码语言:javascript复制<?xml version="1.0" encoding="ISO-8859-1"?>
<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_3_0.xsd"
version="3.0">
</web-app>
空的web.xml 如上所示,
Step1.4 pom.xml中添加web的支持
添加web的支持
代码语言:javascript复制<!--web-->
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!--JSP-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<!--JSTL-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
版本信息如下:
代码语言:javascript复制<junit.version>3.8.1</junit.version>
<servlet.version>3.1.0</servlet.version>
<jstl.version>1.2</jstl.version>
<jsp.version>2.1</jsp.version>
由于项目中可能会用到Filter和ServletRequest接口,所以在编译项目时,必须听servlet-api和jsp-api依赖。 通常Web容器都会自带servlet-api和jsp-api的jar包,为了避免jar包重复引起错误,需要将servlet-api和jsp-api的scope配置为provided.
配置为provided的jar包在项目打包时,不会将依赖的jar包打包到项目中,项目运行时这些jar包需要欧容器提供,这样避免了重复jar包引起的错误。
一般以JSP作为视图的项目中,jstl是很常见的搭配,使用jstl可以在视图中处理复杂的逻辑,所以都会添加jstl依赖
Step1.5 添加页面用于验证搭建的web项目是否OK
页面中使用了jstl,用来显示服务器的时间。
/ssm/src/main/webapp下添加个home.jsp
同时在web.xml中添加欢迎页面
代码语言:javascript复制<!-- 关于欢迎页面:访问一个网站时,默认看到的第一个页面就叫欢迎页,一般情况下是由首页来充当欢迎页的。
一般情况下,我们会在web.xml中指定欢迎页。 -->
<!-- 指定欢迎页面.指定了2个欢迎页面.
显示时按顺序从第一个找起,如果第一个存在,就显示第一个,后面的不起作用。
如果第一个不存在,就找第二个,以此类推 -->
<welcome-file-list>
<welcome-file>home.jsp</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- web.xml也没指定欢迎页的情况下,它默认先查找index.html文件,
如果找到了,就把index.html作为欢迎页还回给浏览器。
如果没找到index.html,tomcat就去找index.jsp。找到index.jsp就把它作为欢迎页面返回。
而如果index.html和index.jsp都没找到,又没有用web.xml文件指定欢迎页面,那此时tomcat就不知道该返回哪个文件了,
就显示TThe requested resource is not available. -->
home.jsp
代码语言:javascript复制<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/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=UTF8">
<title>Home</title>
</head>
<body>
<p>
用于验证新建的Maven Web项目是否OK
<br>
<br>
页面以及服务器时间正常展示--->OK
</p>
<p>
<%
Date now = new Date();
%>
服务器时间:<fmt:formatDate value="<%=now%>" pattern="yyyy-MM-dd HH:mm:ss"/>
</p>
</body>
</html>
将项目发布到tomcat8中
启动成功后,输入
http://localhost:8080/ssm/home.jsp
或者
http://localhost:8080/ssm
Step2.集成Spring和Spring MVC
Step2.1 添加Spring项目清单用于管理Spring依赖
代码语言:javascript复制 <!-- 在dependencyManagement中引入spring-framework-bom来确保所有的spring模块都使用统一的版本.
添加spring-framework-bom后,就不需要配置每个依赖的版本号了,方便管理与升级 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在dependencyManagement中引入spring-framework-bom来确保所有的spring模块都使用统一的版本.添加spring-framework-bom后,就不需要配置每个依赖的版本号了,方便管理与升级
Step2.2 添加Spring依赖
代码语言:javascript复制 <!--Spring 上下文,核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!--Spring JDBC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!--Spring 事务-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<!--Spring 面向切面编程-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<!--spring-aop 依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
详见注释内容
Step2.3 添加Spring MVC依赖
代码语言:javascript复制 <!--Spring Web 核心-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!--Spring MVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!--spring mvc-json依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.4</version>
</dependency>
前两个依赖是SpringMVC必备的依赖,后面的jackson-databind是SpringMVC转换为JSON时需要使用的依赖
Step2.4 添加Spring XML配置文件
/src/main/resources目录下 增加 applicationContext.xml
代码语言:javascript复制<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置Spring自动扫描类,通过base-package指定扫描的包名 使用了Ant通配符 -->
<context:component-scan base-package="com.artisan.*.service.impl"/>
<!-- 数据源 -->
<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/artisan"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
</beans>
配置文件中component-scan用于配置Spring自动扫描的类,通过base-package属性设置要扫描的包名, 包名支持Ant通配符,报名中的*匹配0或者任意数量的字符,这里的配置可以匹配com.artisan.web.service.impl 或者 com.artisan.xxx.service.impl这样的包。
dataSource配置了一个数据源连接,最好将其独立到单独的配置文件,前面的博客中有讲,这里先不抽取出来了。
Step2.5 添加Spring MVC配置文件
/src/main/resources目录下新增 springmvcConfig.xml
代码语言:javascript复制<?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:mvc="http://www.springframework.org/schema/mvc"
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">
<!-- 扫描控制层的注解,使其成为Spring管理的Bean -->
<context:component-scan base-package="com.artisan.*.controller"/>
<!-- 启用Controller注解支持 -->
<mvc:annotation-driven/>
<!-- 静态资源文件 -->
<mvc:resources mapping="/static/**" location="static/"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
配置项说明参考注释
Step2.6 配置web.xml
集成Spring和SpringMVC后,要在web.xml中进行相应的配置。
对于Spring来说,需要增加如下配置
代码语言:javascript复制<!-- 在web启动时,根据contextConfigLocation配置的路径读取Spring配置文件,启动Spring -->
<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>
对于Spring MVC来说,需要增加如下配置
代码语言:javascript复制<!-- Spring MVC配置 -->
<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:springmvcConfig.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
为了避免编码不一致,通常还需要增加编码过滤器配置
代码语言:javascript复制<!-- 为避免编码不一致,一般情况下都需要增加编码过滤器 -->
<filter>
<filter-name>SpringEncodingFilter</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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SpringEncodingFilter</filter-name>
<url-pattern>/*
Step2.7 验证集成的Spring 以及SpringMVC是否OK
/ssm/src/main/webapp/WEB-INF/jsp目录下增加 index.jsp
代码语言:javascript复制<%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/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=UTF8">
<title>Index</title>
</head>
<body>
<p>
用于验证集成了Spring和SpringMVC是否正常
<br>
<br>
页面以及服务器时间正常展示--->OK
</p>
<p>
通过mv传递过来的now视图参数,获取服务器时间
服务器时间:<fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>
</p>
</body>
</html>
/ssm/src/main/java/com/artisan/web/controller包下增加控制层IndexController.java
代码语言:javascript复制package com.artisan.web.controller;
import java.util.Date;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
*
*
* @ClassName: IndexController
*
* @Description: 用于验证集成Spring以及SpringMVC是否OK
*
* @author: Mr.Yang
*
* @date: 2018年5月1日 下午2:21:11
*/
@Controller
public class IndexController {
@RequestMapping("/index")
public ModelAndView testEnv() {
ModelAndView mv = new ModelAndView();
// 设置跳转页面
mv.setViewName("index");
// 传递参数
mv.addObject("now", new Date());
return mv;
}
}
启动应用,访问 http://localhost:8080/ssm/index
Step3.集成MyBatis
Step3.1 添加mybatis-spring依赖
代码语言:javascript复制<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring}</version>
</dependency>
这里我们使用 1.3.0
版本
Step3.2 配置 SqlSessionFactoryBean
在MyBatis-Spring中,SqlSessionFactoryBean用于创建SqlSessionFactory. 在Spring配置文件applicationContext.xml中配置这个工厂类
代码语言:javascript复制 <!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatisConfig.xml"/>
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations">
<array>
<value>classpath:com/artisan/**/mapper/*.xml
SqlSessionFactoryBean常用属性介绍:
- configLocation 用于配置MyBatis配置XML的路径
MyBatis配置文件 /ssm/src/main/resources/mybatisConfig.xml
代码语言:javascript复制<?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>
<settings>
<setting name="logImpl" value="LOG4J"/>
<setting name="cacheEnabled" value="true"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
</configuration>
- datasource 用于配置数据源,必选项
- mapperLocations 配置SqlSessionFactory扫描XML映射文件的路径
- typeAliasesPackage 配置包中类的别名, 配置后,包中的类在XML映射文件中使用时可以省略包名部分,直接使用类名。 不支持Ant风格的路径,当需要配置多个可以使用分号或者逗号隔开。
其他属性可参考源码,略。
Step3.3 配置MapperScannerConfigurer
推荐使用MapperScannerConfigurer 类自动扫描所有的Mapper接口,使用时可以直接注入接口
/ssm/src/main/resources/applicationContext.xml增加
代码语言:javascript复制 <!-- 配置MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="addToConfig" value="true"/>
<property name="basePackage" value="com.artisan.**.mapper"/>
</bean>
MapperScannerConfigurer常用属性
- basePackage 用于配置基本的包路径,可以使用分号或者逗号作为分隔符设置多个包路径,每个映射器会在指定的包路径中递归被搜索到。
- annotationClass 用于过滤被扫描的接口,如果设置了该属性,那么MyBatis的接口只有包含该注解才会被扫描进去。
3.4applicationContext.xml其他配置AOP和事务
代码语言:javascript复制 <aop:aspectj-autoproxy/>
<aop:config>
<aop:pointcut id="appService" expression="execution(* com.artisan.*.service..*Service*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="appService"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="select*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Step4.示例测试
step4.0数据准备
MySql数据库
代码语言:javascript复制-- ----------------------------
-- Table structure for sys_dict
-- ----------------------------
DROP TABLE IF EXISTS `sys_dict`;
CREATE TABLE `sys_dict` (
`id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(64) NOT NULL COMMENT '类别',
`name` varchar(64) NOT NULL COMMENT '字典名',
`value` varchar(64) NOT NULL COMMENT '字典值',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_dict
-- ----------------------------
INSERT INTO `sys_dict` VALUES ('1', '性别', '男', '男');
INSERT INTO `sys_dict` VALUES ('2', '性别', '女', '女');
INSERT INTO `sys_dict` VALUES ('3', '季度', '第一季度', '1');
INSERT INTO `sys_dict` VALUES ('4', '季度', '第二季度', '2');
INSERT INTO `sys_dict` VALUES ('5', '季度', '第三季度', '3');
INSERT INTO `sys_dict` VALUES ('6', '季度', '第四季度', '4');
step4.1 实体类
在 /src/main/java 新建 com.artisan.web.model包,然后新建SysDict.java
代码语言:javascript复制package com.artisan.web.model;
import java.io.Serializable;
/**
*
*
* @ClassName: SysDict
*
* @Description: SysDict实体类,如果使用缓存,请务必实现java.io.Serializable接口
*
* @author: Mr.Yang
*
* @date: 2018年5月11日 下午4:16:37
*/
public class SysDict implements Serializable {
private static final long serialVersionUID = -2496324675593406906L;
private Long id;
private String code;
private String name;
private String value;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "SysDict [id=" id ", code=" code ", name=" name ", value=" value "]";
}
}
step4.2 开发Mapper层(Dao层)
Mapper层也就是常说的数据访问层(Dao层) 。 使用Mapper和XML映射文件结合的方式进行开发。
4.2.1 根据配置文件中的扫描路径新建包(接口用)或目录(xml用)
在/ssm/src/main/resources/applicationContext.xml集成MyBatis中
MapperScannerConfigurer自动扫描接口的包名为 com.artisan.**.mapper,因此创建Mapper接口也需要参照这个命名规则。
在/src/main/java新建 com.artisan.web.mapper 包,创建DictMapper接口
代码语言:javascript复制public interface DictMapper {
}
同样的,SqlSessionFactoryBean中配置了扫描XML映射文件的路径
classpath:com/artisan/**/mapper/*.xml ,在 /src/main/resources/ 新建com/artisan/web/mapper目录,然后新增DictMapper.xml文件
代码语言:javascript复制<?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接口和XML文件关联的时候, namespace的值就需要配置成接口的全限定名称 -->
<mapper namespace="com.artisan.web.mapper.DictMapper">
</mapper>
4.2.2DictMapper接口
CRUD基本操作
代码语言:javascript复制package com.artisan.web.mapper;
import java.util.List;
import org.apache.ibatis.session.RowBounds;
import com.artisan.web.model.SysDict;
/**
*
*
* @ClassName: DictMapper
*
* @Description: 操作Sys_Dict的接口
*
* @author: Mr.Yang
*
* @date: 2018年5月11日 下午4:24:14
*/
public interface DictMapper {
/**
*
*
* @Title: selectByPrimaryKey
*
* @Description: 根据主键查询
*
* @param id
* @return
*
* @return: SysDict
*/
SysDict selectByPrimaryKey(Long id);
/**
* 条件查询
*
* @param sysDict
* @return
*/
List<SysDict> selectBySysDict(SysDict sysDict, RowBounds rowBounds);
/**
* 新增
*
* @param sysDict
* @return
*/
int insert(SysDict sysDict);
/**
* 根据主键更新
*
* @param sysDict
* @return
*/
int updateById(SysDict sysDict);
/**
* 根据主键删除
*
* @param id
* @return
*/
int deleteById(Long id);
}
4.2.3 DictMapper.xml
代码语言:javascript复制<?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接口和XML文件关联的时候, namespace的值就需要配置成接口的全限定名称 -->
<mapper namespace="com.artisan.web.mapper.DictMapper">
<select id="selectByPrimaryKey" resultType="com.artisan.web.model.SysDict">
SELECT
a.id,
a.`code`,
a.`name`,
a.`value`
FROM
sys_dict a
WHERE
a.id = #{id}
</select>
<select id="selectBySysDict" resultType="com.artisan.web.model.SysDict">
select * from sys_dict
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="code != null and code != ''">
and code = #{code}
</if>
</where>
order by code, `value`
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert
into sys_dict(code, name, value)
values (#{code}, #{name}, #{value})
</insert>
<update id="updateById">
update
sys_dict
set code = #{code},
name = #{name},
value = #{value}
where id = #{id}
</update>
<delete id="deleteById">
delete from sys_dict where id = #{id}
</delete>
</mapper>
有了上述5个方法,就可以实现对表的基本操作了,下面在这5个接口方法的基础上继续开发Service层的代码。
step4.3开发业务层(Service层)
src/main/java 目录下新建 com.artisan.web.service包 ,添加DictService接口
代码语言:javascript复制package com.artisan.web.service;
import java.util.List;
import com.artisan.web.model.SysDict;
/**
*
*
* @ClassName: DictService
*
* @Description: Service层
*
* @author: Mr.Yang
*
* @date: 2018年5月11日 下午5:37:22
*/
public interface DictService {
SysDict findById(Long id);
List<SysDict> findBySysDict(SysDict sysDict, Integer offset, Integer limit);
boolean saveOrUpdate(SysDict sysDict);
boolean deleteById(Long id);
}
Servie层的saveOrUpdate方法对应Mapper中的insert和updateById方法,其他3个方法和Mapper层的方法一一对应。
com.artisan.web.service包下新建 impl包,然后新建DictServiceImpl实现类实现该接口
接口实现类
代码语言:javascript复制package com.artisan.web.service.impl;
import java.util.List;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.artisan.web.mapper.DictMapper;
import com.artisan.web.model.SysDict;
import com.artisan.web.service.DictService;
/**
*
* @ClassName: DictServiceImpl
* @Description: @Service标注的Service层
* @author: Mr.Yang
* @date: 2018年5月11日 下午5:39:22
*/
@Service
public class DictServiceImpl implements DictService {
@Autowired
private DictMapper dictMapper;
@Override
public SysDict findById(Long id) {
return dictMapper.selectByPrimaryKey(id);
}
@Override
public List<SysDict> findBySysDict(SysDict sysDict, Integer offset, Integer limit) {
RowBounds rowBounds = RowBounds.DEFAULT;
if (offset != null && limit != null) {
rowBounds = new RowBounds(offset, limit);
}
return dictMapper.selectBySysDict(sysDict, rowBounds);
}
@Override
public boolean saveOrUpdate(SysDict sysDict) {
if (sysDict.getId() == null) {
return dictMapper.insert(sysDict) == 1;
} else {
return dictMapper.updateById(sysDict) == 1;
}
}
@Override
public boolean deleteById(Long id) {
if (id == null) {
throw new NullPointerException("id");
}
return dictMapper.deleteById(id) == 1;
}
}
Service层的实现类需要添加@Service注解,集成Spring的时候配置过自动扫描包
/ssm/src/main/resources/applicationContext.xml
包名com.artisan.web.service.impl, DictServiceImpl实现类所在的包就是符合这个包名规则,加上注解后,Spring在初始化扫描到这个类时,然后由Spring管理这个类。
同样的,因为配置了自动扫描Mapper接口,所以在Service层可以注解通过@Autowired自动注入Mapper
通过自动扫描Mapper和自动注入可以更加方便的使用MyBatis。
step4.4开发控制层(Controller层)
com.artisan.web.controller包下新建DictController类
代码语言:javascript复制package com.artisan.web.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.artisan.web.model.SysDict;
import com.artisan.web.service.DictService;
/**
*
*
* @ClassName: DictController
*
* @Description: @Controller标注的Dict控制层
*
* @author: Mr.Yang
*
* @date: 2018年5月11日 下午5:40:19
*/
@Controller
@RequestMapping("/dicts")
public class DictController {
@Autowired
private DictService dictService;
/**
* 显示字典数据列表
*
* @param sysDict
* @param offset
* @param limit
* @return
*/
@RequestMapping
public ModelAndView dicts(SysDict sysDict, Integer offset, Integer limit) {
ModelAndView mv = new ModelAndView("dicts");
List<SysDict> dicts = dictService.findBySysDict(sysDict, offset, limit);
mv.addObject("dicts", dicts);
return mv;
}
/**
* 新增或修改字典信息页面,使用 get 跳转到页面
*
* @param id
* @return
*/
@RequestMapping(value = "add", method = RequestMethod.GET)
public ModelAndView add(Long id) {
ModelAndView mv = new ModelAndView("dict_add");
SysDict sysDict;
if (id == null) {
// 如果 id 不存在,就是新增数据,创建一个空对象即可
sysDict = new SysDict();
} else {
// 如果 id 存在,就是修改数据,把原有的数据查询出来
sysDict = dictService.findById(id);
}
mv.addObject("model", sysDict);
return mv;
}
/**
* 新增或修改字典信息,通过表单 post 提交数据
*
* @param sysDict
* @return
*/
@RequestMapping(value = "add", method = RequestMethod.POST)
public ModelAndView save(SysDict sysDict) {
ModelAndView mv = new ModelAndView();
try {
dictService.saveOrUpdate(sysDict);
mv.setViewName("redirect:/dicts");
} catch (Exception e) {
mv.setViewName("dict_add");
mv.addObject("msg", e.getMessage());
mv.addObject("model", sysDict);
}
return mv;
}
/**
* 通过 id 删除字典信息
*
* @param id
* @return
*/
@RequestMapping(value = "delete", method = RequestMethod.POST)
@ResponseBody
public ModelMap delete(@RequestParam Long id) {
ModelMap modelMap = new ModelMap();
try {
boolean success = dictService.deleteById(id);
modelMap.put("success", success);
} catch (Exception e) {
modelMap.put("success", false);
modelMap.put("msg", e.getMessage());
}
return modelMap;
}
}
用了两个视图 dicts和 dict_add ,接下来开发View层
step4.5开发视图层(View层)
/ssm/src/main/resources/springmvcConfig.xml中的配置
/ssm/src/main/webapp/WEB-INF/jsp/dicts.jsp
代码语言:javascript复制<%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8">
<title>字典信息</title>
<script src="${path}/static/jquery-3.1.1.min.js"></script>
</head>
<body>
<table>
<tr>
<th colspan="4">字典管理</th>
</tr>
<tr>
<th>类别名</th>
<th>字典名</th>
<th>字典值</th>
<th> 操作 [<a href="${path}/dicts/add">新增</a>]</th>
</tr>
<c:forEach items="${dicts}" var="dict">
<tr id="dict-${dict.id}">
<td>${dict.code}</td>
<td>${dict.name}</td>
<td>${dict.value}</td>
<td>
[<a href="${path}/dicts/add?id=${dict.id}">编辑</a>]
[<a href="javascript:;" onclick="deleteById(${dict.id}, '${dict.name}')">删除</a>]
</td>
</tr>
</c:forEach>
</table>
<script>
function deleteById(id, label){
var r = confirm('您确定要删除“' label '”吗?');
if(r){
$.ajax({
url: '${path}/dicts/delete',
data: {
id: id
},
dataType: 'json',
type: 'POST',
success: function(data){
if(data.success){
$('#dict-' id).remove();
} else {
alert(data.msg);
}
}
})
}
}
</script>
</body>
</html>
/ssm/src/main/webapp/WEB-INF/jsp/dict_add.jsp
代码语言:javascript复制<%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8">
<title>字典维护</title>
</head>
<body>
<form action="${path}/dicts/add" method="post">
<input type="hidden" name="id" value="${model.id}">
<table>
<c:if test="${msg != null}">
<tr>
<th colspan="2" style="color:red;max-width:400px;">${msg}</th>
</tr>
</c:if>
<tr>
<th colspan="2">字典维护</th>
</tr>
<tr>
<th>类别名</th>
<td><input type="text" name="code" value="${model.code}"></td>
</tr>
<tr>
<th>字典名</th>
<td><input type="text" name="name" value="${model.name}"></td>
</tr>
<tr>
<th>字典值</th>
<td><input type="text" name="value" value="${model.value}"></td>
</tr>
<tr>
<th colspan="2">
<input type="submit" value="保存">
<input type="button" onclick="backToList()" value="取消">
</th>
</tr>
</table>
</form>
<script>
function backToList(){
location.href = '${path}/dicts';
}
</script>
</body>
</html>
其中dicts.jsp使用了jquery-3.1.1.min.js ,请放在 /ssm/src/main/webapp/static/目录下
step4.6部署运行应用
发布到tomcat8中,访问 http://localhost:8080/ssm/dicts
列表页面:
新增
编辑
删除一条我们新增的数据
Step5.代码地址及总结
代码已经提交Github https://github.com/yangshangwei/ssm
本篇博客我们按照顺序依次讲解了如何集成Spring Spring MVC MyBatis ,通过该示例了解了配置和基本的数据操作方法。