10、MyBatis-注解方式整合SSM

时间:2022-05-15 16:37:06

Spring、Spring MVC、MyBatis 整合

一、依赖

<?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</groupId>
    <artifactId>ssm</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--spring mvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <!--事务管理等-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <!--简化pojo类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
            <scope>provided</scope>
        </dependency>

        <!--mybatis整合spring-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.0</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.0</version>
        </dependency>
        <!--jdbc驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>

        <!--druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.14</version>
        </dependency>

        <!--日志-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.26</version>
        </dependency>
    </dependencies>

    <properties>
        <!--编码格式-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!--tomcat 插件方式运行需指定为 war 包-->
    <packaging>war</packaging>

    <build>
        <plugins>
            <!-- 指定jdk -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!--tomcat插件-->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <ignorePackaging>true</ignorePackaging>
                    <port>80</port>
                    <path>/ssm</path>
                    <server>tomcat7</server>
                    <charset>UTF-8</charset>
                    <uriEncoding>UTF-8</uriEncoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

二、配置

数据库信息 db.properties

db.url=jdbc:mysql://192.168.8.136:3306/mybatis?allowMultiQueries=true
db.username=root
db.password=root

mybatis属性配置,也可不配置 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>
        <!-- 本地(一级)缓存作用域,默认 SESSION,会缓存一个会话(SqlSession)中执行的所有查询。 设置为 STATEMENT,会话仅作用在语句执行上,对 SqlSession 的调用将不会共享数据,可认为是禁用一级缓存 -->
        <setting name="localCacheScope" value="SESSION"/>
        <!-- 控制台打印SQL -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
        <setting name="useColumnLabel" value="true"/>
        <!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分  FULL:全部  -->
        <setting name="autoMappingBehavior" value="PARTIAL"/>
        <!-- 这是默认的执行类型  (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新)  -->
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
        <setting name="jdbcTypeForNull" value="NULL"/>
        <!-- 是否允许单条sql 返回多个数据集  (取决于驱动的兼容性) default:true -->
        <setting name="multipleResultSetsEnabled" value="true"/>
        <!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。  default:false  -->
        <setting name="useGeneratedKeys" value="false"/>
    </settings>
</configuration>

注解配置类,tomcat 启动时会加载此类,然后才有后续的操作

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // spring 配置
        return new Class<?>[]{RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        // spring mvc 配置
        return new Class<?>[]{ServletConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        // DispatcherServlet 拦截路径,/* 拦截所有,/ 会排除 *.jsp 文件
        return new String[]{"/"};
    }
}

spring 配置

// 开启事务管理
@EnableTransactionManagement
// 加载 properties 文件
@PropertySource("classpath:db.properties")
// 扫描包路径,spring 扫描除 controller 层以外的,spring 不可从子容器(spring mvc)中获取 bean
@ComponentScan(basePackages = {"ssm.service", "ssm.pojo", "ssm.dao"})
public class RootConfig {

    /**
     * SqlSession 工厂
     * @param dataSource 数据源,会在 IOC 中获取
     */
    @Bean
    public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        // 设置 MyBatis 配置文件路径
        factoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        // 设置 SQL 映射文件路径
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        // 设置 JavaBean 类型别名,在 SQL 映射文件中就不用写全类名
        factoryBean.setTypeAliasesPackage("ssm.pojo");
        return factoryBean;
    }

    /**
     * Druid 数据源
     */
    @Bean
    public DataSource getDataSource(@Value("${db.username}") String name, @Value("${db.password}") String password, @Value("${db.url}") String url) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(name);
        dataSource.setPassword(password);
        return dataSource;
    }

    /**
     * 扫描所有 mapper 接口的实现,让这些 mapper 能够自动注入
     */
    @Bean
    public MapperScannerConfigurer getMapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("ssm.dao");
        return mapperScannerConfigurer;
    }

    /**
     * 事务管理
     */
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 配置一个可以进行批量执行的 sqlSession
     */
    @Bean
    public SqlSessionTemplate getSqlSessionTemplate(SqlSessionFactoryBean sqlSessionFactoryBean) throws Exception {
        /**
         * Simple Executor -- SIMPLE 普通的执行器,默认
         * Reuse Executor -执行器会重用预处理语句(prepared statements)
         * Batch Executor --批量执行器
         */
        SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject(), ExecutorType.BATCH);
        return sessionTemplate;
    }
}

