二、SSM 整合配置实战

本章概要

  • 依赖整合和添加
  • 控制层配置编写(SpringMVC 整合)
  • 业务配置编写(AOP/TX 整合)
  • 持久层配置编写(MyBatis 整合)
  • 容器初始化配置类
  • 整合测试

2.1 依赖整合和添加

  1. 数据库准备

数据库脚本

CREATE DATABASE `mybatis-example`;

USE `mybatis-example`;

CREATE TABLE `t_emp`(
  emp_id INT AUTO_INCREMENT,
  emp_name CHAR(100),
  emp_salary DOUBLE(10,5),
  PRIMARY KEY(emp_id)
);

INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);
  1. 准备项目
  • part04-ssm-integration
  • 转成 web项目
  1. 依赖导入
<?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.atguigu</groupId>  
  <artifactId>part04-ssm-integration</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>
    <logback.version>1.2.3</logback.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>
  <!--
     需要依赖清单分析:
        spring
          ioc/di
            spring-context / 6.0.6
            jakarta.annotation-api / 2.1.1  jsr250
          aop
            spring-aspects / 6.0.6
          tx
            spring-tx  / 6.0.6
            spring-jdbc / 6.0.6

        springmvc
           spring-webmvc 6.0.6
           jakarta.jakartaee-web-api 9.1.0
           jackson-databind 2.15.0
           hibernate-validator / hibernate-validator-annotation-processor 8.0.0.Final
         
        mybatis
           mybatis  / 3.5.11
           mysql    / 8.0.25
           pagehelper / 5.1.11

        整合需要
           加载spring容器 spring-web / 6.0.6
           整合mybatis   mybatis-spring x x
           数据库连接池    druid / x
           lombok        lombok / 1.18.26
           logback       logback/ 1.2.3
  -->

  <dependencies>
    <!--spring pom.xml依赖-->
    <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>


    <!--
       springmvc
           spring-webmvc 6.0.6
           jakarta.jakartaee-web-api 9.1.0
           jackson-databind 2.15.0
           hibernate-validator / hibernate-validator-annotation-processor 8.0.0.Final
    -->
    <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>

    <!-- jsp需要依赖! jstl-->
    <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>


    <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>${hibernate-validator.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator-annotation-processor</artifactId>
      <version>${hibernate-validator.version}</version>
    </dependency>


    <!--
      mybatis
           mybatis  / 3.5.11
           mysql    / 8.0.25
           pagehelper / 5.1.11
    -->
    <!-- mybatis依赖 -->
    <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>

    <!-- 日志 , 会自动传递slf4j门面-->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>${logback.version}</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>
  1. 实体类添加

com.atguigu.pojo

@Data
public class Employee {

    private Integer empId;
    private String empName;
    private Double empSalary;
}
  1. logback配置

位置:resources/logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
    <!-- 指定日志输出的位置,ConsoleAppender表示输出到控制台 -->
    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 日志输出的格式 -->
            <!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->
            <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 设置全局日志级别。日志级别按顺序分别是:TRACE、DEBUG、INFO、WARN、ERROR -->
    <!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
    <root level="DEBUG">
        <!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->
        <appender-ref ref="STDOUT" />
    </root>

    <!-- 根据特殊需求指定局部日志级别,可也是包名或全类名。 -->
    <logger name="com.atguigu.mybatis" level="DEBUG" />

</configuration>

2.2 控制层配置编写(SpringMVC 整合)

主要配置controller,springmvc相关组件配置 。位置:com.atguigu.config.WebJavaConfig.java(命名随意)

/**
 * projectName: com.atguigu.config
 * 
 * 1.实现Springmvc组件声明标准化接口WebMvcConfigurer 提供了各种组件对应的方法
 * 2.添加配置类注解@Configuration
 * 3.添加mvc复合功能开关@EnableWebMvc
 * 4.添加controller层扫描注解
 * 5.开启默认处理器,支持静态资源处理
 */
@Configuration
@EnableWebMvc
@ComponentScan("com.atguigu.controller")
public class WebJavaConfig implements WebMvcConfigurer {

    //开启静态资源
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable(); 
    }
}

