Spring boot 整合MyBatis框架

MyBatis的配置文件包括两个大的部分, 一是基础配置文件,一个是映射文件。在mybatis中可以使用注解和XML文件来配置。

一、Mybatis配置

1.配置内容

mybatis是一个基于SqlSessionFactory构建的框架,用于生成的SqlSession接口的对象是mybatis操作的核心,构建SqlSessionFactory通过配置类(Configuration)来完成,在mybatis-spring-boot-starter,我们可以在application.properties中进行配置相关内容。

在这里插入图片描述

  1. settings:可以配置映射规则等(如自动映射,驼峰映射,执行器类型,缓存等内容)可参考mybatus官方网站
  2. typeAliases:使用类全限定名会比较长,可配置自定义的别名
  3. mappers: 映射器,提供SQL和POJO的映射关系。
  4. typeHandlers:类型处理器,一般不需要自定义,一般使用集中在枚举类型上,在 MyBatis 写入和读取数据库的过程中对于不同类型的数据进行自定义转换(对于 Java JavaType ,对于数据库则是 JdbcType)
  5. objectFactory: 在mybatis生成返回的POJO时会调用的工厂类,Mybatis默认为(DefaultObjectFactory),一般不需要配置
  6. plugins :有时候也称为拦截器,可以修改 MyBatis 底层的实现功能
  7. environments:数据库环境配置,可以配置数据库连接内容和事务,一般采用Spring进行配置
  8. databaseldProvider:可配置多类型数据库,不常用
  9. properties:属性文件在实际用用中一般采用Spring进行配置,如数据库源的配置
@Alias(value = "user") 
public class User {
....
// 性别枚举,这里需要使用typeHandler进行转换(如下)
private SexEnum sex;
}

//使用typeHandler进行转换
@MappedJdbcTypes(JdbcType.INTEGER)   // 声明JdbcType为整形
@MappedTypes(value = SexEnum.class)  // 声明JavaType为SexEnum
public class SexTypeHandler extends BaseTypeHandler<SexEnum> {

    // 通过列名读取性别
    @Override
    public SexEnum getNullableResult(ResultSet rs, String col) throws SQLException {
        int sex = rs.getInt(col);
        if (sex != 1 && sex != 2){
            return null;
        }
        return SexEnum.getEnumById(sex);
    }

    // 通过下标读取性别
    @Override
    public SexEnum getNullableResult(ResultSet rs, int idx) throws SQLException {
        int sex = rs.getInt(idx);
        if (sex != 1 && sex != 2){
            return null;
        }
        return SexEnum.getEnumById(sex);
    }

    // 通过存储过程读取性别
    @Override
    public SexEnum getNullableResult(CallableStatement cs, int idx) throws SQLException {
        int sex = cs.getInt(idx);
        if (sex != 1 && sex != 2){
            return null;
        }
        return SexEnum.getEnumById(sex);
    }

    // 设置非空性别参数
    @Override
    public void setNonNullParameter(PreparedStatement ps, int idx, SexEnum sex, JdbcType jdbcType) throws SQLException {
        ps.setInt(idx, sex.getId());
    }
}

2. 配置application.yml

spring:
  # 配置Mysql数据源
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://10.107.171.101:3306/ssm?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: 123456

    # 指定druid数据库连接池
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      min-idle: 10      # 最小连接池数量
      max-active: 50    # 最大连接活动数
      max-wait: 10000   # 最大连接活动数 ms
      initial-size: 5   # 数据库连接池初始化连接数

