Spring - SpringMVC - MyBatis
1、jar包
commons-dbcp2-2.6.0.jar mybatis-spring-1.3.1.jar spring-context-4.3.9.RELEASE.jar spring-tx-4.3.9.RELEASE.jar
commons-logging-1.1.1.jar mysql-connector-java-5.1.18.jar spring-context-support-4.3.9.RELEASE.jar spring-web-4.3.9.RELEASE.jar
commons-pool2-2.6.1.jar ojdbc7-12.1.0.2.jar spring-core-4.3.9.RELEASE.jar
log4j-1.2.16.jar spring-aop-4.3.9.RELEASE.jar spring-expression-4.3.9.RELEASE.jar
mybatis-3.5.0.jar spring-beans-4.3.9.RELEASE.jar spring-jdbc-4.3.9.RELEASE.jar spring-webmvc-4.3.9.RELEASE.jar
二、整合Spring与MyBatis
1、创建对应的类和表
a、创建表
SearchRecord表结构如下:
mysql> desc SearchRecord;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| starttime | datetime | YES | | NULL | |
| endtime | datetime | YES | | NULL | |
| keyword | varchar(512) | YES | | NULL | |
| result_type | int(11) | YES | | NULL | |
| findcounts | int(11) | YES | | NULL | |
| keyword_findcounts | int(11) | YES | | NULL | |
+--------------------+--------------+------+-----+---------+----------------+
WebInfo表结构如下:
mysql> desc WebInfo;
+-----------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| parentid | int(11) | YES | | NULL | |
| starttime | datetime | YES | | NULL | |
| endtime | datetime | YES | | NULL | |
| ip | varchar(30) | YES | | NULL | |
| url | varchar(1024) | YES | | NULL | |
| savepath | varchar(512) | YES | | NULL | |
| result | int(11) | YES | | NULL | |
+-----------+---------------+------+-----+---------+----------------+
b、创建对应实体类
SearchRecord类
package com.fifi.ssm.entity;
import java.util.Date;
public class SearchRecord {
private int id;
private Date starttime;
private Date endtime;
private String keyword_string;
private int result_type;
private int findcounts;
private int keword_findcounts;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getStarttime() {
return starttime;
}
public void setStarttime(Date starttime) {
this.starttime = starttime;
}
public Date getEndtime() {
return endtime;
}
public void setEndtime(Date endtime) {
this.endtime = endtime;
}
public String getKeyword_string() {
return keyword_string;
}
public void setKeyword_string(String keyword_string) {
this.keyword_string = keyword_string;
}
public int getResult_type() {
return result_type;
}
public void setResult_type(int result_type) {
this.result_type = result_type;
}
public int getFindcounts() {
return findcounts;
}
public void setFindcounts(int findcounts) {
this.findcounts = findcounts;
}
public int getKeword_findcounts() {
return keword_findcounts;
}
public void setKeword_findcounts(int keword_findcounts) {
this.keword_findcounts = keword_findcounts;
}
@Override
public String toString() {
return "SearchRecord : { id="+this.getId()
+",keyword = "+this.getKeyword_string()
+",resulttype = "+this.getResult_type()
+",findcounts = "+this.getFindcounts()
+",keywordfindcounts = "+this.getKeword_findcounts()
+",starttime = "+this.getStarttime()
+",endtime = "+this.getEndtime()
+" }";
}
}
WebInfo类
package com.fifi.ssm.entity;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
public class WebInfo {
private int id;
private int parentid;
@DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss")//2019-01-01
private Date starttime;
@DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss")//2019-01-01
private Date endtime;
private String ip;
private String url;
private String savepath;
private int result;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getParentid() {
return parentid;
}
public void setParentid(int parentid) {
this.parentid = parentid;
}
public Date getStarttime() {
return starttime;
}
public void setStarttime(Date starttime) {
this.starttime = starttime;
}
public Date getEndtime() {
return endtime;
}
public void setEndtime(Date endtime) {
this.endtime = endtime;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSavepath() {
return savepath;
}
public void setSavepath(String savepath) {
this.savepath = savepath;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
@Override
public String toString() {
return "WebInfo : { id="+this.getId()
+",ip = "+this.getIp()
+",parentid = "+this.getParentid()
+",result = "+this.getResult()
+",savepath = "+this.getSavepath()
+",url = "+this.getUrl()
+",starttime = "+this.getStarttime()
+",endtime = "+this.getEndtime()
+" }";
}
}
2、定义DAO接口及mapper.xml文件
a、定义DAO接口类
接口SearchRecordMapper:
package com.fifi.ssm.mapper;
import java.util.ArrayList;
import com.fifi.ssm.entity.SearchRecord;
public interface SearchRecordMapper {
public int addSearchRecord(SearchRecord record);
public boolean deleteSearchRecord(int recrordId);
public ArrayList<SearchRecord> getSearchRecords();
public SearchRecord findSearchRecord(int id);/*@Param("condition")String condition,@Param("filter")String filter*/
}
接口WebInfoMapper:
package com.fifi.ssm.mapper;
import java.util.ArrayList;
import com.fifi.ssm.entity.WebInfo;
public interface WebInfoMapper {
public int addWebInfo(WebInfo webInfo);
public boolean deleteWebInfo(int id);
public ArrayList<WebInfo> getWebInfos();
public WebInfo findWebInfoById(int id);
public ArrayList<WebInfo> findWebInfoByIP(String ip);
}
b、创建mapper.xml文件
SearchRecordMapper.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.fifi.ssm.mapper.SearchRecordMapper">
<insert id="addSearchRecord" parameterType="com.fifi.ssm.entity.SearchRecord" useGeneratedKeys="true" keyProperty="id">
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
insert into SearchRecord(starttime,endtime,keyword,result_type,findcounts,keyword_findcounts)
values(#{starttime},#{endtime},#{keyword_string},#{result_type},#{findcounts},#{keword_findcounts});
</insert>
<delete id="deleteSearchRecord" parameterType="java.lang.Integer">
delete from SearchRecord where id=#{id}
</delete>
<select id="findSearchRecord" parameterType="java.lang.Integer" resultType="com.fifi.ssm.entity.SearchRecord">
select * from SearchRecord where id=#{id}
</select>
<select id="getSearchRecords" resultType="com.fifi.ssm.entity.SearchRecord">
select * from SearchRecord
</select>
</mapper>
WebInfoMapper.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.fifi.ssm.mapper.WebInfoMapper">
<insert id="addWebInfo" parameterType="com.fifi.ssm.entity.WebInfo" useGeneratedKeys="true" keyProperty="id">
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
insert into WebInfo(parentid,starttime,endtime,ip,url,savepath,result) values
(#{parentid},#{starttime},#{endtime},#{ip},#{url},#{savepath},#{result});
</insert>
<delete id="deleteWebInfo" parameterType="java.lang.Integer">
delete from WebInfo where id=#{id}
</delete>
<select id="findWebInfoById" parameterType="java.lang.Integer" resultType="com.fifi.ssm.entity.WebInfo">
select * from WebInfo where id=#{id}
</select>
<select id="getWebInfos" resultType="com.fifi.ssm.entity.WebInfo">
select * from WebInfo
</select>
<select id="findWebInfoByIP" parameterType="java.lang.String" resultType="com.fifi.ssm.entity.WebInfo">
select * from WebInfo where ip=#{ip}
</select>
</mapper>
3、在applicationContext.xml中配置mybatis相关的配置。
1)、创建db.properties文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/webinfo
username=root
password=pwd
maxIdle=6
maxActive=10
2)、在applicationContext.xml中配置,通过 bean 加载db.properties文件
<!-- 通过 bean 加载db.properties文件 -->
<bean id="config" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="locations">
<array>
<value>classpath:db.properties</value>
</array>
</property>
</bean>
3)、配置数据库信息(数据源) 替代mybatis配置文件 conf.xml
<!-- 配置数据库信息 替代mybatis配置文件 conf.xml -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${driverClassName}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
<!--
<property name="maxIdle" value="${maxIdle}"></property>
<property name="maxActive" value="${maxActive}"></property>
-->
</bean>
4)、在spring ioc容器中,创建 mybatis的核心类 SqlSessionFactory
<!-- 在spring ioc容器中,创建 mybatis的核心类 SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 加载mybatis配置文件
<property name="configLocation" value="classpath:conf.xml"></property>
-->
<!-- 加载mapper配置文件 -->
<property name="mapperLocations" value="classpath:com/fifi/ssm/mapper/*.xml">
</property>
</bean>
5)、批量产生的mapper对象,默认的IOC容器中的ID值,为首字母小写的接口名,如: webInfoMapper
<!-- 批量产生的mapper对象,默认的IOC容器中的ID值,为首字母小写的接口名,如: webInfoMapper -->
<bean id="mappers" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!-- 指定mapper接口所在的包,多个包用逗号分隔开 -->
<property name="basePackage" value="com.fifi.ssm.mapper"></property>
</bean>
三、整合Spring 与 SpringMVC
1、在项目中引入Spring支持:
在web.xml中配置ContextLoaderListener监听器,ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。
在web.xml中,输入contextloaderlistener,IDE会自动补全相关配置如下:
<!-- 在WEB项目中,引入Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
将<param-value>location</param-value>改成我们spring配置文件applicationContext.xml的路径:
<param-value>classpath:applicationContext.xml</param-value>
2、在web.xml中配置SpringMVC支持
在web.xml中配置DispatcherServlet,将所有的请求交给SpringMVC处理
<!-- 整合SpringMVC : 为项目加入SpringMVC支持-->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-controller.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3、配置springmvc配置文件applicationContext-controller.xml
a、配置视图解析器 (InternalResourceView)
<!-- 配置视图解析器 (InternalResourceView)-->
<bean id="internalResourceView"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
b、加入mvc:annotation-driven,此配置是springmvc的基础配置,很多功能都需要此配置来协调
<!-- 此配置是springmvc的基础配置,很多功能都需要此配置来协调 -->
<mvc:annotation-driven ></mvc:annotation-driven>
c、加入对静态文件访问的支持(非必须)
<!-- 该配置会让springmvc接收一个请求,并且如果该请求没有对应的@RequestMapping时,将请求交给tomcat处理 -->
<!-- 当然该配置是基于mvc:annotation-driven之上的,所以要达到直接访问静态资源的效果还要加上mvc:annotation-driven的配置 -->
<mvc:default-servlet-handler/>
四、使用搭建好的SSM框架
1、创建相关服务接口和实现类
IWebInfoService接口
package com.fifi.ssm.service;
import java.util.ArrayList;
import com.fifi.ssm.entity.WebInfo;
public interface IWebInfoService {
public int addWebInfo(WebInfo webInfo);
public boolean deleteWebInfo(int id);
public ArrayList<WebInfo> getWebInfos();
public WebInfo findWebInfoById(int id);
public ArrayList<WebInfo> findWebInfoByIP(String ip);
}
对应IWebInfoService的实现类: WebInfoServiceImpl,
package com.fifi.ssm.service;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.fifi.ssm.entity.WebInfo;
import com.fifi.ssm.mapper.WebInfoMapper;
@Service("webInfoService")
public class WebInfoServiceImpl implements IWebInfoService{
@Autowired //自动装配,byType
@Qualifier("webInfoMapper") //@Autowired + @Qualifier :byName(byid)的方式自动装配
private WebInfoMapper webInfoMapper;
@Override
public int addWebInfo(WebInfo webInfo) {
// TODO Auto-generated method stub
int id=webInfoMapper.addWebInfo(webInfo);
return webInfo.getId();
}
@Override
public boolean deleteWebInfo(int id) {
// TODO Auto-generated method stub
boolean b=webInfoMapper.deleteWebInfo(id);
return b;
}
@Override
public ArrayList<WebInfo> getWebInfos() {
// TODO Auto-generated method stub
ArrayList<WebInfo> webInfos=webInfoMapper.getWebInfos();
return webInfos;
}
@Override
public WebInfo findWebInfoById(int id) {
// TODO Auto-generated method stub
WebInfo webInfo=webInfoMapper.findWebInfoById(id);
return webInfo;
}
@Override
public ArrayList<WebInfo> findWebInfoByIP(String ip) {
// TODO Auto-generated method stub
ArrayList<WebInfo> webInfos=webInfoMapper.findWebInfoByIP(ip);
return webInfos;
}
}
这里采用了注解的方式来注入bean : @Service("webInfoService"),
注入属性也同样采用自动装配注释来实现:@Autowired + @Qualifier
将webInfoMapper注入到属性
private WebInfoMapper webInfoMapper;
当中去的,
这个类的实例是由applicationContext.xml中的
<!-- 第三种方式,批量配置多个mapper -->
<!-- 批量产生的mapper对象,默认的IOC容器中的ID值,为首字母小写的接口名,如: webInfoMapper -->
<bean id="mappers" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!-- 指定mapper接口所在的包,多个包用逗号分隔开 -->
<property name="basePackage" value="com.fifi.ssm.mapper"></property>
</bean>
这个配置生成的。产生的mapper对象的ID,是默认规则:为首字母小写的接口名,如: webInfoMapper
2、后台创建controller类,使用@RequestMapping注解进行映射,调用WebInfoService中的Mapper对象来操作数据库的。
SpringMvcHandler类:
package com.fifi.ssm.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.fifi.ssm.entity.WebInfo;
import com.fifi.ssm.service.IWebInfoService;
@Controller
@RequestMapping("handler")
public class SpringMvcHandler {
@Autowired
@Qualifier("webInfoService")
IWebInfoService webInfoService;
@RequestMapping("testGetWebInfo")
public ModelAndView testGetWebInfo() {
List<WebInfo> webInfos= webInfoService.getWebInfos();
ModelAndView modelAndView=new ModelAndView("showall");
modelAndView.addObject("webInfos", webInfos);
return modelAndView;
}
@RequestMapping("testAddWebInfo")
public String testAddWebInfo(WebInfo webInfo,HttpServletRequest request) {
//WebInfo webInfo=new WebInfo();
int id=webInfoService.addWebInfo(webInfo);
request.setAttribute("winfo", webInfo);
return "webinfo";
}
}
这里也是用的注解,自动装配方式将WebInfoService来注入到SpringMvcHandler的属性当中的:
@Autowired
@Qualifier("webInfoService")
IWebInfoService webInfoService;
注意:注入时,不要配置与注解混合使用。如果注入bean时,用的配置,那么属性也要用配置的方式。如果是用注解的方式注入bean时,使用@Autowired +@Qualifier 的方式自动装配
3、前端
a、前端请求页面
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%@ page import="java.util.Date"%>
<%@ page import="java.text.*" %>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link type="text/css" rel="stylesheet" href="css/style.css"></link>
</head>
<body>
<form action="handler/testAddWebInfo" class="white-pink">
<h1>添加</h1>
<label>
<span>parentid :</span>
<input id="parentid" type="text" name="parentid" placeholder="parentid" />
</label>
<label>
<span>starttime :</span>
<input id="starttime" type="text" name="starttime"
value="<%=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) %>"
placeholder="starttime" />
</label>
<label>
<span>endtime :</span>
<input id="endtime" type="text" name="endtime"
value="<%=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) %>"
placeholder="endtime" />
</label>
<label>
<span>ip :</span>
<input id="ip" type="text" name="ip" placeholder="ip" />
</label>
<label>
<span>url :</span>
<input id="url" type="text" name="url" placeholder="url" />
</label>
<label>
<span>savepath :</span>
<input id="savepath" type="text" name="savepath" placeholder="savepath" />
</label>
<label>
<span>result :</span>
<input id="result" type="text" name="result" placeholder="result" />
</label>
<label>
<span> </span>
<input type="submit" value="添加记录"></input>
</label>
</form>
<br/>
<form action="handler/testGetWebInfo" class="white-pink">
<h1>查询</h1>
<label>
<span> </span>
<input type="submit" value="所有记录"></input>
</label>
</form>
<br/>
</body>
</html>
这个页面因为使用了Date和SimpleDateFormat,所以需要在 index.jsp页面的头部引入两个包
<%@ page import="java.util.Date"%>
<%@ page import="java.text.*" %>
由于要格式化前端传给后端的日期格式,所以需要在MVC的配置文件applicationContext-controller.xml中,添加对格式化的支持:
<!-- 数据格式化 -->
<!-- 配置数据格式化 注解 所依赖的bean -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
</set>
</property>
</bean>
<!-- 此配置是springmvc的基础配置,很多功能都需要此配置来协调 -->
<mvc:annotation-driven conversion-service="conversionService">
</mvc:annotation-driven>
b、两个显示界面
webinfo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>显示webinfo</title>
<link type="text/css" rel="stylesheet" href="/SSMProject/css/style.css"></link>
</head>
<body>
<form action="" class="white-pink">
<h1>WebInfo</h1>
<label>
<span>parentid :</span>
<span> ${requestScope.winfo.parentid}</span>
<br>
</label>
<br>
<label>
<span>starttime :</span>
</label>
<span>${requestScope.winfo.starttime}</span>
<br><br>
<label>
<span>endtime :</span>
</label>
<span> ${requestScope.winfo.endtime}</span>
<br><br>
<label>
<span>ip :</span>
<span> ${requestScope.winfo.ip}</span>
<br>
</label>
<br>
<label>
<span>url :</span>
<span> ${requestScope.winfo.url}</span>
<br>
</label>
<br>
<label>
<span>savepath :</span>
<span> ${requestScope.winfo.savepath}</span>
<br>
</label>
<br>
<label>
<span>result :</span>
<span> ${requestScope.winfo.result}</span>
<br>
</label>
<br>
</form>
</body>
</html>
showall.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>显示所有</title>
<link type="text/css" rel="stylesheet" href="/SSMProject/css/style.css"></link>
</head>
<body>
<form action="" class="white-pink">
<h1>WebInfo List</h1>
<c:forEach var="item" items="${requestScope.webInfos}">
<span>id : ${item.id} , </span>
<span>url : ${item.url} , </span>
<span>savepath : ${item.savepath} </span>
<br/><br/>
</c:forEach>
</form>
</body>
</html>
这里因为使用了JSTL语言,所以需要导入两个包
jstl-1.2.jar和standard-1.1.2.jar
还需要在showall.jsp页面头部包含 <taglib> 标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
五、效果图:
1、请求页面
2、点击添加后跳转到的显示页面
3、点击所有记录,显示所有记录的界面
六、项目结构
1、总结构
2、类结构
3、view及资源目录结构
4、jar包