二十、SpringBoot整合Mybatis

添加mybatis依赖:


    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    1.3.2

mybatis-spring-boot-starter依赖.png

步骤:

​ 1)、添加数据源依赖及连接池


    com.alibaba
    druid
    1.1.9


    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    1.3.2

​ 2)、全局配置文件中配置数据源

spring:
  datasource:
    url: jdbc:mysql:///springboot
    username: root
    password: admin
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    minIdle: 5
    maxActive: 20
    schema:
      - classpath*:sql/department.sql
      - classpath*:sql/employee.sql

​ 3)、准备sql文件,并存放在resources目录下的sql文件夹下

​ 4)、注解版

@Mapper
public interface DepartmentMapper {

    @Select("select * from department where id = #{id}")
    public Department getById(Integer id);

    @Delete("delete from department where id = #{id}")
    public int deleteById(Integer id);

    @Insert("insert into department(departmentName) values(#{departmentName})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    public int insert(Department department);

    @Update("update department set departmentName = #{departmentName} where id = #{id}")
    public int update(Department department);
}

问题:

​ 问题1:如果数据库字段与实体属性的不能匹配,但是数据库字段使用下划线来区分隔开,而实体类属性使用驼峰法命名,这样的字段如何使用注解版的mybatis来解决呢?

​ 解决方法1:定义一个mybatis的配置类,并配置一个ConfigurationCustomizer类型的Bean,并将驼峰命名规则设为true即可。

@Configuration
public class MybatisConfig {

    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
        return configuration -> {
            configuration.setMapUnderscoreToCamelCase(true);
        };
    }
}

原理:在MybatisAutoConfiguration自动配置类中,创建了一个SqlSessionFactory的Bean:

@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setVfs(SpringBootVFS.class);
    if (StringUtils.hasText(this.properties.getConfigLocation())) {
        factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
    }
    Configuration configuration = this.properties.getConfiguration();
    if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
        configuration = new Configuration();
    }
    
    //获取所有的Mybatis中的ConfigurationCustomizer定制器,执行各自的定制方法
    if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
        for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
            customizer.customize(configuration);
        }
    }
    factory.setConfiguration(configuration);
    if (this.properties.getConfigurationProperties() != null) {
        factory.setConfigurationProperties(this.properties.getConfigurationProperties());
    }
    if (!ObjectUtils.isEmpty(this.interceptors)) {
        factory.setPlugins(this.interceptors);
    }
    if (this.databaseIdProvider != null) {
        factory.setDatabaseIdProvider(this.databaseIdProvider);
    }
    if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
        factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
    }
    if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
        factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
    }
    if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
        factory.setMapperLocations(this.properties.resolveMapperLocations());
    }

    return factory.getObject();
}

正如上面源码中注释提到的,在配置SqlSessionFactory的Bean的时候,会依次调用每个Mybatis定制器的customize定制方法,从而修改mybatis的默认配置。

所以可以自定义一个Mybatis的ConfigurationCustomizer定制器即可。

​ 解决方法2:在全局配置文件中添加配置:

# 开启驼峰命名法规则
mybatis.configuration.map-underscore-to-camel-case=true

​ 问题2:如果使用驼峰命名法都无法映射的话,那如何解决?

​ 解决方法:使用@Results注解,用于定义之前mybatis的xml映射文件中的标签:

@Mapper
public interface DepartmentMapper {

    @Results({
                @Result(column = "id", property = "id", id = true),
                @Result(column = "department_name", property = "departmentName")
    })
    @Select("select * from department where id = #{id}")
    public Department getById(Integer id);

    @Delete("delete from department where id = #{id}")
    public int deleteById(Integer id);

    @Insert("insert into department(department_name) values(#{departmentName})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    public int insert(Department department);

    @Update("update department set department_name = #{departmentName} where id = #{id}")
    public int update(Department department);
}

​ 问题3:如果每个Mapper接口都使用@Mapper注解会比较麻烦,是否有更简便的方法来配置接口呢?

​ 解决方法:(通常)在主程序入口上添加@MapperScan注解,用于指定扫描mapper接口的包路径:

@MapperScan(basePackages = "mapper接口所在的包路径")

​ 如果mapper分在不同的包中,可以同时该注解配置多个mapper接口所在的包路径:

@MapperScan(basePackages = {"包1", "包2", "包3"})

​ 5)、配置版

​ 首先编写一个mybatis全局配置文件(如果不需要任何配置,则不需要该文件配置):





    
        
    

​ 接着编写一个mapper接口:

public interface EmployeeMapper {

    public Employee getById(Integer id);
    public Employee insert(Employee employee);
}

​ 接着编写sql映射文件:





    
    
    
        INSERT INTO employee(lastName, email, gender, d_id)
        VALUES
        (
            #{lastName},
            #{email},
            #{gender},
            #{dId}
        )
    

​ 最后全局配置文件中设置mybatis属性:

mybatis:
# 如果无需设置,则可以忽略mybatis.config-location
#  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml
  type-aliases-package: org.com.cay.spring.boot.entity

4、整合SpringData JPA

4.1、JPA简介

JPA规范.png

4.2、使用JPA

​ 1)、编写一个实体类和数据库表进行映射,并且配置实体类:

@Entity
@Table
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String lastName;
    private String email;

    //getter、setter、toString
}

​ 2)、编写一个Dao接口来操作实体类对应的数据库,继承JpaRepository

public interface UserRepository extends JpaRepository {
}

​ 3)、在全局配置文件中配置jpa的基本配置,详细的配置属性在JpaProperties配置类中:

spring:
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true  #显示sql

你可能感兴趣的:(二十、SpringBoot整合Mybatis)