序言
一个简单的SSM小项目,使用一个系列讲解,文章题目均使用“SSM-”开头。所用到的技术栈有:
- 前端框架Vue
- 后台框架-SSM(SpringMVC+Spring+MyBatis)
- 数据库-MySQL
- 项目的依赖管理-Maven
- 分页-pagehelper
- 逆向工程-MyBatis Generator
- 等等…
1.创建项目
- 创建一个Maven,勾选Create from archetype,选择maven-archetype-webapp
- 信息有没有显示 BUILD SUCCESS。
- 如果速度太慢可以配置MAVEN镜像。
- 检查编译器是不是8版本。默认1.7改成1.8
<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>
</properties>
- 创建文件夹Directory。创建时Maven Resource Directories一栏,默认存在这些文件名。在src目录下,可以一起创建完成。
- main下的java、resources。
- src下的test\java、test\resources
- 配置pom.xml
- 注释掉或删除<Build>
- 引入依赖
<dependencies>
<!--引入spring-mvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
<!--引入spring-jdbc,支持事务相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.8</version>
</dependency>
<!--引入spring aspects切面编程-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.8</version>
</dependency>
<!--引入mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--引入mybatis整合spring的适配包, 一定要引入-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!--引入druid数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
<!--引入mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>
- 配置Tomcat
- Add Configuration…
- Tomcat Server/local ,Deployment/Artifact/war exploded
- 测试
此时可以启动一下Tomcat,查看是否正常使用,出现“Hello World”。
操作时,出现过没有web.xml的情况,不知道是选错archetype模板了,还是什么其他原因。所以每一步的测试很重要。
2.项目全局配置web.xml
- 配置启动spring容器。添加到web.xml的<web-app>下。
- 再在resources目录下new-> XML-> Spring Cofig文件,命名为applicationContext.xml。
- 它和使用New-> File创建xml文件的区别在于,Spring Config的xml文件是有文件头的。虽然不起眼,但是会影响后面的测试是否正常。
//该web.xml文件,以及文件头应当是自动生成的。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!-- 1、配置启动Spring容器:
主要配置和业务逻辑有关的,比如数据源,事务控制等-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--
ContextLoaderListener: 监听器
1、ContextLoaderListener监听器作用是启动Web容器时,自动装配ApplicationContext的配置信息
2、它实现了ServletContextListener接口,在web.xml配置该监听器,启动容器时,会默认执行它实现的方法
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
- 继续在web.xml配置springMVC的前端控制器,拦截所有请求
<!--
1、配置前端控制器/中央控制器/分发控制器
2. 用户的请求都会经过它的处理
3. 因为没有指定springmvc的配置文件,那么就会默认按照 servlet-name-servlet.xml 来获取
4. 读取配置文件的原理,我在前面讲解springmvc时讲过.
-->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--在web项目启动时,就自动的加载DispatcherServlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<!--说明
1. 这里我们配置的url-pattern是 / ,表示用户的请求都经过 DispatcherServlet
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
3.依然在web.xml字符编码过滤器,解决中文乱码问题。一定要放在其他过滤器最前面。
(如果web.xml的报红,选择只是高亮选择syntax即可,本身没有问题,就是DTD的约束)
<!--配置Spring提供的过滤器,解决中文乱码问题
解读
1. forceRequestEncoding 配置成 true ,表示该过滤器会执行 request.setCharacterEncoding(encoding);
2. forceRequestEncoding 配置成 true, 表示该过滤器会执行 response.setCharacterEncoding(encoding);
-->
<filter>
<filter-name>CharacterEncodingFilter</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>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- web.xml最后配置HiddenHttpMethodFilter
<!--配置HiddenHttpMethodFilter
1. 使用Rest风格的URI,可以把页面发过来的post请求转为指定的delete或者put请求
2. 配置url-pattern 是 /* 表示请求都经过 hiddenHttpMethodFilter过滤
-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.SpringMVC配置
- 创建springMVC的配置文件springDispatcherServlet-servlet.xml:包含网站跳转逻辑的控制。文件名称的组成为:servletname+'-servlet’组成,springmvc会自动读取这个文件
- 需要在WEB-INF这个目录下,按照new-> XML-> Spring Config的方式创建
- 创建项目相关的包
- 配置扫描com.stein.furns包的控制器。都是配置在<bean>标签内部,context需要引入,根据实际配置扫描路径。
<!-- 解读
1. 扫描com.stein.furns包
2. use-default-filters="false" 禁用默认过滤规则
3. context:include-filter 配置说明 只是扫描控制器
-->
<context:component-scan base-package="com.hspedu.furn">
<!--SpringMvc只是扫描Controller-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
- 配置视图解析器。根据这儿的配置,把views文件夹创建好
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置属性suffix 和 prefix-->
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".html"/>
</bean>
- 两个常规配置。这儿mvc也需要引入。
- 支持SpringMVC的高级功能,比如JSR303校验, 映射动态请求
- 将springmvc不能处理的请求,交给tomcat处理,比如css, js
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:default-servlet-handler/>
- 测试:编写相应类,以及views/hi.html页面。
@Controller
public class TestController {
@RequestMapping("/hi")
public String hi(){
System.out.println("TestController-hi()");
return "hi";
}
}
遇到过的问题:曾出现Tomcat没能启动,原因竟然就是applicationContext.xml这个文件是New->File这样的方式创建的,没有文件头,导致Tomcat无法启动。
4.配置Spring和MyBatis,并完成整合
- spring的配置文件application.xml:主要配置和业务逻辑有关,比如数据源,事务控制等
- 此配置用配置说明,不扫描控制器@Controller
- 因为它在SpringMVC管理的springDispatcherServlet-servlet.xml里面已经扫描了。
- context需要引用。配置路径根据需要自行修改。
<beans> //此行用来说明以下内容在这个标签里面。
<context:component-scan base-package="com.hspedu.furn">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
- 配置resources/jdbc.properties,用于配置数据库连接
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/furn_ssm?useSSL=true&useUnicode=true&characterEncoding=UTF-8
jdbc.user=root
jdbc.pwd=root
- 配置数据源
<!--引入外部的jdbc.properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置数据源对象-DataSoruce Druid数据源-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="pooledDataSource">
<!--给数据源对象配置属性值-->
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pwd}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
</bean>
- 配置spring与mybatis的整合(已经添加到步骤1的代码中了)
<!--引入mybatis整合spring的适配包, 一定要引入-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
applicationContext.xml中的整合。需要新建文件夹resources/mapper
<!--配置mybatis和spring整合
1、在项目中引入 mybatis整合到spring的适配库/包
2. 这里爆红,是因为你还没有相应的文件, 当有文件时,就不会爆红
-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<!--指定mybatis全局配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--指定数据源-->
<property name="dataSource" ref="pooledDataSource"/>
<!--指定mybatis的mapper文件[Mapper.XML]位置
1、我们在开发中, 通常将mapper.xml放在类路径 resources/mapper
2. 所以这里指定的value 是 classpath:mapper/*.xml
-->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
- 将mybatis的接口实现加入到ioc容器,在applicationContext.xml配置
<!-- 配置扫描器,将mybatis接口的实现加入到ioc容器中
1、我们的mapper接口放在com.stein.furn.dao
2. mybatis就是处于DAO层, 操作DB
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--
1. 扫描所有的dao接口的实现,加入到ioc容器中
2. 这里dao接口,就是mapper接口
-->
<property name="basePackage" value="com.hspedu.furn.dao"/>
</bean>
- 配置事务控制,在applicationContext.xml配置
<!--配置事务管理器-对象
1. DataSourceTransactionManager 这个对象是进行事务管理
2. 一定要配置数据源属性,这样指定该事务管理器 是对哪个数据源进行事务控制
-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="pooledDataSource"/>
</bean>
- 配置启动基于注解的声明式事务管理功能。二选一
<tx:annotation-driven transaction-manager="transactionManager"/>
- 或者使用这种方法:开启基于注解的事务(使用XML配置+切入表达式),并指定切入点
<!--
解读
1. execution(* com.hspedu.furns.service..*(..)):
表示对com.hspedu.furns.service包所有类的所有方法控制事务
2. tx:advice : 配置事务增强, 也就是指定事务如何切入
-->
<aop:config>
<!-- 切入点表达式 -->
<aop:pointcut id="txPoint" expression="execution(* com.stein.furn.service..*(..))"/>
<!-- 配置事务增强/规则: 使用txAdvice 指定规则对 txPoint进行切入-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>
<!-- 配置事务增强【指定事务规则】,也就是指定事务如何切入-->
<tx:advice id="txAdvice">
<tx:attributes>
<!-- *代表所有方法都是事务方法-->
<tx:method name="*"/>
<!-- 以get开始的所有方法 ,我们认为是只读,进行调优-->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
- 测试
public class Test {
@org.junit.Test
public void t1(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ioc.getBean("pooledDataSource"));
System.out.println(ioc.getBean("sqlSessionFactory"));
}
}
5.创建表,使用逆向工程生成Bean、XxxMapper和XxxMapper.xml
使用MyBatis Generator逆向工程生成bean mapper接口和mapper.xml
在pom.xml引入包
<!-- 引入mybatis逆向工程依赖包 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
创建并配置mbg.xml文件。放在项目目录下,挨着pom.xml。官方文档
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 生成没有注释的bean-->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 配置数据库连接信息-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/furn_ssm?characterEncoding=utf8"
userId="root"
password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 指定javaBean生成的位置-->
<javaModelGenerator targetPackage="com.stein.furn.bean" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 指定sql映射文件生成的位置
1. 要根据自己的实际情况指定
-->
<sqlMapGenerator targetPackage="mapper" targetProject=".\src\main\resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 指定dao接口生成的位置, 也就是mapper接口-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.stein.furn.dao" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 指定要逆向生成的表和生成策略-->
<table tableName="furn" domainObjectName="Furn"></table>
</context>
</generatorConfiguration>
运行该逆向工程的java代码。官方代码
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("mbg.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
注意事项
- insertSelective 和 insert 的区别
- insertSelective–选择性保存数据;
- 而 insert 则是不论设置多少个字段,统一都要添加一遍,不论你设置几个字段,即使是一个
- sqlSession会自动关闭放回连接池,不用自己设置关闭