SSM框架整合(一)

整合SSM三大框架之:实现基本查询和添加

目录

〇、整体思路

一、新建项目

1.1、创建项目步骤

1.2、pom.xml

二、运行逻辑分析

2.1、加载配置文件

2.2、项目运行整体流程

三、搭建spring环境 

3.1、Spring的配置文件

3.2、详细代码示例

四、搭建springMVC

4.1、配置前端控制器

4.2、配置springMVC.xml

4.3、实例代码

五、整合Spring和SpringMVC

5.1、在web.xml中配置监听器

5.2、整合

六、搭建mybatis(可省略)

6.1、编写核心配置文件

6.2、dao

6.3、测试

七、整合spring和mybatis

7.1、spring的配置文件

7.2、在service中注入dao

7.3、在controller中注入service

7.4、添加数据(事务管理)

八、总结

8.1、创建项目结构

8.2、编写SSM项目

九、附件:源码

1、添加maven项目的支持pom.xml

2、web.xml

3、springmvc.xml

4、applicationContext.xml

5、准备实体类

6、发送请求

7、控制器类

8、service及其实现类

9、dao

10、视图--JSP页面

11、实例演示

添加


〇、整体思路

  1. 创建项目,添加各种支持(jar包),使用maven项目(注意配置maven仓库!),编写pom.xml。

  2. 要想整体使用SSM框架,则需要将SSM三个框架中每一个都能够独立编写正确,分别测试成功运行。

  3. SSM角色分析:

Spring:业务层,控制层。
        主要还是Controller。接受请求,向下级发布,并获取到结果,然后返回响应。
        java类的编写。依然是Controller包、dao包、service包(含实现类)、javaBean包(实体类)。
SpringMVC:表现层,视图层。
        在Controller中返回的字符串,通过注解的方式跳转到相对应的jsp页面。
MyBatis:持久层。
        连接数据库,通过得到dao中方法的调用,对数据库中的数据进行增删改查。
        注意:事务的操作。

一、新建项目

1.1、创建项目步骤

 创建之后,需等待一段时间(大概5分钟左右),则会看到项目中的webapp、main、resources等目录。
如果仍然没有,则右键--->添加框架支持---->web应用。

1.2、pom.xml

添加SSM项目中用到的各种jar包支持!

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.shq</groupId>
  <artifactId>SSM_test</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SSM_test Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
<!-- 1.spring   -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.8</version>
    </dependency>
<!--2.aop    -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.3.8</version>
    </dependency>
<!-- 3.织入   -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.6.8</version>
    </dependency>
<!--  4.springMVC  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.19.RELEASE</version>
    </dependency>
<!--  5. WEB  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.1.19.RELEASE</version>
    </dependency>
<!--  6.事务  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.3.8</version>
    </dependency>
<!--  7.jdbc  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.8</version>
    </dependency>
<!-- 8. spring测试   -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.3.8</version>
    </dependency>
<!-- 9.测试   -->

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>compile</scope>
    </dependency>
<!-- 10. mysql数据库   -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.25</version>
    </dependency>
<!--  11.servlet  -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
<!-- 12.jsp   -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
    </dependency>
<!--    13. jstl标签库-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
<!--  14.log4j日志  -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
<!-- 15.  slf4j:日志标准,不是一个日志实现   -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.6</version>
    </dependency>
<!-- 16. mybatis   -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.13</version>
    </dependency>
<!-- 17. mybatis整合spring   -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.1</version>
    </dependency>
<!--  18.c3p0连接池  -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>SSM_test</finalName>
  </build>
</project>

二、运行逻辑分析

2.1、加载配置文件

项目的运行,默认第一步会加载web.xml

