SpringBoot整合mybatis

本文围绕Spring Boot和MyBatis展开,介绍了依赖和配置,如@MapperScan和@Mapper的使用、type-aliases-package设置等。还阐述了常用语法,像@MapKey返回类型、${}与 #{}区别等。同时讲解了各类标签的用法、事务管理以及自定义类型转换TypeHandler的配置与使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

依赖

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>

配置

mybatis:
  config-location: classpath:mybatis-config.xml
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.data.*

@MapperScan和@Mapper

@Mapper:在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类。


@Mapper
public interface TestMapper {}

@MapperScan:在Springboot启动类上面添加,指定要变成实现类的接口所在的包,包下面的所有接口在编译之后都会生成相应的实现类。


@SpringBootApplication
@MapperScan("com.mybatis.mappers")
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}
在不使用@MapperScan前,需要在每一个Mapper类上面添加注解@Mapper,重复。通过使用@ MapperScan注解,可以不用为每个Mapper类都添加@Mapper注解。

type-aliases-package

mapper.xml文件中resultMap的type,parameterType,resultType引用实体类,需要写上全类名。

在application.yml文件中设置mybatis:type-aliases-package参数后,可以不写全类名,只写一个实体类的名称的话。


mybatis:
    type-aliases-package: com.test.data.*

打印sql

第一种

mybatis:
# spring boot集成mybatis的方式打印sql
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

以下表示配置成功

效果

第二种

# 日志的方式打印sql
# com.seamax.bdsearch.dao = 你的mapper包。
logging:
  level:
    com.seamax.bdsearch.dao: DEBUG

效果

参考:Spring boot mybatis 打印SQL语句_星澄码帝的博客-优快云博客_springboot中mybatis打印sql语句

常用语法

@MapKey返回Map<String,Object> 类型

作用是将List结果集转换成key-value形式的Map结果集,方便快速从结果集中查询指定结果。

Mapper.java


@MapKey("userId")
Map<String,UserInfo> getUserInfoByUserIds(@Param("list") List<String> ids);
Map的key:每条记录的主键(数据库字段或者别名),也可以用其他值表示,ps:此处若将map的key的类型改为其他类型,不影响@MapKey给map的key赋值;
Map的value:表示查询出这条记录的每个字段的字段名称和字段值。

Mapper.xnl


<select id="getUserInfoByUserIds" resultType="java.util.Map">
    select
    info.id as userId,
    info.name as userName
    from user_info info
    where info.id in 
    <foreach item="id" collection="list" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

truncate清除表数据

使用<update>标签

${}与 #{}区别

  • #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".

  • $将传入的数据直接显示生成在sql中。

order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.

  • #方式能够很大程度防止sql注入,$方式无法防止Sql注入。

$方式一般用于传入数据库对象,例如传入表名.

一般能用#的就别用$。
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#

转义字符

< —— &lt;
> —— &gt;
& —— &amp;
'  —— &apos;
"  —— &quot;

<![CDATA[ ]]>

这是XML语法。在CDATA内部的所有内容都会被解析器忽略。

如果文本包含了很多的"<"字符 <=和"&"字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。

但是有个问题那就是 <if test=""> </if> <where> </where> <choose> </choose> <trim> </trim> 等这些标签都不会被解析,所以我们只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小 <![CDATA[ ]]> 的范围。

标签

if 标签

例如:判断字符串XXX为0

  1. 用toString()转成字符串, '0'.toString()

  1. 改为双引号"0",外层使用单引号。

<if test=" XXX == '0'.toString() ">
或者
<if test = ' XXX != "0" '>

choose标签

实现 if else 逻辑

	<choose>
      <when test="state == 1">
        AND name = #{name1}
      </when>
      <otherwise>
        AND name = #{name2}
      </otherwise>
    </choose>

foreach标签

需要在db链接url后面带一个参数 &allowMultiQueries=true

批量查询

<select id="queryUserInfoById" resultType="com.user">
    SELECT
        *
    FROM
    user_info t
    WHERE ID IN
    <foreach collection="list" item="id" open="(" separator="," close=")">
	    #{id}
    </foreach>
</select>

批量新增

