教你如何使用IDEA + Maven 搭建SSM Web项目
- 前言
- 1. 环境
- 2. 前期准备
- 3. 开始创建工程
- 4. 调整IDEA自动创建的工程目录
- 4.1 创建源代码路径
- 4.2 创建test路径
- 4.3 创建resource路径
- 4.4 整个的目录结构
- 4.5 修改pom.xml文件
- 4.6 增加Mybatis配置文件
- 4.7 增加数据库连接基本参数配置文件
- 4.8 增加Spring配置文件
- 4.9 配置web.xml文件
- 5. 配置Tomcat尝试跑一下
- 6. 类的创建
- 6.1 创建Employee类
- 6.2 创建EmployeeDao类
- 6.3 增加Mapper文件
- 6.4 创建EmployeeDao的测试类
- 6.5 创建EmployeeService类,调用Dao层代码
- 6.6 创建EmployeeAction类,调用Service层代码
- 6.7 创建用户注册页面register.jsp
- 6.8 创建提示页面message.jsp
- 7. 最终效果
- 8. 可能遇到的坑
- 参考
前言
本文将带你一步一步使用IDEA搭建SSM项目(Spring SpringMVC Mybatis)。最终所实现的效果是通过访问用户注册界面(http://localhost/register.jsp),将新用户添加进MySQL数据库。通过post方法访问http://localhost/emp/getAll,获取所有用户信息的json数据。
1. 环境
java version:12.0.2
maven版本:3.6.1
MySQL版本:5.x
2. 前期准备
创建数据库:
CREATE DATABASE mybatisdb;
创建表:
create table employee(
eid int(5) primary key,
ename varchar(20),
esalary double(8,2),
esex varchar(2)
);
3. 开始创建工程
1.File->New->Project…
2.选择Maven项目
3.填写项目信息
3.设置Maven
我在这里选择的是我自己下载的一个maven,maven的源已经被我在settings.xml中设置成了阿里的源,如果不设置的将会导致下载jar包时消耗很长的时间。设置方法就不在这里讲了,网上教程一大堆。
4.选择项目存放路径,最后点Finish
此时的项目结构如下:
4. 调整IDEA自动创建的工程目录
4.1 创建源代码路径
右键main文件夹---->new—>Directory,取名为java
将该目录设置为源代码路径
创建包com.yky,并在包中创建domain、dao、service、controller。创建好的包目录如下:
4.2 创建test路径
右键src—>new—>Directory,取名为test。在新创建的test目录下创建java文件夹,并设置为test的根目录
在test/java目录下创建com.yky.dao包,用于存放dao层的测试代码
4.3 创建resource路径
创建resource路径专门用来存放配置文件
右键main文件夹—>new->Directory,取名为resource。并设置为resource根路径
为了让配置文件看起来不乱,在resource目录下创建mapper目录,专门用来存放Mybatis的mappper文件。
在WEB-INF下创建jsp目录,用来专门存放jsp。
4.4 整个的目录结构
至此,目录就创建完成了。完整的目录结构如下:
4.5 修改pom.xml文件
想要使用Spring 、SpringMVC、Mybatis,我们需要用Maven导入相关的jar包。配置pom.xml文件如下:
注意这里的jdk版本设置成了12,如果使用的jdk版本与我的不同,请做出相应的更改。最后记得import一下。
<?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.yky</groupId>
<artifactId>ssm-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>ssm-test 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>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- spring版本号 -->
<spring.version>4.3.5.RELEASE</spring.version>
<!-- mybatis版本号 -->
<mybatis.version>3.4.1</mybatis.version>
<java.version>12</java.version>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<dependencies>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 实现slf4j接口并整合 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.2</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.0.pr3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0.pr3</version>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
<scope>runtime</scope>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis/spring整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
<scope>runtime</scope>
</dependency>
<!--servlet API-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
<build>
<finalName>ssm-test</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.0.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.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</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>
4.6 增加Mybatis配置文件
在resource目录下创建mybatis.xml文件,该文件只需要针对mapper文件进行配置,数据库连接相关操作不在本文件中配置,交由Spring来管理!
<?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>
<mappers>
<!--一会儿会在这里导入Mapper文件-->
</mappers>
</configuration>
4.7 增加数据库连接基本参数配置文件
在resource目录下新建jdbc.properties,并写入以下内容
database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/mybatisdb
database.username=root
database.password=123456
4.8 增加Spring配置文件
数据库的连接、SqlSession的创建、Mybatis事务的管理都交由Spring来管理。可以看到Spring配置文件中有读取jdbc.properties文件,拿到数据库的连接参数,从而去链接数据库;Spring配置文件中有配置sqlSessionFactory,并导入了先前创建的mybatis.xml配置文件。
在resource目录下新建applicationContext.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: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/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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置数据库相关参数properties的属性:${url} -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置C3P0连接池,目的:管理数据库连接 -->
<bean id="comboPooledDataSourceID" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${database.driver}"/>
<property name="jdbcUrl" value="${database.url}"/>
<property name="user" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<!-- 配置SqlSessionFactoryBean,目的:加载mybaits配置文件和映射文件,即替代原Mybatis工具类的作用 -->
<bean id="sqlSessionFactoryBeanID" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis.xml"/>
<property name="dataSource" ref="comboPooledDataSourceID"/>
</bean>
<!-- 配置Mybatis的事务管理器,即因为Mybatis底层用的是JDBC事务管事器,所以在这里依然配置JDBC事务管理器 -->
<bean id="dataSourceTransactionManagerID" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="comboPooledDataSourceID"/>
</bean>
<!-- 配置事务通知,即让哪些方法需要事务支持 -->
<tx:advice id="tx" transaction-manager="dataSourceTransactionManagerID">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务切面,即让哪些包下的类需要事务 -->
<!-- <aop:config>-->
<!-- <aop:pointcut id="pointcut" expression="execution(* com.yky.service.EmpService.addEmp(..))"/>-->
<!-- <aop:advisor advice-ref="tx" pointcut=""/>-->
<!-- </aop:config>-->
<!--
(1)导入jackson-annotations-2.10.0.jar、jackson-core-2.10.0.jar、jackson-databind-2.10.0.jar这三个jar包
配置JSON适配器
-->
<bean id="mappingJackson2HttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>text/json;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
<!--开启以注解的方式来管理事务-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManagerID"/>
<!--扫描注解-->
<context:component-scan base-package="com.yky"/>
</beans>
4.9 配置web.xml文件
做好了上面的准备工作后,配置web.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xis="http://www.w3.org/2001/XMLSchema-instance"
xis:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>client</display-name>
<!--配置前置控制器 -->
<servlet>
<servlet-name>ClientDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ClientDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--欢迎文件-->
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
至此,关键配置文件添加完毕!再来看一看目录结构:
5. 配置Tomcat尝试跑一下
基础准备工作已经完成,接下来配置Tomcat尝试跑一下,看欢迎界面能否出来
Run—>Edit Configurations 弹出以下界面
添加Tomcat服务器
按照下面的步骤选择
改一下Application context,改完点确定
运行服务器,访问看一下
6. 类的创建
6.1 创建Employee类
package com.yky.domain;
public class Employee {
private Integer id;
private String name;
private Double salary;
private String sex;
public Employee(){}
public Employee(Integer id, String name, Double salary, String sex) {
this.id = id;
this.name = name;
this.salary = salary;
this.sex = sex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
", sal=" + salary +
", sex='" + sex + '\'' +
'}';
}
}
6.2 创建EmployeeDao类
package com.yky.dao;
import com.yky.domain.Employee;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class EmployeeDao
{
@Autowired
private SqlSessionFactory sqlSessionFactory;
/**
* 增加员工
*/
public void add(Employee emp) throws Exception
{
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("empNamespace.add",emp);
sqlSession.commit();
}
public List<Employee> getAll() throws Exception
{
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession.selectList("empNamespace.getAll");
}
}
6.3 增加Mapper文件
在resource/mapper下新建EmployeeMapper.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="empNamespace">
<resultMap type="com.yky.domain.Employee" id="empMap">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="salary" column="esalary"/>
<result property="sex" column="esex"/>
</resultMap>
<!-- 增加员工 -->
<insert id="add" parameterType="com.yky.domain.Employee">
insert into employee(eid,ename,esalary,esex) values(#{id},#{name},#{salary},#{sex})
</insert>
<select id="getAll" resultMap="empMap">
select * from employee;
</select>
</mapper>
mybatis.xml文件导入Mapper文件
<configuration>
<mappers>
<mapper resource="mapper/EmployeeMapper.xml"/>
</mappers>
</configuration>
6.4 创建EmployeeDao的测试类
测试代码如下:
package com.yky.dao;
import com.yky.domain.Employee;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
import static org.junit.Assert.*;
public class EmployeeDaoTest {
ApplicationContext applicationContext;
public void init()
{
//加载Spring配置文件
applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void add() throws Exception
{
Employee employee = new Employee();
employee.setId(3);
employee.setName("tom");
employee.setSalary(11000D);
employee.setSex("男");
init();
EmployeeDao employeeDao = (EmployeeDao) applicationContext.getBean("employeeDao");
employeeDao.add(employee);
}
@Test
public void getAll() throws Exception {
init();
EmployeeDao employeeDao = (EmployeeDao) applicationContext.getBean("employeeDao");
List<Employee> employees = employeeDao.getAll();
System.out.println(employees);
}
}
运行效果:
6.5 创建EmployeeService类,调用Dao层代码
package com.yky.service;
import com.yky.dao.EmployeeDao;
import com.yky.domain.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class EmployeeService
{
@Autowired
private EmployeeDao employeeDao;
@Transactional
public void addEmp(Employee emp) throws Exception {
employeeDao.add(emp);
}
public List<Employee> getAllEmp() throws Exception{
return employeeDao.getAll();
}
}
6.6 创建EmployeeAction类,调用Service层代码
package com.yky.controller;
import com.yky.domain.Employee;
import com.yky.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("/emp")
//@RestController
public class EmployeeAction
{
@Autowired
private EmployeeService employeeService;
@RequestMapping("/register")
public String register(Model model, Employee emp) throws Exception
{
System.out.println("用户注册");
employeeService.addEmp(emp);
System.out.println("注册成功");
model.addAttribute("message","注册成功");
return "/WEB-INF/jsp/message.jsp";
}
@RequestMapping("/getAll")
public @ResponseBody
List<Employee> getAll() throws Exception
{
System.out.println("获取所有用户");
return employeeService.getAllEmp();
}
}
6.7 创建用户注册页面register.jsp
<%--
Created by IntelliJ IDEA.
User: danxi
Date: 2019/10/31
Time: 9:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>员工注册</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/emp/register" method="POST">
<table border="2" align="center">
<tr>
<th>编号</th>
<td><input type="text" name="id"></td>
</tr>
<tr>
<th>姓名</th>
<td><input type="text" name="name"></td>
</tr>
<tr>
<th>薪水</th>
<td><input type="text" name="salary"></td>
</tr>
<tr>
<th>性别</th>
<td>
<input type="radio" name="sex" value="男"/>男
<input type="radio" name="sex" value="女" checked/>女
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="注册"/>
</td>
</tr>
</table>
</form>
</body>
</html>
6.8 创建提示页面message.jsp
<%--
Created by IntelliJ IDEA.
User: danxi
Date: 2019/10/31
Time: 11:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>提示</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
7. 最终效果
浏览器访问http://localhost/register.jsp
成功注册
通过postman成功拿到json数据:
8. 可能遇到的坑
8.1 JDK版本不匹配导致报错
解决方法:
步骤1:file—>Progect structure确保以下几个位置的版本一致
步骤2:settings—>Build,Execution,Deployment—>Compiler—>java Compiler
通过以上两部就解决了JDK版本不一致的问题。
8.2 明明已经在Maven中导入了相关jar包还报错
诸如以下形式的错误:
java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter
java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
此时查看spring配置文件和web.xml文件中的相关类也可以点进去。
其实问题所在是tomcat的WEB-INF下没有lib文件所致,既然没有,那就把它加进去!
file—>Progect structure—>Artifacts
右键点击最右侧的工程名,选择Put into Output Root,点击后发现左侧的WEB-INF下多了lib文件,这样的话这个问题就解决了!