2.3 业务配置编写(AOP/TX 整合)

主要配置service,注解aop和声明事务相关配置。位置: com.atguigu.config.ServiceJavaConfig.java(命名随意)

/**
 * projectName: com.atguigu.config
 * 
 * 1. 声明@Configuration注解,代表配置类
 * 2. 声明@EnableTransactionManagement注解,开启事务注解支持
 * 3. 声明@EnableAspectJAutoProxy注解,开启aspect aop注解支持
 * 4. 声明@ComponentScan("com.atguigu.service")注解,进行业务组件扫描
 * 5. 声明transactionManager(DataSource dataSource)方法,指定具体的事务管理器
 */
@EnableTransactionManagement
@EnableAspectJAutoProxy
@Configuration
@ComponentScan("com.atguigu.service")
public class ServiceJavaConfig {
    
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
    
}

2.4 持久层配置编写(MyBatis 整合)

主要配置mapper代理对象,连接池和mybatis核心组件配置

  1. MyBatis整合思路
//1.读取外部配置文件
InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");

//2.创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);

//3.创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.获取mapper代理对象
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
//5.数据库方法调用
int rows = empMapper.deleteEmpById(1);
System.out.println("rows = " + rows);
//6.提交和回滚
sqlSession.commit();
sqlSession.close();

MyBatis核心api介绍

  • SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 无需ioc容器管理!

  • SqlSessionFactory

一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,因此 SqlSessionFactory 的最佳作用域是应用作用域。需要ioc容器管理!

  • SqlSession

每个线程都应该有它自己的SqlSession实例。SqlSession的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 无需**ioc**容器管理!

  • Mapper 映射器实例

映射器是一些绑定映射语句的接口。映射器接口的实例是从SqlSession中获得的。虽然从技术层面上来讲,任何映射器实例的最大作用域与请求它们的SqlSession相同。但方法作用域才是映射器实例的最合适的作用域。
从作用域的角度来说,映射器实例不应该交给ioc容器管理!
但是从使用的角度来说,业务类(service)需要注入mapper接口,所以mapper应该交给ioc容器管理!

在这里插入图片描述

  • 总结
    • SqlSessionFactory实例存储到IoC容器
    • Mapper实例存储到IoC容器

MyBatis整合思路理解:

MyBatisapi实例化需要复杂的过程。
例如,自己实现sqlSessionFactory加入ioc容器:

@Bean
public SqlSessionFactory sqlSessionFactory(){
   //1.读取外部配置文件
  InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");
  
  //2.创建sqlSessionFactory
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);
  
  return sqlSessionFactory;
}

过程比较繁琐,为了提高整合效率,MyBatis提供了提供封装SqlSessionFactoryMapper实例化的逻辑的FactoryBean组件,我们只需要声明和指定少量的配置即可!

SqlSessionFactoryBean源码展示(MyBatis提供):

package org.mybatis.spring;

public class SqlSessionFactoryBean
    implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ContextRefreshedEvent> {
    
       //封装了实例化流程
       public SqlSessionFactory getObject() throws Exception {
          if (this.sqlSessionFactory == null) {
            //实例化对象逻辑
            afterPropertiesSet();
          }
          //返回对象逻辑
          return this.sqlSessionFactory;
       }
   
}

MyBatis整合思路总结:

  • 需要将SqlSessionFactoryMapper实例加入到IoC容器
  • 使用MyBatis整合包提供的FactoryBean快速整合
  1. 整合外部配置文件

数据库连接信息。位置: resources/jdbc.properties

jdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql:///mybatis-example
jdbc.driver=com.mysql.cj.jdbc.Driver
  1. 整合方式1(保留mybatis-config.xml
  • 介绍

依然保留MyBatis的外部配置文件(xml), 但是数据库连接信息交给Druid连接池配置!

在这里插入图片描述

缺点: 依然保留MyBatis的外部配置文件(xml), 但是数据库连接信息交给Druid连接

  • MyBatis配置文件

数据库信息以及mapper扫描包设置使用Java配置类处理!MyBatis其他的功能(别名、settings、插件等信息)依然在mybatis-config.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>
    <settings>
        <!-- 开启驼峰式映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 开启logback日志输出-->
        <setting name="logImpl" value="SLF4J"/>
        <!--开启resultMap自动映射 -->
        <setting name="autoMappingBehavior" value="FULL"/>
    </settings>

    <typeAliases>
        <!-- 给实体类起别名 -->
        <package name="com.atguigu.pojo"/>
    </typeAliases>

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--
                helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。
                你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
                oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
                (完整内容看 PageAutoDialect) 特别注意:使用 SqlServer2012 数据库时,
                https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md#%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E6%96%B9%E8%A8%80
             -->
            <property name="helperDialect" value="mysql"/>
        </plugin>
    </plugins>
</configuration>
  • MyBatis和持久层配置类

持久层Mapper配置、数据库配置、Mybatis配置信息。 位置:com.atguigu.config.MapperJavaConfig.java(命名随意)

@Configuration
@PropertySource("classpath:jdbc.properties")
public class MapperJavaConfig {

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


    //数据库连接池配置
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        return dataSource;
    }

    /**
     * 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可
     * @param dataSource 需要注入连接池对象
     * @return 工厂Bean
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        //实例化SqlSessionFactory工厂
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        //设置连接池
        sqlSessionFactoryBean.setDataSource(dataSource);

        //设置配置文件
        //包裹外部配置文件地址对象
        Resource resource = new ClassPathResource("mybatis-config.xml");
        sqlSessionFactoryBean.setConfigLocation(resource);

        return sqlSessionFactoryBean;
    }

    /**
     * 配置Mapper实例扫描工厂,配置 <mapper <package 对应接口和mapperxml文件所在的包
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //设置mapper接口和xml文件所在的共同包
        mapperScannerConfigurer.setBasePackage("com.atguigu.mapper");
        return mapperScannerConfigurer;
    }

}

问题:
当在Spring配置类中添加了sqlSessionFactoryBeanmapperScannerConfigurer配置方法时,可能会导致@Value注解读取不到值为null的问题。这是因为SqlSessionFactoryBeanMapperScannerConfigurer是基于MyBatis框架的配置,它们的初始化顺序可能会导致属性注入的问题。

SqlSessionFactoryBeanMapperScannerConfigurer在配置类中通常是用来配置MyBatis相关的Bean,例如数据源、事务管理器、Mapper扫描等。这些配置类通常在@Configuration注解下定义,并且使用@Value注解来注入属性值。

当配置类被加载时,Spring容器会首先处理Bean的定义和初始化,其中包括sqlSessionFactoryBeanmapperScannerConfigurer的初始化。在这个过程中,如果@Value注解所在的Bean还没有被完全初始化,可能会导致注入的属性值为null

解决方案:
分成两个配置类独立配置,互不影响,数据库提取一个配置类,MyBatis提取一个配置类即可解决!

  • 拆分配置

数据库配置类(DataSourceJavaConfig.java)

@Configuration
@PropertySource("classpath:jdbc.properties")
public class DataSourceJavaConfig {


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


    //数据库连接池配置
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername(user);
        dataSource.setPassword(password);
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        return dataSource;
    }

}

MyBatis配置类(MapperJavaConfig.java)

@Configuration
public class MapperJavaConfig {

    /**
     * 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可
     * @param dataSource 需要注入连接池对象
     * @return 工厂Bean
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        //实例化SqlSessionFactory工厂
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        //设置连接池
        sqlSessionFactoryBean.setDataSource(dataSource);

        //设置配置文件
        //包裹外部配置文件地址对象
        Resource resource = new ClassPathResource("mybatis-config.xml");
        sqlSessionFactoryBean.setConfigLocation(resource);

        return sqlSessionFactoryBean;
    }

    /**
     * 配置Mapper实例扫描工厂,配置 <mapper <package 对应接口和mapperxml文件所在的包
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //设置mapper接口和xml文件所在的共同包
        mapperScannerConfigurer.setBasePackage("com.atguigu.mapper");
        return mapperScannerConfigurer;
    }

}
  1. 整合方式2 (完全配置类 去掉mybatis-config.xml
  • 介绍

不在保留MyBatis的外部配置文件(xml), 所有配置信息(settings、插件、别名等)全部在声明SqlSessionFactoryBean的代码中指定!数据库信息依然使用DruidDataSource实例替代!
在这里插入图片描述

优势:全部配置类,避免了**XML**文件解析效率低问题!

  • mapper配置类
/**
 * projectName: com.atguigu.config
 *
 * description: 持久层配置和Druid和Mybatis配置 使用一个配置文件
 */
@Configuration
public class MapperJavaConfigNew {

    /**
     * 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可
     * @param dataSource 需要注入连接池对象
     * @return 工厂Bean
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
        //实例化SqlSessionFactory工厂
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        //设置连接池
        sqlSessionFactoryBean.setDataSource(dataSource);

        //TODO: 替代xml文件的java配置
        /*

            <settings>
                <!-- 开启驼峰式映射-->
                <setting name="mapUnderscoreToCamelCase" value="true"/>
                <!-- 开启logback日志输出-->
                <setting name="logImpl" value="SLF4J"/>
                <!--开启resultMap自动映射 -->
                <setting name="autoMappingBehavior" value="FULL"/>
            </settings>

            <typeAliases>
                <!-- 给实体类起别名 -->
                <package name="com.atguigu.pojo"/>
            </typeAliases>

            <plugins>
                <plugin interceptor="com.github.pagehelper.PageInterceptor">
                    <!--
                        helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。
                        你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
                        oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
                        (完整内容看 PageAutoDialect) 特别注意:使用 SqlServer2012 数据库时,
                        https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md#%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E6%96%B9%E8%A8%80
                     -->
                    <property name="helperDialect" value="mysql"/>
                </plugin>
            </plugins>

         */

        //settings [包裹到一个configuration对象,切记别倒错包]
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setLogImpl(Slf4jImpl.class);
        configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);
        sqlSessionFactoryBean.setConfiguration(configuration);

        //typeAliases
        sqlSessionFactoryBean.setTypeAliasesPackage("com.atguigu.pojo");

        //分页插件配置
        PageInterceptor pageInterceptor = new PageInterceptor();

        Properties properties = new Properties();
        properties.setProperty("helperDialect","mysql");
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryBean.addPlugins(pageInterceptor);

        return sqlSessionFactoryBean;
    }

    /**
     * 配置Mapper实例扫描工厂,配置 <mapper <package 对应接口和mapperxml文件所在的包
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //设置mapper接口和xml文件所在的共同包
        mapperScannerConfigurer.setBasePackage("com.atguigu.mapper");
        return mapperScannerConfigurer;
    }

}

2.5 容器初始化配置类

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  //指定root容器对应的配置类
  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] {MapperJavaConfig.class, ServiceJavaConfig.class, DataSourceJavaConfig.class };
  }
  
  //指定web容器对应的配置类
  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] { WebJavaConfig.class };
  }
  
  //指定dispatcherServlet处理路径,通常为 / 
  @Override
  protected String[] getServletMappings() {
    return new String[] { "/" };
  }
}

2.6 整合测试

  1. 需求
  • 查询所有员工信息,返回对应 json 数据
  1. controller
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @GetMapping("list")
    public List<Employee> retList(){
        List<Employee> employees = employeeService.findAll();
        log.info("员工数据:{}",employees);
        return employees;
    }
}
  1. service
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 查询所有员工信息
     */
    @Override
    public List<Employee> findAll() {
        List<Employee> employeeList =  employeeMapper.queryAll();
        return employeeList;
    }
}
  1. mapper