<insert id="insertBatch">
    INSERT INTO xxxx
            (a, b, c)
    VALUES
    <foreach collection ="list" item="user" separator =",">
         (#{user.a}, #{user.b}, #{user.c})
    </foreach>
</insert>

批量修改

<update id="updateBatchxxxxxx" parameterType="java.util.List">
    <foreach collection="list" item="bean" index="index" open="" close="" separator=";">
        update xxxxxx
        <set>
            a= #{bean.a}
        </set>
        <where>
            b= #{bean.b}
        </where>
    </foreach>
</update>
item:集合中元素迭代时的别名,该参数为必选。
index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选
open:foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选
separator:元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
close: foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
collection: 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键,Map对象没有默认的键。
入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。
还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List是ids。入参是User对象,那么这个collection = "ids"; 如果User有属性Ids ids,其中Ids是个对象,Ids有个属性List id,入参是User对象,那么collection = "ids.id"。

trim标签

trim 有四个属性

prefix:表示在trim包裹的SQL语句前面添加的指定内容。

suffix:表示在trim包裹的SQL末尾添加指定内容

prefixOverrides:表示去掉(覆盖)trim包裹的SQL的指定首部内容

suffixOverrides:表示去掉(覆盖)trim包裹的SQL的指定尾部内容

实例

<select id="getUserInfo" resultType="UserInfo">
    SELECT * FROM t_user t
    <trim prefix="WHERE" prefixOverrides="AND |OR">
    <if test='id != null'>AND t.ID = #{id}</if>
    <if test='name != null'>AND t.NAME = #{name}</if>
    </trim>
</select>

<update id="updateUserInfo">
    update t_user 
    set modifier = #{modifier}, 
    modification_time = sysdate()
    <trim prefix="," suffixOverrides=",">
        <if test='name != null'>name = #{name},</if>
        <if test='remark != null'>remark = #{remark},</if>
    </trim>
    where id = #{id}
</update>

事务管理

例如:删除菜单时,需要同时删除角色菜单关系表,如果两张表中有一个表删除失败返回false或者产生异常,都会产生事务回滚,将之前修改的数据进行回滚。

第一步,在springboot的启动类上开启事务,注解@EnableTransactionManagement


@EnableTransactionManagement
public class SystemManagementApp {}

第二步:事务注解,@Transactional(rollbackFor = Exception.class)


@Transactional(rollbackFor = Exception.class)
public Result deleteMenu(String navigationUuid) {}
正常情况下加注解@Transactional和try catch捕获异常会让注解失效。
解决办法就是在catch语句块中添加TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

@Transactional(rollbackFor = Exception.class)
public Result deleteNavigation(String navigationUuid) {
    try {
        // TODO
    } catch (Exception e) {
        // TODO
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return result;
    }
}

自定义类型转换 TypeHandler

全局配置

配置一:

mybatis-config.xml配置文件

<configuration>
    <typeHandlers>
        <typeHandler handler="com.xxx.xx.xxx.mybatis.handler.Timestamp2LongHandler"/>
    </typeHandlers>
</configuration>

在 SpringBoot 中指定如下配置,否则将不会生效

mybatis:
  config-location: classpath:mybatis-config.xml

配置二:

springboot 配置文件,可以通过指定type-handlers-package来注册 TypeHandler

mybatis:
  type-handlers-package: com.xxx.xx.xxx.mybatis.handler

使用:

在实体类上使用

@TableField(typeHandler = JacksonTypeHandler.class)
@ApiModelProperty(value = "显示颜色 {\"color\":\"\",\"id\":\"\"}")
private JSONObject color;

在xml的<result>标签中,通过 typeHandler 指定

<result column="ext_info" property="extInfo" typeHandler="com.zhyq.sys.basic.common.mp.type_handler.JacksonTypeHandler"/>

极化码(Polar Code)是由土耳其科学家Erdal Arıkan在2009年提出的一种新型纠错编码技术。它通过利用信道的极化现象,将虚拟信道分为误码率接近0和接近1/2的两类。在编码设计中,数据被放置在误码率极低的信道上,从而实现高效的数据传输。极化码的主要优势在于其理论编码容量能够达到香农限,并且构造方法较为简单。 MATLAB是一种功能强大的数学计算和编程工具,广泛应用于科学研究和工程领域。在极化码的研究中,MATLAB可用于构建编码和解码算法,模拟数据在不同信道条件下的传输效果,验证理论性能,并优化相关参数。 SC(Successive Cancellation,逐位取消)译码是极化码的基本解码方法。它从最可靠的比特开始,依次解码每个虚拟信道,且每个比特的解码结果会影响后续比特的解码,因为它们之间存在依赖关系。虽然SC译码的实现较为简单,但其计算复杂度较高,随着码长的增加,解码时间会线性增长。 SCL(Successive Cancellation List,逐位取消列表)译码是SC译码的改进版本。它通过引入列表机制,同时处理多个路径,从而增强了错误校正能力,并在一定程度上降低了错误率。与SC译码相比,SCL译码虽然需要消耗更多的计算资源,但能够提供更好的性能。 一个完整的MATLAB仿真资源通常包含以下内容: 编码模块:用于实现极化码的生成,包括码字构造和极化矩阵操作等。 信道模型:用于模拟各种通信信道,例如AWGN(加性高斯白噪声)信道或衰落信道。 SC/SCL译码模块:包含SC译码和SCL译码的算法实现。 误码率(BER)计算:通过比较发送和接收的码字,计算误码率,以评估编码性能。 性能曲线绘制:绘制误码率与信噪比(SNR)之间的关系曲线,展示不同译码策略的性能差异。 使用说明:指导用户如何运行仿真,理解代码结构,以及如何调整参数以进行自定义实验。 代码注
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值