spring mvc 配置,需实现 WebMvcConfigurer 接口

// 开启事务管理
@EnableTransactionManagement
// 加载 properties 文件
@PropertySource("classpath:db.properties")
// 扫描包路径,spring 扫描除 controller 层以外的,spring 不可从子容器(spring mvc)中获取 bean
@ComponentScan(basePackages = {"ssm.service", "ssm.pojo", "ssm.dao"})
public class RootConfig {

    /**
     * SqlSession 工厂
     * @param dataSource 数据源,会在 IOC 中获取
     */
    @Bean
    public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        // 设置 MyBatis 配置文件路径
        factoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        // 设置 SQL 映射文件路径
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        // 设置 JavaBean 类型别名,在 SQL 映射文件中就不用写全类名
        factoryBean.setTypeAliasesPackage("ssm.pojo");
        return factoryBean;
    }

    /**
     * Druid 数据源
     */
    @Bean
    public DataSource getDataSource(@Value("${db.username}") String name, @Value("${db.password}") String password, @Value("${db.url}") String url) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(name);
        dataSource.setPassword(password);
        return dataSource;
    }

    /**
     * 扫描所有 mapper 接口的实现,让这些 mapper 能够自动注入
     */
    @Bean
    public MapperScannerConfigurer getMapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("ssm.dao");
        return mapperScannerConfigurer;
    }

    /**
     * 事务管理
     */
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 配置一个可以进行批量执行的 sqlSession
     */
    @Bean
    public SqlSessionTemplate getSqlSessionTemplate(SqlSessionFactoryBean sqlSessionFactoryBean) throws Exception {
        /**
         * Simple Executor -- SIMPLE 普通的执行器,默认
         * Reuse Executor -执行器会重用预处理语句(prepared statements)
         * Batch Executor --批量执行器
         */
        SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject(), ExecutorType.BATCH);
        return sessionTemplate;
    }
}

三、测试

1.dao层

@Repository
public interface UserMapper {
    public User getUserById(User user);
    public boolean addUserById(User user);
}

对应的 SQL 映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace 对应接口文件的全路径 -->
<mapper namespace="ssm.dao.UserMapper">
    <select id="getUserById" parameterType="user" resultType="user">
      select * from user where user.id = ${id}
    </select>
    <insert id="addUserById" parameterType="user">
      insert into user(name,age) values(#{name},#{age})
    </insert>
</mapper>

2.实体层

@Getter
@Setter
@ToString
public class User {
    private Integer id;
    private String name;
    private Integer age;
}

3.service 层

@Service
public class UserManagerService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    // 使用事务
    @Transactional
    public User getUserById(){
        User user = new User();
        user.setId(1);
        userMapper.getUserById(user);
        user = sqlSessionTemplate.selectOne("ssm.dao.UserMapper.getUserById",user);
        
        userMapper.addUserById(user);
        // 异常回退
        int i = 3/0;
        
        return user;
    }
}

4.controller 层

@Controller
public class HelloWorld {

    @Autowired
    private UserManagerService userManagerService;

    @ResponseBody
    @RequestMapping(value = "/hw",method = RequestMethod.GET)
    public String hw() {
        return userManagerService.getUserById().toString();
    }
}

插件方式启动 tomcat

10、MyBatis-注解方式整合SSM

项目结构

10、MyBatis-注解方式整合SSM

 


 

mybatis 整合文档

spring mvc 文档