mapper接口 包:com.atguigu.mapper

public interface EmployeeMapper {

     List<Employee> queryAll();
}

mapper XML 文件位置: resources/mappers

<?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">
<!-- namespace等于mapper接口类的全限定名,这样实现对应 -->
<mapper namespace="com.atguigu.mapper.EmployeeMapper">

    <select id="queryAll" resultType="employee">
        <!-- #{empId}代表动态传入的参数,并且进行赋值!后面详细讲解 -->
        select emp_id empId,emp_name empName, emp_salary empSalary from t_emp
    </select>

</mapper>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/374752.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS远程真机调试方法

生成密钥库文件 打开DevEco Studio&#xff0c;点击菜单栏上的build&#xff0c; 填一些信息点击&#xff0c;没有key的话点击new一个新的key。 生成profile文件 AppGallery Connect (huawei.com) 进入该链接网站&#xff0c;点击用户与访问将刚生成的csr证书提交上去其中需…

2024版细致idea解读(包含下载,安装,破解,讲解怎么使用)

前言 我们历经了对应的javase开发&#xff0c;使用的软件从eclipse也逐步升级到了idea&#xff0c;IntelliJ旗下的产品之一 内部复函很大的集成平台插件供大家使用 下载介绍 IntelliJ IDEA – 领先的 Java 和 Kotlin IDE 这个是他的网站地址 进入之后我们可以看到对应的界面…

