1. 程式人生 > >10、MyBatis-註解方式整合SSM

10、MyBatis-註解方式整合SSM

連接 cto 部分 共享數據 configure 類名 ext bject auto

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

技術分享圖片

項目結構

技術分享圖片


mybatis 整合文檔

spring mvc 文檔

10、MyBatis-註解方式整合SSM