前面学习了很多在SSM中要使用的东西,Mybatis,Freemarker等,今天终于到了要整合一整个可用框架的时候了
项目源码:源码下载
~~
这篇东西有点多,不过如果你看了前面的几篇文章的话,这篇文章应该很简单,没有看也没有关系,只要按照这篇文章里的做绝对可以搭出来并成功运行,前提我代码里的注释很重要,一定要看注释
~~
Spring SpringMVC Mybatis整合
Spring SpringMVC 整合
创建项目与整体目录与所需文件
- src/main下创建目录webapp
- webapp下创建目录WEB-INF
- WEB-INF下创建文件web.xml
- WEB-INF下创建文件夹ftl,用于存放网页静态资源
- resources下创建应用上下文applicationContext.xml
- 创建java类文件夹,用于存放java类
- 最终项目目录结构如下
pom.xml配置
打包方式改为war
<packaging>war</packaging>
增加jetty插件
<build>
<plugins>
<!--引入jetty插件-->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.14.v20181114</version>
<configuration>
<!--增加配置去读取jetty自定义配置,让其生效-->
<webApp>
<!--防止无法热部署异常,此文件180行改为false-->
<defaultsDescriptor>src/main/resources/webdefault.xml</defaultsDescriptor>
</webApp>
<!--配置应用启动后加载webapp的网页与资源-->
<webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>
<!--设置http连接器相关属性-->
<httpConnector>
<!--启动端口,不写默认与tomcat一致,为8080-->
<port>80</port>
</httpConnector>
</configuration>
</plugin>
</plugins>
</build>
导入jetty的webdefault.xml
此文件不导入的话,修改页面后可能会报错,此文件一般在.m2里的如下目录,直接复制到项目的resources下
修改其中的180行,值改为false,如果版本不同也可能不是180行,那就找useFileMappedBuffer
光导入此文件还不行,还需要在pom.xml中进行引用才可以,上面引入jetty插件的时候已经引用好了
增加SpringMVC配置
<dependency>
<groupId>org.springframework</groupId>
<!--SpringMVC 最核心的依赖-->
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
加入json序列化支持包
<!--json start-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<!--自动与springmvc框架结合-->
<artifactId>jackson-annotations</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<!--自动与springmvc的数据绑定-->
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!--json end-->
加入Freemarker支持包
<!--Freemarker核心jar包-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<!--SpringFreemarker整合第三方组件的支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
阿里云仓库设置
如果有下载不下来的包可以设置阿里云仓库,也可以不设置
<!--阿里云中央仓库-->
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<!--maven.aliyun.com-->
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
web.xml配置
头文件声明
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
Servlet相关配置
<!--SpringMVC最核心的servlet:DispatcherServlet-->
<servlet>
<servlet-name>ssm</servlet-name>
<!--拦截请求,创建对应的Controller进行处理-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--指明DispatcherServlet初始化时加载的配置文件-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--启动程序时对Servlet进行加载 0:优先级最高-->
<load-on-startup>0</load-on-startup>
</servlet>
<!--spring mvc 影射 ,启用上面的Servlet需要作以下配置-->
<servlet-mapping>
<servlet-name>ssm</servlet-name>
<!-- / :拦截所有请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
如果上面的有关Servlet的东西都设置好后,还有红线的话,有可能是没有引入Servlet相关包引起的,pom.xml中引入相关包
<!--拦截器所用java servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>compile</scope>
</dependency>
乱码处理
<!--此项配置为POST提交参数乱码处理配置,使用TOMCAT时必须配置,使用jetty时无须配置,jetty自带了乱码配置-->
<filter>
<filter-name>characterFilter</filter-name>
<!--CharacterEncodeingFilter 将Post请求中的参数字符集设置为UTF-8-->
<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>characterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
应用上下文相关
头声明
<?xml version="1.0" encoding="UTF-8" ?>
<!--
//mvc命名空间,用于对mvc进行控制和配置
xmlns:mvc="http://www.springframework.org/schema/mvc"
//引入context命名空间,用于启用注解
xmlns:context="http://www.springframework.org/schema/context"
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
</beans>
启用SpringMVC注解扫描
<!--启用Spring注解形式扫描对象-->
<context:component-scan base-package="com.zhangyx"></context:component-scan>
<!--启用SpringMVC的注解模式-->
<mvc:annotation-driven>
<mvc:message-converters>
<!--StirngHttpMessageConverter 用于设置文本类型http响应的设置-->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<!--配置支持的媒体类型(MIME)-->
<property name="supportedMediaTypes">
<list>
<!--响应输出的文本被浏览器作为html进行解释,使用字符集为UTF-8-->
<value>text/html;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--将静态资源排队在外,用于提高执行效率【img,js,css等】-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
FreeMarker相关
<!--freemarker配置
FreemarkerViewResolver是Spring-Context-Support提供的整合类,
在IOC容器初始化时通知SpringMVC默认使用Freemarker进行数据展现-->
<bean id="ViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<!--设置响应输出并解决中文乱码问题-->
<property name="contentType" value="text/html;charset=utf-8"></property>
<!--指定Freemarker文件扩展名-->
<property name="suffix" value=".ftl"></property>
</bean>
<!--Freemarker设置类-->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!--设置模板保存目录,后端跳转时不用再写这个目录-->
<property name="templateLoaderPath" value="/WEB-INF/ftl"></property>
<!--模板引擎其他设置-->
<property name="freemarkerSettings">
<props>
<!--设置Freemarker脚本与数据渲染时使用的字符集-->
<prop key="defaultEncoding">UTF-8</prop>
</props>
</property>
</bean>
到这里Spring与SpringMVC的框架算是搭建完成了,下面继续Spring 与Mybatis框架
Spring 与Mybatis整合
大概四步
- pom.xml依赖spring-jdbc、mybatis、mybatis-spring、druid
- applicationContext.xml配置数据源
- applicationContext.xml配置会话工厂sqlSessionFactory
- applicationContext.xml配置MapperScannerConfigurer
<!--SM整合 start-->
<!--spring为jdbc做的扩展组件,简化jdbc底层操作-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<!--Mybatis核心组件-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
<!--最主要的,Spring与Mybatis整合全领先Mybatis机构的这个包
springframework并没有对mybatis进行支持-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!--Druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.13</version>
</dependency>
<!--jdbc驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!--SM整合 end-->
<!--mybatis整合配置-数据源
Mybatis与Spring整合是指SessionFactory对象不再由我们程序自己创建
而改为使用配置方式由SpringIOC容器创建与管理
这样做的好处是,配置方便,并在此基础上为Mybatis扩展很多额外的功能
-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&characterEncodeing=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--定义sqlSessionFactory连接工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--关联数据源,value指向上面的数据源-->
<property name="dataSource" ref="dataSource"/>
<!--mybatis配置文件地址-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--mapper XML文件保存目录
之前是在mybatis-config.xml 里写的 <mapper resource="goods.xml">-->
<property name="mapperLocations" value="classpath:mappers/*.xml"/>
</bean>
<!--Spring为Mybatis提供了一种新的开发方式“Mapper接口”
这个配置用于扫描com.zhangyx.ssm包下所有有效的Mapper接口类-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zhangyx.ssm"/>
</bean>
resources下创建对应文件与文件夹
mappers文件夹
mybatis-config.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">
<!--头文件以及下面的配置,都可以在官网上找到
地址:https://mybatis.org/mybatis-3/zh/getting-started.html
-->
<configuration>
</configuration>
测试
测试时发现,这是因为mappers文件夹是空的,下面必须有文件才行,我这里随便创建了一个README.text,运行成功
@Controller
public class HelloController {
@GetMapping("/hello")
public ModelAndView hello(){
ModelAndView mv = new ModelAndView("/hello");
return mv;
}
}
其中遇到的坑 1.driverClassName不要写错了 2.引入数据源dataSource时要用ref,不要用value
Mapper接口开发
mapper接口开发要素
- Mapper.xml里的namespace指向接口,不能随意书写了
- Mapper.xml Sql方法 ID要与接口方法名一致
- 接口方法参数会直接传入到SQL中,多参时参数前加@Param
- 方法返回值可以是List对象,也可以是单个对象,Mybatis会自动判断
相应包创建
实体类包:com.zhangyx.ssm.entity-存放与数据库对应的实体类
接口类包:com.zhangyx.ssm.mapper-存放与SQL xml 文件对应的接口类
mybatis-config.xml设置
驼峰命名转换
<settings>
<!--驼峰命名转换-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
mapper接口类-一般命名标准ClassMapper.java
注意:看注释,此代码里的注释与下面的SQL.xml里的注释结合来看
public interface GoodsMapper {
/*SQL.xml中的SQL ID 要与此方法名保持一致
SQL.xml中的取值key也要与这里的参数名保持一致
*/
Goods findById(Integer goodsId);
}
SQL.xml-跟之前有很大区别
mappers下创建goods_mapper.xml
注意:看注释,此代码里的注释与上面的mapper接口里的注释结合来看
<?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">
<!--spring整合了Mybatis后,此处的namespace要指向我们的接口类-->
<mapper namespace="com.zhangyx.ssm.mapper.GoodsMapper">
<!--id:跟上面的namespace一样,要与接口中的方法名保持一致,指向接口中的findById方法名
参数类型也要与接口方法中的保持一致,返回数据类型一样
上层(service)调用时会直接调用到这里去请求数据库
此xml可以看作是我们之前的dao的实现类,我是这样理解的-->
<select id="findById" parameterType="Integer" resultType="com.zhangyx.ssm.entity.Goods">
select * from t_goods where goods_id = #{value }
</select>
</mapper>
测试 service层省略
@Resource
private GoodsService goodsService;
@GetMapping("/goods")
public ModelAndView goodsInfo(){
ModelAndView mv = new ModelAndView("/goods");
Goods goods = goodsService.findById(739);
mv.addObject("goods",goods);
return mv;
}
多参数(条件),多数据返回
多参数多条件查询时,有两种方式
- 利用Map传参
- 利用@Param
Map 形式
sql.xml
注意parameterType,resultType
<select id="list" parameterType="java.util.Map" resultType="com.zhangyx.ssm.entity.Goods">
select * from t_goods where category_id = #{categoryId} and current_price < #{currentPrice}
</select>
mapper 接口
List<Goods> list(Map params);
controller
@GetMapping("/list")
public ModelAndView list(){
ModelAndView mv = new ModelAndView("/list");
/*利用Map传参*/
Map param = new HashMap();
param.put("categoryId",40);
param.put("currentPrice",800);
List<Goods> goodsList = goodsService.list(param);
mv.addObject("goodsList",goodsList);
return mv;
}
@Param形式
SQL.xml不变
mapper接口如下
/*@Param("参数名"),将参数封装到Map里,参数名作为Map里的key,后面的参数值category作为对应map的值*/
List<Goods> list(@Param("categoryId") Integer category,@Param("currentPrice") Float currentPrice);
controller类
@GetMapping("/list")
public ModelAndView list(){
ModelAndView mv = new ModelAndView("/list");
/*利用Map传参*/
// Map param = new HashMap();
// param.put("categoryId",40);
// param.put("currentPrice",800);
/*直接传*/
List<Goods> goodsList = goodsService.list(40,800f);
mv.addObject("goodsList",goodsList);
return mv;
}