# Mybatis配置
mybatis:
  # MyBatis映射文件的匹配
  mapper-locations: classpath:mapper/*.xml
  # MyBatis扫描别名包,和注解@Alias 联用
  type-aliases-package: com.cq3jk.demomybatis.entity
  # 配置typeHandler的扫描包
  type-handlers-package: com.cq3jk.demomybatis.typehandler

3、定义一个映射的接口


// 此接口不需要任何实现类,由一个xml文件去实现
// MyBatis 提供了一个对 Mapper 注解@Mapper
@Repository
public interface UserMapper {
    User getUser (Long id) ;
}

4. 定义一个映射文件(userMapper.xml)

<?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">
<mapper namespace="com.cq3jk.demomybatis.mapper.UserMapper">
	
	<!--根据ID查询用户-->
    <select id="getUser" parameterType="long" resultType="user">
        select id, user_name as userName, sex, note
        from t_user
        where id = #{id}
    </select>
    
</mapper>
  1. <mapper> 元素的 namespace 属性为需要映射的接口
  2. select中的id与映射的接口保持一致
  3. parameterType 属性配置为参数类型
  4. resu tType 指定返回值类型,此处为别名,也可以使用全限定名
  5. 列名与POJO的属性名保持一致,也可开启驼峰

二、Spring boot 整合Mybatis

1. 使用@MapperScan 定义扫描 - 最简单的方法

@SpringBootApplication(scanBasePackages = "com.cq3jk.demomybatis")
@MapperScan(
        basePackages = "com.cq3jk.demomybatis.mapper",   //指定扫描包
        // 指定 SqlSessionFactory,如果sqlSessionTemplate被指定,则作废
        // 这里有一个或多个的Spring的容器
        sqlSessionFactoryRef = "sqlSessionFactory",
        // 指定 sqlSessionTemplate,将忽略SqlSessionFactory配置
         这里有一个或多个的Spring的容器
        sqlSessionTemplateRef = "sqlSessionTemplate",
        // 基于包下面扫描所有的接口类并注册,也有指定的属性
        annotationClass = Repository.class
)
public class DemoMybatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoMybatisApplication.class, args);
    }

}

2. 其他方式装配接口(了解)

  1. MapperFactoryBean类:针对一个接口配置
// SqlSessionFactory是 Spring Boot 自动为我们生成的,
@Autowired
SqlSessionFactory sqlSessionFactory ;

@Bean // 可以装备
public MapperFactoryBean<UserMapper> initUserMapper() {
    MapperFactoryBean<UserMapper> bean = new MapperFactoryBean<UserMapper>();
    bean.setMapperInterface(UserMapper.class);
    bean.setSqlSessionFactory(sqlSessionFactory);
    return bean;
}
  1. MapperScannerConfigurer类:扫描装配 MyBatis 的接口到Spring IoC 容器中

@Bean
public MapperScannerConfigurer mapperScannerConfig () {
      MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
      mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
      mapperScannerConfigurer.setBasePackage("com.cq3jk.demomybatis.mapper");
      mapperScannerConfigurer.setAnnotationClass(Repository.class);
      return mapperScannerConfigurer
}

3. resultMap 解析

association, collection 中有一个的属性resultMap来复用映射


<!--column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象">
  <id column="表的主键字段,或者可以为查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" />
  <result column="表的一个字段(可以为任意表的一个字段)" jdbcType="字段类型" property="映射到pojo对象的一个属性(须为type定义的pojo对象中的一个属性)"/>
  
  <!-- 一对一映射到JavaBean的某个“复杂类型”属性 -->
  <association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
    <id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的主席属性"/>
    <result  column="任意表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
  </association>
  
  <!-- 
  一对多映射到JavaBean中的某个集合,
  集合中的property须为oftype定义的pojo对象的属性
  -->
  <collection property="pojo的集合属性" ofType="集合中的pojo对象">
    <id column="集合中pojo对象对应的表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" />
    <result column="可以为任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />  
  </collection>
</resultMap>
<!-- 
该模型由一个

作者编写的博客组成,
其中包含许多帖子,每个帖子可能没有或有许多评论和标记 
-->
<resultMap id="detailedBlogResultMap" type="Blog">
  
  <!-- 2. 注入到字段或 JavaBean 属性的普通结果-->
  <result property="title" column="blog_title"/>
  
  <!-- 
  	   3. 一对一映射到JavaBean的某个“复杂类型”属性 
  	   4. association中有一个的属性resultMap来复用映射
  -->
  <association property="author" javaType="Author">
    <!--设置该项可以有效地提升MyBatis的性能 -->
    <id property="id" column="author_id"/> 
    <result property="username" column="author_username"/>
  </association>
  
  <!-- 4. 一对多映射到JavaBean中的某个集合 -->
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    
    <association property="author" javaType="Author"/>
    
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
  	
  	<!--使用结果值来决定使用哪个 resultMap or resultType-->
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection>
</resultMap>
collection标签使用嵌套查询
// 注意:
// <collection>标签中的column:
// 要传递给select查询语句的参数,如果传递多个参数,格式为column= ” {参数名1=表字段1,参数名2=表字段2} ;
<collection column="传递给嵌套查询语句的字段参数" 
			property="pojo对象中集合属性" 
			ofType="集合属性中的pojo对象" 		
			select="嵌套的查询语句" > 
</collection>

// 示例如下
<select id="getById"  resultMap="ShopResultMap">
	select id, name, category_id
    from t_shop
    where id= #{id};
</select>

<resultMap id="ShopResultMap" type="shop">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="name"  property="name" />
    <result column="category_id" property="categoryId" />
    <collection column="{sId=id}" property="attributes" ofType="attributes" select="getAttribute" > 
    </collection>
</resultMap>

<select id="getAttribute"  resultMap="AttributeResultMap">
    select id, sid, attr_name
    from t_shop_attribute
    where  sid = #{sId};
</select>

<resultMap id="AttributeResultMap" type="attribute">
    <id column="id"  property="id" />
    <result column="attr_name"  property="attributeName" />
</resultMap>


4. 参数传递

#{} 与 ${} 的区别:
#{} 拿到值之后,拼装sql,会自动对值添加单引号”
${} 则把拿到的值直接拼装进sql,如果需要加单引号”,必须手动添加,一般用于动态传入表名或字段名使用,同时需要添加属性statementType=”STATEMENT”,使用非预编译模式

基本数据类型(int,String,Date等)

1、 只能传入一个参数,通过#{参数名}

public List<User> selectUserByOrgId(String orgId);
select * from user where org_id = #{orgId}

2、 传入多个参数,通过#{0}、#{1}……索引方式

public User selectUserByNameAndAge(String name,int age);
select * from user where name = #{0} and age = #{1}

3、传入多个参数,通过#{参数名}传多个值,可以使用@param()注解

public User selectUserByNameAndAge(@param("name")String name, @param("age")int age);
select * from user where name = #{name} and age = #{age}

复杂数据类型(包含JAVA实体类、Map)

4、传入多个基本类型参数,参数用map封装,通过#{mapKey}取值

public User selectUserByNameAndAge(Map map);
<select id="selectUserByNameAndAge" parameterType="Map" resultType="user">
    select * from user where name = #{name} and age = #{age}
</select>

5、使用map封装实体类,通过通过#{mapKey.attributeName}取值

public User selectUserByNameAndAge(Map map);
select * from user where name = #{user.name} and age = #{user.age}

6、直接传入实体参数,通过#{属性名}取值

public User selectUserByNameAndAge(User userParam);
<select id="selectUserByNameAndAge" parameterType="User" resultType="user">
    select * from user where name = #{userParam.name} and age = #{userParam.age}
</select>

mybatis中如果用了if那么传进来的参数不能直接单独传入,要封装到map或vo(对象)中

5. 返回自增长主键

  1. 第一种
// id会直接将映射到参数的实体上使用时直接使用参数的实体get获取值
<insert id="insertBatchReturnId" useGeneratedKeys="true" keyProperty="id" parameterType="xxx"  >  
  1. 第二种 (oracl需额外的配置)
<insert id="add" parameterType="EStudent">  
  // 下面是SQLServer获取最近一次插入记录的主键值的方式  
  <selectKey resultType="_long" keyProperty="id" order="AFTER">  
    select @@IDENTITY as id  
  </selectKey>  
  insert into TStudent(name, age) values(#{name}, #{age})  
</insert>  

6. 分页插件(pagehelper)

spring boot 集成mybatis实现分页功能的实例
https://blog.csdn.net/wufewu/article/details/84586489

三、Mybatis-plus 与 通用Mapper

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值