在web.xml中配置以下几点:

  1. 解决中文字符乱码问题(CharacterEncodingFilter)。 ​ (这个需要写在其他配置前面,否则web.xml会报错) ​
  2. 配置spring监听器(ContextLoaderListener)和监听映射。(此项配置也需要靠前写) ​ 用于加载spring的配置文件applicationContext.xml。 ​ 由于默认只加载WEB-INF目录下,所以需要context-param做一个统一管理,设置配置文件路径。 ​
  3. 配置前端控制器(DispatcherServlet)及映射(servlet-mapping)。 ​
    1. 注意:要加载springmvc的配置文件。(通过控制器配置中的初始化参数init-param)

applicationContext.xml中的配置:

  1. 开启注解扫描,即支持代码中的注解。 ​在ssm中此处只用处理servcie和dao中的注解就行了,controller中的注解交给springMVC处理! ​
  2. spring整合mybatis。 ​
    1. 配置连接池。 ​ c3p0.ComboPooledDataSource连接数据库(之前用到的所谓“四大金刚”)。 ​
    2. 配置sqlSessionFactory工厂(SqlSessionFactoryBean)。 ​ 将连接池配置进去,则可以直接创建工厂。(可生成代理类) ​
    3. 映射扫描,扫描指定包(MapperScannerConfigurer)。 ​ 配置BankDao接口所在的包。 ​​
  3. 配置spring框架声明式事务管理。
    1. 配置事务管理器(DataSourceTransactionManager)。 ​ 传入连接池对象,进行事务管理。 ​
    2. 配置事务通知(tx:advice)。 ​ 引入事务管理器(transactionManager)。 ​ tx:attributes中可以使用tx:method设置事务的传播行为、隔离级别等等。 ​
    3. 配置AOP增强(aop:config)。 ​ 引用事务通知,切入表达式 。

springmvc.xml中启动注解扫描:

    1、开启注解扫描,只扫描controller中的注解。
    2、配置视图解析器对象。
    3、过滤静态资源:JS、CSS等
    4、开启springMVC注解的支持!!! 

2.2、项目运行整体流程

三、搭建spring环境 

3.1、Spring的配置文件

1、添加spring框架的各种约束。
2、开启注解扫描
3、要扫描的包路径:就是找到Controller的全路径。

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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--开启注解扫描,即支持代码中的注解
        此时将shq.itdemo中的所有注解都扫描了。在ssm中只用处理servcie和dao中的就行了。
        controller中的注解交给springMVC处理即可!
    -->
    <context:component-scan base-package="shq.itdemo">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>

3.2、详细代码示例

实体类


/**
 * 账户
 *    实现序列化接口   :需要传输或者说远程调用的对象都会实现Serializable接口
                 目的:第一个是便于存储,第二个是便于传输。
 * */
@Repository
public class Bank implements Serializable {

  private long id;
  private String username;
  private String money;

    /**
     * getter和setter
     * */
}

dao

/*
* 账户DAO接口
*	  
*  mybatis中接口会生成代理类,不需要再编写实现类。
	整合时使用注解写sql语句即可。
* */
public interface BankDao {
     //查询所有
    public List<Bank> findAll();
    //保存账户信息(新增操作)
    public void saveAccount(Bank Bank);
}

service实现类

@Service("bankService")// 👈👈👈此时 把service交给IOC容器去管理
public class BankServiceImpl implements BankService {
    @Override
    public List<Bank> findAll() {
        System.out.println("业务层:查询所有信息。。。");
        return null;
    }
    @Override
    public void saveAccount(Bank Bank) {
        System.out.println("业务层:保存账户信息。。。");
    }
}

测试类

public class TestSpring {
    @Test
    public void runSpring(){
        //加载配置文件(程序中spring配置文件可以起到作用)
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        //获取对象     引号中的bankService是实现类中注解的名字
        BankService as = (BankService) ac.getBean("bankService");
        //调用方法
        as.findAll();//此时可以调用到方法了
    }
}

选中方法名字,右键也可以运行。

注意:@Test这个注解,是因为在pom文件中添加了单元测试的支持,想运行,则必须要有这个注解!

控制台结果:正常运行。