【经典例子】Java实现2048小游戏(附带源码)

一、游戏回顾 2048游戏是一款数字益智游戏&#xff0c;目标是通过合并相同数字的方块来达到2048这个目标。游戏在一个4x4的方格上进行&#xff0c;每个方格上都有一个数字&#xff08;初始时为2或4&#xff09;。玩家可以通过滑动方向键&#xff08;上、下、左、右&#xff09;…

SpringBoot 事务管理Transactional 数据回滚 数据一致性

介绍 SpringBoot当中的事物他保证了一致性&#xff0c;要么全部一起成功&#xff08;提交&#xff09;&#xff0c;要么一起失败&#xff0c;失败&#xff08;回滚&#xff09;后数据会回到当初的样子&#xff0c;是一组操作的集合。 事物类型 开启事物提交事物回滚事物 案…

银河麒麟 aarch64 Mysql环境安装

一、操作系统版本信息 组件版本操作系统Kylin V10 (SP3) /(Lance)-aarch64-Build23/20230324Kernel4.19.90-52.22.v2207.ky10.aarch64MySQLmysql-8.3.0JDK1.8.0_312 二、MySQL下载 官网下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 三、MySQL 安装 3.1 删…

图数据库neo4j入门

neo4j 一、安装二、简单操作<一>、创建<二>、查询<三>、关系<四>、修改<五>、删除 三、常见报错<一>、默认的数据库密码是neo4j,打开浏览器http://localhost:7474登录不上,报错: Neo.ClientError.Security.Unauthorized: The client is un…

Mac利用brew安装mysql并设置初始密码

前言 之前一直是在windows上开发后段程序&#xff0c;所以只在windows上装mysql。(我记得linux只需要适应yum之类的命令即可) 另外, linux的移步 linux安装mysql (详细步骤,初次初始化,sql小例子,可视化操作客户端推荐) 好家伙&#xff0c;我佛了&#xff0c;写完当天网上发…

【十】【C++】string类的模拟实现

浅拷贝 浅拷贝&#xff08;Shallow Copy&#xff09;是对象复制的一种方式&#xff0c;其中复制对象的过程仅仅复制对象的值&#xff0c;而不复制引用所指向的实际对象或数据。这意味着原始对象和拷贝对象会共享相同的引用或指针指向的数据。 浅拷贝的特点&#xff1a; 共享…

深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之行存(一)

在当今的大数据时代&#xff0c;高效的数据检索和分析能力已成为许多应用程序的核心需求。Elasticsearch&#xff0c;作为一款强大的分布式搜索和分析引擎&#xff0c;正是为了满足这些需求而诞生的。它之所以能够在海量数据中实现毫秒级的搜索响应&#xff0c;以及灵活的数据分…

