SSM整合

SSM整合

1.整合原理

SMM框架指的是spring MVC,spring和mybatis框架的整合,是标准的MVC模式

各个框架的作用

  • springMVC:表述层架构,处理浏览器发送给服务器的请求,将一些数据请求到浏览器。
  • MyBatis:持久层框架,对数据库的操作(连接、访问、操作)。
  • Spring:整合型架构,通过IOC管理对象,比如MyBatis中的SqlSession对象。
2.整合步骤
2.1创建新的项目

首先创建一个新的项目(项目名称命名为ssm)

这里选择Maven,之后点击创建,项目创建成功

2.2将项目转成为一个Maven工程

出现如下字样说明转换成功

同时打开项目目录出现webapp目录即为成功

2.3创建log4j和jdbc配置文件(resources包下)

jdbc.properties配置文件

在这里插入图片描述

log4j.properties配置文件(这段直接在网上找就好,我这里是找好的)

######
log4j.rootLogger = debug,stdout,D,E

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ./logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =./logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
2.4pom.xml文件中导入依赖

依赖有点多,已经分好了

在properties标签内我把版本号作为变量进行声明,方便maven依赖标签用${变量名}的形式动态获取版本号。这样做的好处是当版本号发生改变时,仅仅需要更新properties标签中的变量值就行了,不用煞费心思更新所有依赖的版本号,便于管理。

<?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>org.example</groupId>  
  <artifactId>ssm</artifactId>  
  <version>1.0-SNAPSHOT</version>  
  <packaging>war</packaging>  
  <properties>
    <spring.version>6.0.6</spring.version>
    <jakarta.annotation-api.version>2.1.1</jakarta.annotation-api.version>
    <jakarta.jakartaee-web-api.version>9.1.0</jakarta.jakartaee-web-api.version>
    <jackson-databind.version>2.15.0</jackson-databind.version>
    <hibernate-validator.version>8.0.0.Final</hibernate-validator.version>
    <mybatis.version>3.5.11</mybatis.version>
    <mysql.version>8.0.25</mysql.version>
    <pagehelper.version>5.1.11</pagehelper.version>
    <druid.version>1.2.8</druid.version>
    <mybatis-spring.version>3.0.2</mybatis-spring.version>
    <jakarta.servlet.jsp.jstl-api.version>3.0.0</jakarta.servlet.jsp.jstl-api.version>
    <lombok.version>1.18.26</lombok.version>
    <maven.compiler.source>17</maven.compiler.source>  
    <maven.compiler.target>17</maven.compiler.target>  
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>jakarta.annotation</groupId>
      <artifactId>jakarta.annotation-api</artifactId>
      <version>${jakarta.annotation-api.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</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>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>jakarta.platform</groupId>
      <artifactId>jakarta.jakartaee-web-api</artifactId>
      <version>${jakarta.jakartaee-web-api.version}</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>jakarta.servlet.jsp.jstl</groupId>
      <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
      <version>${jakarta.servlet.jsp.jstl-api.version}</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson-databind.version}</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>${hibernate-validator.version}</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator-annotation-processor</artifactId>
      <version>${hibernate-validator.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>

    <!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>

    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>${pagehelper.version}</version>
    </dependency>

    <!-- 整合第三方特殊依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis-spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.8.0-beta4</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.8.0-beta4</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>${druid.version}</version>
    </dependency>
  </dependencies>
</project>

2.5创建包以及配置类

整体包的创建就是这样

######

2.5.1数据源配置类DataSourceConfig
package com.csi.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

/**
 * 数据源配置
 */
//@Configuration注解的作用:声明一个类为配置类,用于取代bean.xml配置文件注册bean对象。
@Configuration
//@PropertySource注解用来加载配置文件jdbc.properties,这里要声明路径
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {

    //使用@Value注解注入属性值。
    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;


    //使用@Bean注解告诉dataSource()方法,产生一个Bean对象,返回一个DataSource对象
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();

        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        return dataSource;
    }
}
2.5.2MyBatis的核心配置类MapperJavaConfig
package com.csi.config;

import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.session.AutoMappingBehavior;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
public class MapperJavaConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {

