mybatis框架学习笔记

本文介绍了MyBatis在SpringBoot中的应用,涵盖了JDBC数据库连接池的优势、如何配置application.properties、Mapper接口的使用、注解方式和XML映射文件的两种功能实现,包括删除、插入、更新、查询操作,以及参数占位符、主键返回和动态SQL的讲解。

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

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档



简介

MyBatis是一款优秀的持久层框架用于简化JDBC的开发,所谓持久层,可以理解成数据 保存在 数据库或者 硬盘一类可以保存很长时间的设备里面,不像放在内存中那样断电就消失了,也就是把数据存在持久化设备上

JDBC

Java Database Connectivity是Java语言操作关系型数据库的一套API
各个数据库公司提供实现这套接口的驱动jar包,我们可以使用这套接口编程
真正执行的代码是驱动jar包的实现类

数据库连接池

标准接口 DataSource
官方提供的数据库连接池接口,由第三方组织实现该接口
功能:获取连接
例如阿里巴巴的Druid(德鲁伊)
是Java语言最好的数据库连接池之一

优势

mybatis使用了数据库连接池
它允许程序重复运用一个现有的数据库连接,而不是在建立一个
释放空闲时间超过设定的最大空闲时间的连接,避免没有释放连接引起数据库连接遗漏

创建

创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok)
在这里插入图片描述

在这里插入图片描述

application.properties中引入数据库连接信息



#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=1234

创建对应的实体类(实体类属性采用驼峰命名),并用ptg(idea的一个插件)添加set和get以及构造方法
也可以使用lombok(jar包和插件)的注解方式,只需添加@Data,@NoArgsConstructor,@AllArgsConstructor
在这里插入图片描述
在这里插入图片描述
lombok

注:为避免数据库的下划线命名法和Java的驼峰命名法冲突,可以再properties配置文件中添加属性,实现两者间的映射关系
mybatis.configuration.map-underscore-to-camel-case=true(打出camel就会自动提示)

准备Mapper接口:EmpMapper

@Mapper注解:表示当前接口为mybatis中的Mapper接口
程序运行时会自动创建接口的实现类对象(代理对象),并交给Spring的IOC容器管理

@Mapper
public interface EmpMapper {

}

mybatis的两种编写方式

1.功能实现(注解方式)

删除

SQL语句
删除id=17的数据

delete from emp where id = 17;

(Mybatis框架让程序员更关注于SQL语句 )
接口方法
//SQL语句中的id值不能写成固定数值,需要变为动态的数值
//解决方案:在delete方法中添加一个参数(用户id),将方法中的参数,传给SQL语句

  /**
     * 根据id删除数据
     */
    @Delete("delete from emp where id = #{id}")//使用#{key}方式获取方法中的参数值
    public void delete(Integer id);```
   @Delete注解:用于编写delete操作的SQL语句
 如果mapper接口方法形参只有一个普通类型的参数,#{} 里面的属性名可以随便写,如:#{id}、#{value}。但是建议保持名字一致。
 在单元测试类中通过@Autowired注解注入EmpMapper类型对象
 

```java
@SpringBootTest
class SpringbootMybatisCrudApplicationTests {
    @Autowired //从Spring的IOC容器中,获取类型是EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    public void testDel(){
        //调用删除方法
        empMapper.delete(16);
    }
}

测试:
测试只需在springboot的测试类内加上之前的接口,并使用注释@Autowired,因为
接口被Mapper注释,系统在程序运行时会自动创建接口放入IOC容器中
接着在@test注释下写test函数,创建所需测试方法的参数对象,函数内利用接口中的方法测试即可。

@SpringBootTest
class SpringbootMybatisCrudApplicationTests {
    @Autowired //从Spring的IOC容器中,获取类型是EmpMapper的对象并注入
    private EmpMapper empMapper;

    @Test
    public void testDel(){
        //调用删除方法
        empMapper.delete(16);
    }

}

使用#{}的原因:
使用#{}时会进行预编译,编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译。效率更高,而且能有效防止sql注入(字段内容中包含sql语句关键词导致sql’语句变化)将敏感字进行转义,保障SQL的安全性。

日志输入

在Mybatis当中我们可以借助日志,查看到sql语句的执行、执行传递的参数以及执行结果。具
打开application.properties文件

开启mybatis的日志,并指定输出到控制台体操作如下:

#指定mybatis输出日志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

但是我们发现输出的SQL语句:delete from emp where id = ?,我们输入的参数16并没有在后面拼接,id的值是使用?进行占位。那这种SQL语句我们称为预编译SQL。

参数占位符

