【自学java笔记#第五十二天#】springmvc day03 手把手教你搭建一个ssm项目
一、创建数据库
create database ssm; use ssm; create table account(id int primary key auto_increment, name varchar(20),money double );
二、建立新项目,导入坐标
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.source>1.8</maven.compiler.source>
<spring.version>5.0.2.RELEASE</spring.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<mysql.version>5.1.6</mysql.version>
<mybatis.version>3.4.5</mybatis.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</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-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</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-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
</dependencies>
三、搭建基本环境
1、目录结构如下:

2、提供两个基本方法:
/** * 查询所有 * @return */ public List<Account> findAll(); /** * 保存账户信息 * @param account */ public void saveAccount(Account account);
3、实体类Account:
public class Account implements Serializable { private Integer id; private String name; private Double money; 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 getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + '}'; } }
4、Dao层采用动态代理技术,无需写实现类;表现层需要写实现类
四、首先确保spring框架的环境搭建是正确的
1、在service层实现类上添加注解:
@Service("accountService") public class AccountServiceImpl implements AccountService {
2、开启注解扫描:
<!--开启注解扫描,希望处理service和dao,controller不需要spring框架去处理-->
<context:component-scan base-package="com.lulu">
<!--配置哪些注解不扫描-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
因为spring框架只负责service和dao层,所以在这里将controller包排除在注解扫描的范围之内。
3、加入测试类:
public class TestSpring { @Test public void run1(){ //加载配置文件 ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); //获取对象 AccountService accountService = (AccountService) ac.getBean("accountService"); //调方法 accountService.findAll(); } }
4、运行结果:


说明spring框架的环境搭建是没有问题的。
5、此阶段遇到的问题:
Error:java: Compilation failed: internal java compiler error:
这是jdk版本和项目版本不匹配造成的,解决方案:
https://www.cnblogs.com/comeluder/p/8215317.html
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
没有引入log4j的配置文件造成的,解决方案:将log4j.properties文件放在resources目录下即可。
五、再确保springMVC框架的环境搭建是正确的
1、配置web.xml文件:
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载springmvc.xml配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--启动服务器,创建该servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--解决中文乱码的过滤器-->
<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>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2、配置springmvc.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--开启注解扫描,只扫描Controller注解--> <context:component-scan base-package="com.lulu"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--配置视图解析器对象--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--过滤静态资源--> <mvc:resources location="/css/" mapping="/css/**" /> <mvc:resources location="/images/" mapping="/images/**" /> <mvc:resources location="/js/" mapping="/js/**" /> <!--开启springmvc框架的注解支持--> <mvc:annotation-driven></mvc:annotation-driven> </beans>
3、完善springmvc的目录结构:

4、在处理器中编写方法:
/** * 账户web */ @Controller @RequestMapping("/account") public class AccountController { @RequestMapping("/testFindAll") public String findAll(){ System.out.println("表现层:查询所有账户"); return "list"; } }
5、测试结果:

到了这一步,说明springmvc的环境搭建得也是没有问题的。
六、spring整合springMVC框架
1、在web.xml文件中增加一个spring框架的监听器:
<!--配置spring的监听器,默认只加载WEB-INF目录下的applicationContext.xml配置文件-->
<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>
2、完善处理器的方法:注入service层对象,并调用它的方法:
/** * 账户web */ @Controller @RequestMapping("/account") public class AccountController { @Autowired private AccountService accountService; @RequestMapping("/testFindAll") public String findAll(){ System.out.println("表现层:查询所有账户"); //调用service的方法 accountService.findAll(); return "list"; } }
3、执行结果:

到这一步,spring框架已经成功完成了和springmvc框架的整合。
七、再确保Mybatis框架的环境搭建是正确的
1、完善AccountDao接口中的语句:
public interface AccountDao { /** * 查询所有 * @return */ @Select("select * from account") public List<Account> findAll(); /** * 保存账户信息 * @param account */ @Insert("insert into account(name,money) values(#{name},#{money})") public void saveAccount(Account account); }
2、配置SqlMapConfig.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"> <configuration> <!--配置环境--> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.10.102:3306/ssm"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!--引入映射配置文件--> <mappers> <package name="com.lulu.dao"></package> </mappers> </configuration>
3、往数据库里添加数据

4、加入测试类:
public class TestMybatis { @Test public void run1() throws Exception { //加载配置文件 InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml"); //创建SqlSessionFactory对象 SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in); //创建SqlSession对象 SqlSession sqlSession = build.openSession(); //获取代理对象 AccountDao dao = sqlSession.getMapper(AccountDao.class); //调用方法 List<Account> list = dao.findAll(); for(Account account:list){ System.out.println(account); } //释放资源 sqlSession.close(); in.close(); } }
5、测试结果:

到这一步,Mybatis的框架也搭建完成了。
八、spring整合mybatis框架
1、将SqlMapConfig.xml文件里面的内容,全部转移到applicationContext.xml文件中:
<!--spring整合mybatis框架-->
<!--配置连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql//192.168.10.102:3306/ssm"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<!--配置SqlSessionFactory工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置AccountDao接口所在的包-->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lulu.dao"></property>
</bean>
2、将dao层对象注入到service层实现类中:
@Service("accountService") public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Override public List<Account> findAll() { System.out.println("业务层查询所有账户信息"); return accountDao.findAll(); } @Override public void saveAccount(Account account) { System.out.println("业务层保存账户"); accountDao.saveAccount(account); }
3、将dao层接口加上@Repository注解,交给Ioc容器去管理:
@Repository public interface AccountDao {
//省略中间的内容
}
4、对list页面做了一些改动:
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2020/5/26 Time: 10:49 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> </head> <body> <h3>查询了所有的账户信息</h3> <c:forEach items="${list}" var="account"> ${account.money} </c:forEach> </body> </html>
5、运行结果:

网页输出:

6、此阶段遇到的问题:
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
错误原因:配置连接池时,写错了jdbc的配置(少写了一个:号)
错误写法:
<property name="jdbcUrl" value="jdbc:mysql//192.168.10.102:3306/ssm"></property>
正确写法:
<property name="jdbcUrl" value="jdbc:mysql://192.168.10.102:3306/ssm"></property>
到这一步,三大框架整合基本上已经完成了。但是目前还是只能正常地执行查询操作,保存操作执行起来可能会有问题。所以我们还需要配置事务管理。
九、配置事务管理
1、完善applicationContext.xml文件:
<!--配置Spring框架声明式事务管理-->
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" isolation="DEFAULT"></tx:method>
</tx:attributes>
</tx:advice>
<!--配置AOP增强-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.lulu.service.impl.AccountServiceImpl.*(..))"/>
</aop:config>
2、再在处理器里写一个保存的测试方法:
@RequestMapping("/testSave") public void testSave(Account account, HttpServletRequest request,HttpServletResponse response) throws Exception { System.out.println("表现层:查询所有账户"); //调用service的方法 accountService.saveAccount(account); response.sendRedirect(request.getContextPath()+"/account/testFindAll"); return; }
3、从index.jsp处提交表单:
<form action="account/testSave" method="post"> 姓名:<input type="text" name="name"><br> 金额:<input type="text" name="money"><br> 提交:<input type="submit" value="保存"> </form>
4、运行结果:

网页输出:

5、此阶段遇到的问题:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountService': Unsatisfied dependency expressed through field 'accountDao';
错误原因:配置AOP的pointcut时,路径少写了一个类
错误写法:
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.lulu.service.impl.*(..))"/>
</aop:config>
正确写法:
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.lulu.service.impl.AccountServiceImpl.*(..))"/>
</aop:config>
A C3P0Registry mbean is already registered. This probably means that an application using c3p0 was undeployed, but not all PooledDataSources were closed prior to undeployment. This may lead to resource leaks over time. Please take care to close all Pooled
错误原因:大概是在这一个Tomcat服务器上部署了两个以上的项目,所以导致连接关闭不及时。
解决方案:在配置c3p0提供的连接池时,需要配一个destory-method属性,如下:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
到了这里,最基本的SSM框架就完全搭建成功啦!
浙公网安备 33010602011771号