        //实例化SqlSessionFactoryBean,SqlSessionFactoryBean是MyBatis中的一个类,用于创建SqlSessionFactory。
        // SqlSessionFactory是用于创建SqlSession的工厂,而SqlSession是执行命令和获取映射的主要接口。

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource);

        //'org.apache.ibatis.session.Configuration'是MyBatis的核心配置类,用于配置SQL映射语句、结果集映射、类型处理器等。创建这个类的实例,可以加载以下配置
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        //开启驼峰映射
        //对应xml中的<setting name="mapUnderscoreToCamelCase" value="true"/>
        configuration.setMapUnderscoreToCamelCase(true);

        //开启logback日志输出
        //<setting name="logImpl" value="SLF4J"/>
        configuration.setLogImpl(Slf4jImpl.class);

        //开启resultMap自动映射
        //<setting name="autoMappingBehavior" value="FULL"/>
        configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);

        //开启缓存
        configuration.setCacheEnabled(true);

        sqlSessionFactoryBean.setConfiguration(configuration);

        /*
        给实体类起别名
        <typeAliases>
         <package name="com.csi.pojo"/>
         </typeAliases>
         **/
        sqlSessionFactoryBean.setTypeAliasesPackage("com.csi.domain");

        /*
        <plugins>
            <plugin interceptor="com.github.pagehelper.PageInterceptor">
                <property name="helperDialect" value="mysql"/>
            </plugin>
         </plugins>
         */

        /*
        helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
        oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby

         */

        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("helperDiaLect", "mysql");
        sqlSessionFactoryBean.setPlugins(pageInterceptor);

        return sqlSessionFactoryBean;

        }
        @Bean
        public MapperScannerConfigurer mapperScannerConfigurer(){

        //MapperScannerConfigurer是一个用于在Spring启动时扫描指定包下的所有类
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();

        //Spring启动时,它会扫描这个包(com.csi.mapper)下的所有类,并对其中的Mapper接口进行扫描和配置。
        mapperScannerConfigurer.setBasePackage("com.csi.mapper");

        return mapperScannerConfigurer;

    }
}

2.5.3事务管理和AOP配置类ServiceJavaConfig
package com.csi.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
//@EnableTransactionManagement:启用Spring的注解事务管理,Spring会自动管理事务的开启、提交和回滚。
@EnableTransactionManagement
//@ComponentScan("com.csi.service"):让Spring扫描"com.csi.service"这个包以及其子包,寻找并注册所有被@Component、@Service、@Repository、@Controller等注解的类,这些类在Spring中就是所谓的bean。
@ComponentScan("com.csi.service")
//@EnableAspectJAutoProxy:启动AspectJ的自动代理,用于实现面向切面的编程(AOP)。AOP是面向对象编程(OOP)的一种补充,它允许程序员在不改变业务逻辑代码的情况下,对业务逻辑进行增强,例如日志、事务管理等。
@EnableAspectJAutoProxy
public class ServiceJavaConfig {
    //这个bean会被Spring用于管理数据库事务
    @Bean
    public TransactionManager transactionManager(DataSource dataSource){

        TransactionManager transactionManager = new DataSourceTransactionManager(dataSource);

        return transactionManager;
    }
}

2.5.4Spring MVC的配置类WebJavaConfig
package com.csi.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * WebMvcConfigurer接口用于通过实现类对Spring MVC框架进行定制。尽管这个类并没有实现任何方法,
 * 但是它仍然必须被声明为实现这个接口,以启用Spring MVC的一些特定配置和功能。
 */

@Configuration
@ComponentScan("com.csi.controller")
//@EnableWebMvc注解将启用Spring MVC
@EnableWebMvc
public class WebJavaConfig implements WebMvcConfigurer {

}
2.5.5Spring MVC的初始化类WebMVCInit
package com.csi.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * 此配置类是用来配置和初始化一个基于Spring MVC的Web应用程序的。
 */
public class WebMVCInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    /*
    getRootConfigClasses()方法返回一个Class数组,表示的是这个应用程序的主配置类。
    返回的是DataSourceConfig.class、MapperJavaConfig.class和ServiceJavaConfig.class三个类,
    意味着Spring在启动时会加载这三个配置类。
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{DataSourceConfig.class, MapperJavaConfig.class, ServiceJavaConfig.class};
    }

    /*
    getServletConfigClasses()方法返回一个Class数组,表示的是Web应用的Servlet配置类。
    返回的是WebJavaConfig.class,Web应用会使用这个配置类来配置相关的Servlet。
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebJavaConfig.class};
    }

    /*
    getServletMappings()方法返回一个字符串数组,表示的是Web应用中每个Servlet的URL映射。
    返回的是"/",表示所有的请求都会被映射到这个Web应用。
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

配置类到这里就结束了,在项目中需要根据实际情况进行修改

2.6创建数据库(ssm)
2.6.1创建表

2.6.2添加数据

我在表中随机生成了1000条数据,便于测试

在这里插入图片描述

2.7创建实体类(Employee)
package com.csi.domain;

import lombok.Data;

/**
 * 实体类
 */

//@Data注解省去代码中大量的get()、set()、toString()等方法。
@Data
public class Employee {
    