至此,spring框架已成功运行!下一步,编写springMVC并测试!

四、搭建springMVC

4.1、配置前端控制器

web.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>
  <display-name>Archetype Created Web Application</display-name>
  <!--解决中文乱码的过滤器,写在前面,否则xml中会报错!!!-->
  <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> 
 <!--配置前端控制器-->
  <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>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

4.2、配置springMVC.xml

编写JSP访问页面。因为注解的原因,则能够跳转到对应的控制器servlet中,执行。结果返回一个字符串,该字符串则是对应视图JSP的名字。

springmvc.xml中主要有几大功能:

1、开启注解扫描,只扫描控制器controller中的注解

2、视图解析器对象(配置路径的前缀和后缀,以至于在类中返回的字符串能够直接跳转到对应jsp页面中)

3、过滤静态资源(否则在jsp中的静态资源,比如JS代码则不会起作用。)

4、开启springmvc注解的支持!!!

<?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="cn.shq">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
    </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>
<!--过滤静态资源:JS、CSS等-->
    <!--  可以使用此方法,分别对每种文件进行过滤。
   		<mvc:resources location="/css/" mapping="/css/**"/>
    	<mvc:resources location="/images/" mapping="/images/**"/>
    	<mvc:resources location="/js/" mapping="/js/**"/>
    -->
    <!--也可以使用这一种!-->
 	<mvc:default-servlet-handler/>
<!--开启springMVC注解的支持-->
    <mvc:annotation-driven/>
</beans>

4.3、实例代码

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <a href="/bank/findAll">测试</a>
</body>
</html>

Controller

@Controller
@RequestMapping("bank")
public class BankController {
    @RequestMapping("findAll")
    public String findAll(){
        System.out.println("view: OK");
        System.out.println("表现层:查询到。。。");
        return "result";  //  <---- 需要创建表示结果的JSP页面用于跳转。
        				//  参考👆xml中配置的目录,在对应的文件夹下创建JSP。
    }
}

运行测试。

注意:记得配置tomcat,将项目部署到tomcat服务器上。

测试发现:能够正常跳转result.jsp页面!

五、整合Spring和SpringMVC

主要思路:视图发送的请求即业务层,接受请求并返回响应的是控制层,整合这两步,即在控制器servlet中,如果能够成功调用到service中的方法,整合成功!

此时,控制器controller已经放入到容器中去管理,那么service也放入到容器中,则可以注入controller中。但是此时项目启动之后,web.xml中只是启动了springmvc.xml,扫描了controller中的注解,而applicationContext.xml没有启动,其他service、dao中的注解根本没起到作用。

5.1、在web.xml中配置监听器

因为spring的监听器默认情况下只加载根目录WEB-INF下的文件,

而我们配置的文件不在该目录下,所以需要context-param统一配置。

context-param标签需要写在前面,按照顺序!

<!--👇标签顺序:context-param 写在display-name后面-->

<!--因为配置文件放在了resources目录下,所以做一个统一管理,设置配置文件路径-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

<!--👇标签顺序:listener 写在filter过滤器的配置后面-->

<!--配置spring的监听器,默认只加载WEB-INF目录下的applicationContext.xml配置文件-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
 

5.2、整合

此时spring和springmvc都放入容器中,则可以利用依赖注入完成整合。

@Controller
@RequestMapping("bank")
public class BankController {

    @Autowired    //<-----自动注入service对象后 ,下面可以调用方法
    private BankService bankService;

    @RequestMapping("findAll")
    public String findAll(){
        System.out.println("view: OK");
        System.out.println("表现层:查询到。。。");
        bankService.findAll();  //  可以调用方法了。
        return "result";
    }
}

此时测试,则整合成功。

六、搭建mybatis(可省略)

mybatis的配置文件在整合后可以删除。所以此步骤可以省略。

如果想要体验一下,则可以按照以下步骤完成。

6.1、编写核心配置文件