在Mybatis中提供的参数占位符有两种:${…} 、#{…}

  • #{…}

    • 执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值
    • 使用时机:参数传递,都使用#{…}
  • ${…}

    • 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题
    • 使用时机:如果对表名、列表进行动态设置时使用
      注:在项目开发中,建议使用#{…},生成预编译SQL,防止SQL注入安全。

新增

SQL语句:

insert into 
emp
(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) 
values 
('songyuanqiao','宋远桥',1,'1.jpg',2,'2012-10-09',2,'2022-10-01 10:00:00','2022-10-01 10:00:00');

接口方法:

@Mapper
public interface EmpMapper {

    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
    public void insert(Emp emp);
}

说明:#{…} 里面写的名称是对象的属性名

主键返回

在数据添加成功后,需要获取插入数据库数据的主键。
只需在定义的接口的所需要返回主键id的方法上面加
@Options(useGeneratedKeys = true,keyProperty = "id")

更新

sql语句:

update emp 
set 
username = 'linghushaoxia', 
name = '令狐少侠', gender = 1 , 
image = '1.jpg' , job = 2, 
entrydate = '2012-01-01', dept_id = 2, 
update_time = '2022-10-01 12:12:12' 
where id = 18;

接口方法:

@Mapper
public interface EmpMapper {
    /*
     根据id修改员工信息
     */
    @Update("update emp 
    set username=#{username}, 
    name=#{name}, gender=#{gender}, 
    image=#{image}, job=#{job}, 
    entrydate=#{entrydate}, dept_id=#{deptId}, 
    update_time=#{updateTime} where id=#{id}")
    public void update(Emp emp);
}

查询

根据ID查询

sql语句:

select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp;

接口方法:

@Mapper
public interface EmpMapper {
    @Select("select id, username, 
    password, name, gender, image, 
    job, entrydate, dept_id, 
    create_time, update_time 
    from emp where id=#{id}")
    public Emp getById(Integer id);
}
数据封装
  • 实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。
  • 如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。
  • 解决方案:
  1. 起别名
  2. 结果映射
  3. 开启驼峰命名
    在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样
1.起别名
@Select("select id, username, password, name, gender, image, job, entrydate, " +
        "dept_id AS deptId, create_time AS createTime, update_time AS updateTime " +
        "from emp " +
        "where id=#{id}")
public Emp getById(Integer id);
2.手动结果映射
@Results({@Result(column = "dept_id", property = "deptId"),
          @Result(column = "create_time", property = "createTime"),
          @Result(column = "update_time", property = "updateTime")})
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
public Emp getById(Integer id);
3.开启驼峰命名(推荐)
# 在application.properties中添加:
mybatis.configuration.map-underscore-to-camel-case=true
条件查询

sql语句:

select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time 
from emp 
where name like '%张%' 
      and gender = 1 
      and entrydate between '2010-01-01' and '2020-01-01 ' 
order by update_time desc;

接口方法:

@Mapper
public interface EmpMapper {
    @Select("select * from emp " +
            "where name like '%${name}%' " +
            "and gender = #{gender} " +
            "and entrydate between #{begin} and #{end} " +
            "order by update_time desc")
    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
}

mysql的concat函数可以进行字符串拼接
比如
where name like concat(‘%’,#{name},‘%’)
即可以进行模糊匹配,也能有效防止sql注入

参数名说明

在上面我们所编写的条件查询功能中,我们需要保证接口中方法的形参名和SQL语句中的参数占位符名相同,否则会找不到参数,出现问题。

功能实现(XML映射文件方式)

介绍

Mybatis的开发有两种方式:

  1. 注解
  2. XML
  3. 使用Mybatis的注解方式,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件中。

XML映射文件使用规范

使用XML映射文件时必须符合以下三个规范:

  1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)

  2. XML映射文件的namespace属性为Mapper接口全限定名一致

  3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

XML映射使用

1创建文件



编写XML映射文件

xml映射文件中的dtd约束,直接从mybatis官网复制即可

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
 
</mapper>

配置:XML映射文件的namespace属性为Mapper接口全限定名
配置:XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">

    <!--查询操作-->
    <select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        where name like concat('%',#{name},'%')
              and gender = #{gender}
              and entrydate between #{begin} and #{end}
        order by update_time desc
    </select>
</mapper>

Mybatis动态SQL

if

<if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。

<if test="条件表达式">
   要拼接的sql语句
</if>
  • <if>

    • 用于判断条件是否成立,如果条件为true,则拼接SQL

    • 形式:

      <if test="name != null"></if>
      
  • <where>

    • where元素只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
  • <set>

    • 动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)
foreach
<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每一次遍历使用的分隔符" 
         open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
</foreach>
include
<sql id="commonSelect">
 	select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
</sql>

然后通过<include> 标签在原来抽取的地方进行引用。操作如下:

  <include refid="commonSelect"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值