    private int empId;
    
    private String empName;
    
    private double empSalary;
}
2.8创建数据访问层接口EmployeeMapper
package com.csi.mapper;

import com.csi.domain.Employee;

import java.util.List;

public interface EmployeeMapper {
    
    //查询全部员工
    List<Employee> employees();
}
2.9创建业务逻辑层接口EmployeeService及其实现类EmployeeServiceImpl
package com.csi.service;

import com.csi.domain.Employee;

import java.util.List;

public interface EmployeeService {

    List<Employee> employees();
}
package com.csi.service.impl;

import com.csi.domain.Employee;
import com.csi.mapper.EmployeeMapper;
import com.csi.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
//@Service注解用于将EmployeeServiceImpl类标记为一个服务层的组件,并将其纳入Spring容器中进行管理。
@Service
//@Transactional是Spring框架的事务管理注解,用于声明EmployeeServiceImpl类的方法具有事务管理特性。
// 这意味着在方法执行过程中发生异常时,将自动回滚事务,保证数据的一致性。
@Transactional
public class EmployeeServiceImpl implements EmployeeService {

    /*
    @Autowired是Spring框架的自动装配注解,用于将EmployeeMapper类的实例自动注入到EmployeeServiceImpl类中。
     */
    @Autowired
    private EmployeeMapper employeeMapper;
     /*
    这是在employees()方法上的另一个@Transactional注解,用于声明该方法的事务属性。
    Propagation.NOT_SUPPORTED表示该事务不支持嵌套事务,即不能在一个已经存在的事务内部再开启一个新的事务。
    ReadOnly = true表示该事务只读,即对数据的操作不会改变数据库中的数据。
    */
    @Transactional(propagation = Propagation.NOT_SUPPORTED,readOnly = true)
    @Override
    public List<Employee> employees() {
        return employeeMapper.employees();
    }
}

2.10创建EmployeeController
package com.csi.controller;

import com.csi.domain.Employee;
import com.csi.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

//@Controller:该标注用于标识一个SpringMVC控制器,用于处理HTTP请求。
//@Controller标注的类中定义的方法可以接收HTTP请求,并返回相应的视图或者数据。
@RestController
//@RequestMapping("/emp"):该注解为控制器类指定了一个URL前缀,即"/emp",表示该控制器处理的所有请求URL都需要以"/emp"开头。
@RequestMapping("/emp")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

    //@GetMapping用于处理HTTP GET请求,它相当于@RequestMapping注解的快捷方式,用于映射GET请求到指定的处理方法上。
    @GetMapping
    public List<Employee> list(){
        return employeeService.employees();
    }
}
2.11创建EmployeeMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--定义一个名为com.csi.mapper.EmployeeMapper的映射器-->
<mapper namespace="com.csi.mapper.EmployeeMapper">
<!--    这里的id要与方法名相同,否则无法映射-->
<!--    resultType表示查询结果为Employee类型,将查询的结果映射到Employee实体类的属性-->
    <select id="employees" resultType="employee">
        SELECT emp_id empId,emp_name empName,emp_salary empSalary FROM t_emp
    </select>
</mapper>

2.12配置Tomcat

Tomcat就已经配置好了,不过要确保Tomcat是10以上的版本,否则用不了,之后点击应用启动就可以了

3测试

输入设置好的路径localhost:8080/emp

在这里插入图片描述

里面会显示在之前在数据库生成的1000条数据,当然我们还可以做出一个分页的效果

在EmployeeController类做出修改

package com.csi.controller;

import com.csi.domain.Employee;
import com.csi.service.EmployeeService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

//@Controller:该标注用于标识一个SpringMVC控制器,用于处理HTTP请求。
//@Controller标注的类中定义的方法可以接收HTTP请求,并返回相应的视图或者数据。
@Controller
//@RequestMapping("/emp"):该注解为控制器类指定了一个URL前缀,即"/emp",表示该控制器处理的所有请求URL都需要以"/emp"开头。
@RequestMapping("/emp")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

    //@GetMapping用于处理HTTP GET请求,它相当于@RequestMapping注解的快捷方式,用于映射GET请求到指定的处理方法上。
    //pageNo用于设置页数,pageSize用于设置每页条数
    @GetMapping
    public List<Employee> list(@RequestParam(value = "pageNo",defaultValue = "1") int pageNo,
                               @RequestParam(value = "pageSize",defaultValue = "10")int pageSize){
        PageHelper.startPage(pageNo,pageSize);
        return employeeService.employees();
    }
}

重新启动后结果如下:

默认只会显示第1页的10条数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

并且可以通过设置参数,查询第几页的数据

在这里插入图片描述

同时还可以修改每页的条数

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值