SqlMybatisConfig.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.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///2101_files"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射配置文件-->
    <mappers>
        <!--之前的方式,使用配置文件写SQL语句,但现在使用的是注解的方式。比如@Select(),所以不用resource属性-->
        <!--<mapper resource="cn/shq/dao/xxx.xml"></mapper>
        	<mapper class="cn.shq.dao.AccountDao"/>
        	如果接口多了,则使用下面package更方便!
        -->
        <!--使用package则包内所有接口全部被扫描-->
        <package name="cn.shq.dao"/>
    </mappers>
</configuration>

6.2、dao

配置文件完成之后,编写dao中代码:

public interface BankDao {
    //查询所有
    @Select("select * from bank")
    public List<Bank> findAll();
    //保存账户信息(新增操作)
    @Insert("insert into bank(username,money) values (#{username},#{money})")
    public void saveAccount(Bank bank);
}

6.3、测试

 /*
    * 测试查询
    * */
    @Test
    public void testMybatis() throws IOException {
        //加载配置文件,输入流读取配置文件
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建sqlSessionFactory对象
        SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(is);
        //创建sqlSession对象
        SqlSession session = fac.openSession();
        //获取到代理对象
        BankDao dao = session.getMapper(BankDao.class);
        //调用方法,查询数据
        List<Bank> all = dao.findAll();
        for(Bank bank:all){
            System.out.println(bank);
        }
        //关闭资源
        session.close();
        is.close();
    }
    /*
    * 测试添加
    * */
    @Test
    public void testMybatis2() throws IOException {
        Bank account = new Bank();
        account.setUserName("卡丁");
        account.setMoney(850d);
        //加载配置文件,输入流读取配置文件
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建sqlSessionFactory对象
        SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(is);
        //创建sqlSession对象
        SqlSession session = fac.openSession();
        //获取到代理对象
        BankDao dao = session.getMapper(BankDao.class);
        //调用方法,添加数据
       dao.saveAccount(account);
       //提交事务
        session.commit();
        //关闭资源
        session.close();
        is.close();
    }

右键运行查询方法,控制台输出数据库中数据,则正确!

右键运行添加方法,查看数据库数据添加完成,则正确!

至此,mybatis环境搭建完成!

七、整合spring和mybatis

主要思路:service能够调用dao,对数据库数据进行操作,则成功。

此时,service的类已经放入容器中,而dao接口则可以通过程序生成代理对象,将代理对象存进IOC容器中,service则可以拿到dao对象,注入使用方法。

关键问题:怎样把生成的代理对象存进IOC容器中?

步骤:        1、把代理存入IOC容器

                   2、service注入dao对象

解决办法:编写spring配置文件即可!

7.1、spring的配置文件

applicationContext.xml:

 <!--spring整合mybatis-->
    <!--配置连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///ssm"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    <!--配置sqlsessionfactory工厂-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--将连接池配置进去,则可以直接创建工厂-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置BankDao接口所在的包-->
    <!-- 映射扫描,扫描指定包-->
    <bean id="mapperScan" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.shq.dao"/>
    </bean>

7.2、在service中注入dao

@Service("bankService")
public class BankServiceImpl implements BankService {
    @Autowired
    private BankDao dao;	// 👈  注入dao对象
    @Override
    public List<Bank> findAll() {
        System.out.println("业务层:查询所有信息。。。");
        List<Bank> all = dao.findAll();   // 👈 可以调用dao中方法
        return all;
    }
}

如果跳过上面第6步的操作(没有搭建mybatis,直接整合的话),则需要检查dao中代码👇:

public interface BankDao {
    @Select("select * from bank")
    public List<Bank> findAll();
    @Insert("insert into bank(username,money) values (#{username},#{money})")
    public void saveAccount(Bank Bank);
}

7.3、在controller中注入service

