本文通过图文的方式详细介绍了通过IDEA如何搭建一个SSM项目,对于那些对IDEA不熟悉或者之前没有使用过IDEA的小伙伴是非常友好的。项目已经上传到github,地址:https://github.com/gitlxp1101/ssm_demo.git
打开IDEA,点击如下图红框圈住的选项
细心的小伙伴可能就会发现,这种方式创建的项目是缺少存放类和资源的目录的,所有需要我们自己去创建。
鼠标右键选择main目录 -> New -> Directory,给新建目录起名为“java”
新建的“Java”目录是不会被识别成存放类的目录的,需要进行标记,才能被识别。具体操作为: 鼠标右键选择main目录 -> New -> Mark Directory as -> Sources Root
这里我简单解释下 Mark Directory as 选项展示的标记部分具体作用(大家应该也能从这些选项看出具体作用):
步骤与上步骤基本一致,需要将resources目录标记为:Resources Root
这个项目结构也同样确实测试目录,需要我们自己构建
2.6.1 在src目录下创建一个“test”目录,与“main”目录是同级的
2.6.2 在“test”目录下分别创建“java”目录和“resources”目录,分别标记为“Test Sources Root”和“Test ReSources Root”(这里参考上一节,步骤是差不多的)
这里我先所有需要用到依赖放在下面了
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>ssm_demo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>ssm_demo Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <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> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <org.springframework.version>4.0.0.RELEASE</org.springframework.version> <org.mybatis.version>3.4.1</org.mybatis.version> <org.mybatis.spring.version>1.3.0</org.mybatis.spring.version> </properties> <dependencies> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>7.0.64</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.3</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${org.mybatis.spring.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${org.mybatis.version}</version> </dependency> <!-- mybatis pager --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.0</version> </dependency> <!--集成druid连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!-- MyBatis 生成器 --> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>20.0</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!--<scope>test</scope>--> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.3</version> </dependency> <!-- id加密解密 --> <dependency> <groupId>org.hashids</groupId> <artifactId>hashids</artifactId> <version>1.0.1</version> </dependency> <!-- file upload --> <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.0.1</version> </dependency> </dependencies> <build> <finalName>ssm_demo</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build></project>复制代码
在web.xml中配置一个监听器,用于tomcat容器启动后加载Spring的配置文件,这里我给Spring的配置文件起名为:applicationContext.xml,在resources目录下。
这里简单介绍两个常用标签
4.2.1 包扫描
4.2.1 切面
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.example" annotation-config="true"/> <aop:aspectj-autoproxy/> </beans>复制代码
如果在web.xml同级目录下配置 "拦截器名-servlet.xml",springmvc会自动扫描该文件。如我配置的拦截器名字为“dispatcher”,那么与web.xml同目录下的 “dispatcher-servlet.xml” 就会被扫描。
<?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" xmlns:aop="http://www.springframework.org/schema/aop" 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"> <!--只扫描com.example.controller下的注解--> <!--use-default-filters=false:不使用默认扫描--> <context:component-scan base-package="com.example.controller" annotation-config="true" use-default-filters="false"> <!--只扫描Controller的bean--> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter> </context:component-scan> <!--使用@Response注解的时候,可以对返回的类型转换成Json字符串--> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 文件上传 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760"/> <!-- 10m --> <property name="maxInMemorySize" value="4096" /> <property name="defaultEncoding" value="UTF-8"></property> </bean> </beans>复制代码
<?xml version="1.0" encoding="UTF-8"?> <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_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Archetype Created Web Application</display-name> <!--字符串过滤--> <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>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext.xml </param-value> </context-param> <!--配置springmvc的拦截规则,如果在web.xml同级目录下配置 "拦截器-servlet.xml",springmvc会自动扫描该文件。--> <!--如我配置的拦截器名字为dispatcher,那么与web.xml同目录下的 dispatcher-servlet.xml 就会被扫描--> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>复制代码
至此,我们已经完成了Spring+SpringMVC的整合,接下来我们先测试下有没有问题
5.6.1 在IDEA中配置该项目,用于启动
5.6.1.1 如图所示,IDEA顶部点击“Edit Configurations”
5.6.1.2 参考下图配置
5.6.1.3 点击就能看到如下图配置页面
5.6.1.4 先给项目命个名:ssm_demo
5.6.1.5 这里也可以修改启动端口号,这里我就不改了,使用默认的8080
5.6.1.6 该配置页效果,细心的小伙伴看到了下面有一个警告,缺少“artifact”,接下来就要配置这个了。
5.6.1.7 配置artifact
按如图方式添加一个artifact,记住选择带exploded结尾的版本,等会说下具体原因。
5.6.1.8 热发布
简单说下,就是程序在debug运行时,修改代码后,不需要重启项目也能看到修改后的结果。让我们回到最开始的配置页面,按下图方式配置。然后点击ok。完成
5.6.1.9 运行
配置好后,就能看到下面的结果了,店家绿色的三角形可以启动项目,就可以在浏览器下面的结果。
我们这里写个测试用的Controller,然后再浏览器中看下。
6.1.1 新建一个“com.example.mbg”包,用于存放生成这些文件的代码
6.1.2 Generator.java
package com.example.mbg; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * 用于生产MBG的代码 * Created by macro on 2018/4/26. */ public class Generator { public static void main(String[] args) throws Exception { //MBG 执行过程中的警告信息 List warnings = new ArrayList(); //当生成的代码重复时,覆盖原代码 boolean overwrite = true; //读取我们的 MBG 配置文件 InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(is); is.close(); DefaultShellCallback callback = new DefaultShellCallback(overwrite); //创建 MBG MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); //执行生成代码 myBatisGenerator.generate(null); //输出警告信息 for (String warning : warnings) { System.out.println(warning); } } }复制代码
6.1.3 配置 generatorConfig.xml
上节代码中可以看到我们需要一个generatorConfig.xml(在resources目录下创建)文件,用于配置生成的信息。具体内容在我已经放在了下面,注释也写在里面,大家可以看下。
<?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> <properties resource="datasource.properties"/> <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat"> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <property name="javaFileEncoding" value="UTF-8"/> <!-- 为模型生成序列化方法--> <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/> <!-- 为生成的Java模型创建一个toString方法 --> <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/> <!--生成mapper.xml时覆盖原文件--> <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" /> <!--配置数据库连接--> <jdbcConnection driverClass="${jdbc.driverClass}" connectionURL="${jdbc.connectionURL}" userId="${jdbc.userId}" password="${jdbc.password}"> <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题--> <property name="nullCatalogMeansCurrent" value="true" /> </jdbcConnection> <!--指定生成model的路径--> <javaModelGenerator targetPackage="com.example.domain" targetProject="./src/main/java"/> <!--指定生成mapper.xml的路径--> <sqlMapGenerator targetPackage="mapper" targetProject="./src/main/resources"/> <!--指定生成mapper接口的的路径--> <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.dao" targetProject="./src/main/java"/> <!--生成全部表tableName设为%,指定表名就只会创建出一个表的相关文件--> <table tableName="%"> <generatedKey column="id" sqlStatement="MySql" identity="true"/> </table> </context> </generatorConfiguration>复制代码
6.1.4 datasource.properties
generatorConfig.xml需要数据库的连接信息,我放在了datasource.properties(在resources目录下创建)。下面展示下generator.properties的内容,大家根据自己的情况进行修改
jdbc.driverClass=com.mysql.jdbc.Driver #选择要配置的数据库 jdbc.connectionURL=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai #数据库用户名 jdbc.userId=root #数据库的密码 jdbc.password=123456复制代码
6.2.1 在resources目录下新建一个 applicationContext-datasource.xml用于数据库和mybatis的配置。
applicationContext-datasource.xml
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--用于加载属性文件--> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="2"/> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="locations"> <list> <value>classpath:datasource.properties</value> </list> </property> <property name="fileEncoding" value="utf-8"/> </bean> <!-- 基于Druid数据库链接池的数据源配置 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 基本属性driverClassName、 url、user、password --> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="${jdbc.connectionURL}" /> <property name="username" value="${jdbc.userId}" /> <property name="password" value="${jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <!-- 通常来说,只需要修改initialSize、minIdle、maxActive --> <property name="initialSize" value="2" /> <property name="minIdle" value="2" /> <property name="maxActive" value="30" /> <property name="testWhileIdle" value="false" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="5000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="30000" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 解密密码必须要配置的项 --> <property name="filters" value="config" /> <property name="connectionProperties" value="config.decrypt=false" /> </bean> <!--配置mybatis SqlSessionFactoryBean--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath*:mapper/*Mapper.xml"></property> </bean> <bean name="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.dao"/> </bean> <!-- 使用@Transactional进行声明式事务管理需要声明下面这行 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> <!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> <property name="rollbackOnCommitFailure" value="true"/> </bean> </beans>复制代码
6.2.2 在applicationContext.xml中引入applicationContext-datasource.xml
6.2.3 测试
6.2.3.1 在测试类TestController添加如下,然后启动tomcat
6.2.3.2 在浏览器中输入如下,可以看到结果
6.2.3.3 该数据库文件我放在的resources/db目录下,需要的小伙伴可以自己去添加到自己的数据库中