2024/02/06

画出TCP三次握手和四次挥手的示意图 三次握手 四次挥手 并且总结TCP和UDP的区别 TCP: TCP提供面向连接的&#xff0c;可靠的数据传输服务传输过程中&#xff0c;数据无误、数据无丢失、数据无失序、数据无重复 TCP会给每个数据包编上编号&#xff0c;该编号称之为序列号每个序…

Minio Linux 安装

1.下载地址 MinIO | Code and downloads to create high performance object storage 2.创建文件相关文件夹 mkdir 3.赋权 chomd x minio 4.创建用户组和租户 groupadd minio ### useradd minio -g minio ### 验证 cat /etc/passwd5.创建配置文件 vi minio.confMINIO_VOLU…

带着问题阅读源码——Spring MVC是如何在Spring Boot中注入的?

Spring MVC简介 Spring Web的MVC框架旨在全面处理HTTP请求&#xff0c;它具备以下特性&#xff1a; 可配置的处理程序映射&#xff1a;允许开发者根据需要将特定的URL路径映射到相应的处理程序上。 视图解析&#xff1a;框架能够根据处理程序返回的逻辑视图名&#xff0c;解析…

微软.NET6开发中解决方案和项目的概念

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;看到不少初学者在学习编程语言的过程中如此的痛苦&#xff0c;我决定做点什么&#xff0c;下面我就重点讲讲微软.NET6开发中解决方案和项目的概念。我将介绍 Visual Studio 2022的解决方案和项目的结构及组成…

UE5 获得UE内的音频组件与频谱

打开Audio Synesthesia插件 在Sounds内Analysis选择Synesthesia NRT 创建好后选择Settings,下面的sound选择你要选择的音乐 在Actor里添加Constant QNRT变量,选择刚刚创建的NRT 添加Audio组件 这里需要先运行SetSound,然后获得当前音频的总长度,Get Duration并设置变量 绑定时间…

zabbix-监控应用程序(Mysql、Nginx)

基础环境&#xff1a;zabbix服务端、两台zabbix被监控端、分别安装Mysql和Nginx环境拓扑图&#xff1a; 实验目标&#xff1a;可以通过zabbix监控到被监控端上安装的mysql与nginx&#xff0c;通过zabbix实时检测mysql和nginx的数据。实验步骤&#xff1a;1.在8.7服务器上安装My…

Asp .Net Core 系列:Asp .Net Core 集成 NLog

简介 NLog是一个基于.NET平台编写的日志记录类库&#xff0c;它可以在应用程序中添加跟踪调试代码&#xff0c;以便在开发、测试和生产环境中对程序进行监控和故障排除。NLog具有简单、灵活和易于配置的特点&#xff0c;支持在任何一种.NET语言中输出带有上下文的调试诊断信息…

Linux 命令基础

Shell概述 Linux操作系统的Shell作为操作系统的外壳&#xff0c;为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。 Shell是用户和Linux内核之间的接口程序&#xff0c;如果把硬件想象成一个球体的中心&#xff0c;内核围绕在硬件的外层管理着…

基于Python机器学习算法农业数据可视化分析预测系统(完整系统源码+数据库+详细文档+论文+部署教程)

文章目录 基于Python机器学习算法农业数据可视化分析预测系统完整源码获取方式在文章末尾一、项目简介二、开发环境三、项目技术四、功能结构五、功能实现模型构建封装类用于网格调参训练模型系统可视化数据请求接口模型评分 0.5*mse 六、系统实现七、总结完整源码获取 基于Pyt…

Qt程序设计-自定义QLineEdit控件添加鼠标单击事件

本文讲解Qt自定义QLineEdit控件添加鼠标单击事件。 QLineEdit控件默认没有单击事件,但是项目开发中有时需要单击事件,比如单击QLineEdit控件弹出软键盘。具体实现过程如下: 创建项目,在项目中添加一个类,命名为MyLineEdit 输入继承QLineEdit #ifndef MYLINEEDIT_H #defi…