@Controller
@RequestMapping("bank")
public class BankController {
    @Autowired
    private BankService bankService;/*  <-----自动注入service对象 ,然后下面可以调用方法*/
    @RequestMapping("findAll")
    public String findAll(Model model){
        System.out.println("表现层:查询到。。。");
        List<Bank> all = bankService.findAll();  // 得到查询结果
        model.addAttribute("list",all);  
        return "result";
    }
}

查询整合完成!

7.4、添加数据(事务管理)

对数据库添加数据,则需要进行事务提交。

spring框架中提供声明式事务管理,需要在applicationContext.xml中配置

<!--配置spring框架声明式事务管理-->
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--传入连接池对象,进行事务管理-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置事务通知-->
    <!-- 引入事务管理器-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--以find开头的方法,只读事务-->
            <tx:method name="find*" read-only="true"/>
            <!--除了find开头的其他方法,可以设置传播行为、隔离级别等等-->
            <tx:method name="*" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>
    <!--配置AOP增强-->
    <aop:config>
<!--引用事务通知,切入表达式pointcut=execution(
     第一个public可省略,
     第二个返回值可以写*,
     第三个写包名。指定包名下ServiceImpl结尾的类中的所有方法..两个点表示所有类型、个数的参数)-->
        <aop:advisor advice-ref="txAdvice"
           pointcut="execution(public * cn.shq.service.impl.*ServiceImpl.*(..))"/>
    </aop:config>

至此,对service中的方法进行了事务管理操作。

页面上:

<h2>添加测试</h2>
   <form action="${pageContext.request.contextPath}/bank/saveInfo" method="post">
        姓名:<input type="text" name="username"><br>
        余额:<input type="text" name="money"><br>
        <input type="submit" value="保存">
    </form>

控制器中的方法:

 @RequestMapping("saveInfo")
    public void saveInfo(Bank bank, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println(bank);
        bankService.saveAccount(bank);
        //然后重新查询一下,重定向到查询方法。
        //需要用到请求和响应对象,所以声明request和response对象
        //获取到请求的全路径(项目路径拼接上查询的路径)
        response.sendRedirect(request.getContextPath()+"/bank/findAll");
        return;
    }

service中的添加方法:

  @Override
    public void saveAccount(Bank bank) {
        System.out.println("业务层:保存账户信息。。。");
        dao.saveAccount(bank);   //  ----->调用dao中方法,执行插入数据的操作。
    }

至此,整合完毕。

八、总结

8.1、创建项目结构

test包属于测试包,整合完毕可以删除!

mybatis的映射文件,在整合完毕之后也可以删除!

8.2、编写SSM项目

首先了解项目逻辑。

1、打开页面,发送请求。该请求直接访问到控制器类中的方法。(因为注解!

2、控制器类中接受请求,调用service中的方法。(此处是关键点!是spring和springmvc的整合

 此处重难点在于:
     spring中将对象放入IOC容器去管理,要想调用service中的对象,则需要将service的对象放入IOC容器,然后依赖注入则可以直接调用。       

3、service调用dao中方法(整合mybatis)。

 1、因为myBatis中接口会生成代理类,则此处dao接口不用手动书写实现类。
 2、sql语句则利用注解,直接卸载接口中方法上面。

4、连接数据库,对数据进行操作!

 在spring的配置文件中,整合mybatis。
 主要有以下几步:
         1、配置连接池
         2、配置sqslSessionFactory工厂
         3、配置映射扫描,指定需要扫描的包。

至此,请求已完成,接下来看响应。

5、控制器中类方法执行过后,得到一个结果。将该结果存入Model对象中,发送到JSP,显示在页面上。

返回一个字符串,则由于springmvc配置文件的原因,能够直接跳转到对应名称的JSP页面。(此处为spring和springmvc的整合

6、JSP页面对数据进行展示。

九、附件:源码

源码下载

1、添加maven项目的支持pom.xml

 具体代码在文档开头第一步。

2、web.xml

启动项目先执行web.xml。

    具体配置以下几点:
    1、配置spring的监听器。
        因为web.xml中没有加载spring的配置文件,又由于监听器默认只加载WEB-INF下的文件,而我们为了
        方便,将所有的配置文件都放在了resources目录下,所以需要做一下统一管理。配置一下文件路径,
        使得项目启动的时候,能够启动spring的配置文件applicationContext.xml。
    2、解决中文乱码问题的过滤器。
    3、配置前端控制器(DispatcherServlet)。
        在serlvet的配置中,直接初始化启动springmvc.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>
  <display-name>Archetype Created Web Application</display-name>
  <!--因为配置文件放在了resources目录下,所以做一个统一管理,设置配置文件路径-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!--解决中文乱码的过滤器,写在前面,否则xml中会报错!!!-->
  <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>
  <!--配置spring的监听器,默认只加载WEB-INF目录下的applicationContext.xml配置文件-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!--配置前端控制器-->
  <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>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

3、springmvc.xml

具体步骤:    

        1、开启注解扫描。只扫描Controller中的注解。
        2、配置视图解析器对象。
                目的是:为了使Controller中方法执行完成后,返回的字符串能够直接跳转到对应的JSP页面。
                需要配置路径的前缀和后缀。
        3、过滤静态资源。
            由于servlet配置中拦截的所有(/*),所以在JSP中使用的静态资源(JS代码,CSS样式,图片等)不
            会有对应的效果。再次需要过滤一下所有的静态资源。
        4、开启springMVC注解的支持    

完整配置代码:

<?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="cn.shq">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
    </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>
    <!--过滤静态资源:JS、CSS等-->
    <mvc:default-servlet-handler/>
    <!--开启springMVC注解的支持-->
    <mvc:annotation-driven/>
</beans>

4、applicationContext.xml

spring的配置文件主要有以下几个步骤:

        1、开启注解扫描。除了controller中的注解,扫描其余的注解。
        2、整合mybatis。
                2.1、配置连接池
                2.2、配置sqlSessionFactory工厂(为了创建工厂,生成代理类)
                2.3、扫描指定包。(dao包的路径)
        3、配置spring框架声明式事务管理。
            a、配置事务管理器(DataSourceTransactionManager)。
                传入连接池对象,进行事务管理。
            b、配置事务通知(tx:advice)。
                引入事务管理器(transactionManager)。
                tx:attributes中可以使用tx:method设置事务的传播行为、隔离级别等等。
            c、配置AOP增强(aop:config)。
                引用事务通知,切入表达式

完整代码:
 

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--开启注解扫描,即支持代码中的注解
        此时将cn.shq中的所有注解都扫描了。在ssm中只用处理servcie和dao中的就行了。
        controller中的注解交给springMVC处理即可!
    -->
    <context:component-scan base-package="cn.shq">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

<!--spring整合mybatis-->
    <!--配置连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///2101_files"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    <!--配置sqlsessionfactory工厂-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--将连接池配置进去,则可以直接创建工厂-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置BankDao接口所在的包-->
    <!-- 映射扫描,扫描指定包-->
    <bean id="mapperScan" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.shq.dao"/>
    </bean>

<!--配置spring框架声明式事务管理-->
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--传入连接池对象,进行事务管理-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置事务通知-->
    <!-- 引入事务管理器-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--以find开头的方法,只读事务-->
            <tx:method name="find*" read-only="true"/>
            <!--除了find开头的其他方法,可以设置传播行为、隔离级别等等-->
            <tx:method name="*" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>
    <!--配置AOP增强-->
    <aop:config>
        <!--引用事务通知,
        切入表达式pointcut=execution(
                第一个public可省略,
                第二个返回值可以写*,
                第三个写包名。指定包名下ServiceImpl结尾的类中的所有方法..两个点表示所有类型、个数的参数)-->
        <aop:advisor advice-ref="txAdvice"
                     pointcut="execution(public * cn.shq.service.impl.*ServiceImpl.*(..))"/>
    </aop:config>

</beans>

5、准备实体类

/**
 * 账户
 *    实现序列化接口
 * */
@Repository
public class Bank implements Serializable {

  private long id;
  private String username;
  private String money;

    /**
     * getter和setter
     * */
  /**
  	toString方法
  */
}

6、发送请求

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>测试首页</title>
</head>
<body>
    <a href="/bank/findAll">测试</a>
    <h2>添加测试</h2>
    <form action="${pageContext.request.contextPath}/bank/saveInfo" method="post">
        姓名:<input type="text" name="username"><br>
        余额:<input type="text" name="money"><br>
        <input type="submit" value="保存">
    </form>
</body>
</html>

7、控制器类

注意:

     1、类上使用controller注解(交由IOC容器管理)。
     2、类上的RequestMapping注解---请求访问路径的一级目录。
     3、方法上的RequestMapping注解---请求访问路径的二级目录。
     4、由于要调用servcie中的方法,所以将service对象放入IOC容器中。在类中需要进行注入。

完整代码:

package cn.shq.controller;

import cn.shq.entity.Bank;
import cn.shq.service.BankService;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Controller
@RequestMapping("bank")
public class BankController {

    @Autowired
    private BankService bankService;/*  <-----自动注入service对象 ,然后下面可以调用方法*/

    @RequestMapping("findAll")
    public String findAll(Model model){
        System.out.println("view: OK");
        System.out.println("表现层:查询到。。。");
        List<Bank> all = bankService.findAll();
        model.addAttribute("list",all);
        return "result";
    }

    @RequestMapping("saveInfo")
    public void saveInfo(Bank bank, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println(bank);
        bankService.saveAccount(bank);
        //然后重新查询一下,重定向到查询方法。
        //需要用到请求和响应对象,所以声明request和response对象
        //获取到请求的全路径(项目路径拼接上查询的路径)
        response.sendRedirect(request.getContextPath()+"/bank/findAll");
        return;
    }
}

8、service及其实现类

package cn.shq.service.impl;

import cn.shq.dao.BankDao;
import cn.shq.entity.Bank;
import cn.shq.service.BankService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("bankService")// 👈👈👈此时 把service交给IOC容器去管理
public class BankServiceImpl implements BankService {
    @Autowired
    private BankDao dao;
    @Override
    public List<Bank> findAll() {
        System.out.println("业务层:查询所有信息。。。");
        List<Bank> all = dao.findAll();
        return all;
    }
    @Override
    public void saveAccount(Bank bank) {
        System.out.println("业务层:保存账户信息。。。");
        dao.saveAccount(bank);
    }
}

9、dao

/*
* 账户DAO接口
*
*  mybatis中接口会生成代理类,不需要再编写实现类
* */
package cn.shq.dao;

import cn.shq.entity.Bank;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import java.util.List;

public interface BankDao {
    //查询所有
    @Select("select * from bank")
    public List<Bank> findAll();
    //保存账户信息(新增操作)
    @Insert("insert into bank(username,money) values (#{username},#{money})")
    public void saveAccount(Bank Bank);
}

10、视图--JSP页面

经过以上步骤,控制器类中得到一个查询结果----list。并且存放入Model对象中,返回一个字符串。则跳转至对应JSP页面。

result.jsp

<%--
  Created by IntelliJ IDEA.
  User: AdminSun
  Date: 2023/5/20
  Time: 11:38
  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>
</head>
<body>
        这是结果页面
        <h1>使用JSTL遍历输出</h1>
        <table width="20%"  border="1" cellspacing="0">
            <tr>
                <th>姓名</th>
                <th>金额</th>
            </tr>
            <c:forEach items="${list}" var="ac">
                <tr>
                    <td>${ac.username}</td>
                    <td>${ac.money}</td>
                </tr>
            </c:forEach>
        </table>
</body>
</html>

11、实例演示

查询功能

添加功能

 

SSM项目整合(阶段一)完成!  

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CiCi喜之郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值