当前位置: 首页 > article >正文

# MyBatis 基础了解

MyBatis最初是Apache基金会的一个开源项目,名为iBatis。是一款基于Java的持久层框架。

核心优点:

  • 支持定制化SQL:MyBatis允许开发者编写自定义的SQL语句,满足复杂的业务需求。
  • 存储过程与高级映射:除了支持SQL语句外,MyBatis还支持存储过程以及高级映射功能。
  • 消除JDBC代码:MyBatis免除了几乎所有的JDBC代码,以及手动设置参数和获取结果集的工作。
  • XML或注解配置:MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO(Plain Ordinary Java Objects,普通的Java对象)为数据库中的记录。
  • 动态SQL:MyBatis支持根据不同的条件构造动态SQL语句,提高了代码的复用性。
  • 缓存机制:提供一级缓存和二级缓存,减少了对数据库的频繁访问,提高了系统性能。
  • 解除SQL与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。

一 入门

1 快速入门

创建Springboot 项目的时候 选择l两个依赖

  • MyBatis Framework
  • MySQL Driver

创建项目之后要在resources 下面的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

创建一个User类

public class User {
    private Integer id;
    private String name;
    private Short age;
    private Short gender;
    private String phone;
}

创建一个接口

package org.example.springbootmybatisquickstart.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.example.springbootmybatisquickstart.pojo.User;

import java.util.List;

@Mapper//在程序运行的时候框架会自动生成该接口的实现类对象 并且将对象交给IOC容器管理
public interface UserMapper {
    //查询全部用户信息
    @Select("select * from user")
    public List<User> listUser();
}

然后再单元测试中运行

package org.example.springbootmybatisquickstart;

import org.example.springbootmybatisquickstart.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.example.springbootmybatisquickstart.pojo.User;
import java.util.List;
@SpringBootTest
class SpringbootMybatisQuickStartApplicationTests {

  @Autowired
  private UserMapper userMapper;
  @Test
  public void testListUser () {
      List<User> userList = userMapper.listUser();
      for (User user : userList) {
          System.out.println(user);
      }
  }

}


运行程序然后就会查询出来所有结果

User{id=1, name='白眉鹰王', age=55, gender=1, phone='18800000000'}
User{id=2, name='金毛狮王', age=45, gender=1, phone='18800000001'}
User{id=3, name='青翼蝠王', age=38, gender=1, phone='18800000002'}
User{id=4, name='紫衫龙王', age=42, gender=2, phone='18800000003'}
User{id=5, name='光明左使', age=37, gender=1, phone='18800000004'}
User{id=6, name='光明右使', age=48, gender=1, phone='18800000005'}
2 配置相关提示

右键选中SQL 语言 ,然后选择 显示上下午操作

在这里插入图片描述

3 JDBC概念

1 >定义**:JDBC是Java语言用来规范客户端程序如何访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。
2 >**功能:
* 连接数据库:通过JDBC,Java程序可以连接到各种关系型数据库。
* 执行SQL语句:Java程序可以使用JDBC执行SQL查询、更新、删除等操作。
* 处理结果集:JDBC提供了处理SQL查询结果集的方法,使开发者可以方便地获取和处理数据。

4 数据库连接池

1> 定义

数据库连接池是一个连接的集合,它维护了一组数据库连接以供应用程序使用,而不是每次都创建新的连接。这些连接在需要时被提供给应用程序,使用完后被返回到池中以供后续使用。

2> 原理

数据库连接池在内部维护一定数量的数据库连接,并对外提供获取和返回连接的方法。当应用程序需要访问数据库时,它会从连接池中获取一个已建立的连接,而不是创建一个新的连接。当应用程序完成数据库操作后,它会将连接返回给连接池,以便其他应用程序或同一应用程序的后续操作可以重用该连接。

3> 优势

  • 提升性能

建立和断开数据库连接是耗时的操作。通过连接池,可以避免频繁创建和关闭连接,从而减少开销,提升系统性能。

  • 资源管理 :

    数据库连接是宝贵的资源。连接池能有效管理和复用这些连接,避免资源浪费,使应用程序更高效运行。

  • 并发处理

    在高并发场景下,多个请求共享连接能减少数据库连接数量,提高并发处理能力,使应用程序更具扩展性。

  • 连接可靠性

    网络问题或服务器故障可能导致数据库连接中断。但有了连接池,一旦检测到失效连接,它会立即重新创建一个可用的连接,确保应用程序始终可靠运行。

4> 实现

SpringBoot 是默认使用的hikari连接池
内部实现了这个方法
public Connection getConnection() throws SQLException

德鲁伊(Druid)连接池是阿里巴巴开源的一个高性能数据库连接池项目,广泛应用于各种Java应用程序中,特别适用于高并发、高性能、稳定可靠的数据库连接管理场景。以下是对德鲁伊连接池的详细介绍:

如果要切换德鲁伊连接池,那么先把其依赖引入进来

在这里插入图片描述

5 lombok

Lombok是一个Java库,它通过注解的方式自动为Java类生成诸如getter、setter、equals、hashCode、toString等方法的代码,从而减少了样板代码的编写,使得Java代码更加简洁、易读和可维护。
Lombok提供了一系列注解,这些注解可以在Java类中使用,以自动生成常用的方法。以下是一些常用的Lombok注解及其功能:

  • 1 @Getter:生成类的getter方法。如果注解在字段上,则只为该字段生成getter方法。
  • 2 @Setter:生成类的setter方法。如果注解在字段上,则只为该字段生成setter方法。
  • 3 @ToString:生成toString方法。
  • 4 @EqualsAndHashCode:生成equals和hashCode方法。
  • 5 @Data:这是一个方便的注解,它集成了@Getter、@Setter、@ToString、@EqualsAndHashCode和@NoArgsConstructor注解的功能,为类生成这些方法。
  • 6 @NoArgsConstructor:生成无参构造函数。
  • 7 @AllArgsConstructor:生成包含所有参数的构造函数。
  • 8 @RequiredArgsConstructor:生成包含标记为final的字段的构造函数,以及带有@NonNull注解的字段。
  • 9 @Builder:生成建造者模式的构造函数,用于构建复杂对象。

二 Mybatis 操作

1 删除

//根据id删除员工数据
@Delete("delete from tb_emp where id = #{id}")
// 返回值int是影响的行数
int deleteEmpById(Integer id);


可以配置mybatis 日志输出到控制台

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

控制台就会显示预编译SQL 语句
预编译SQL 性能更高 并且 更加安全

JDBC Connection [HikariProxyConnection@1971344738 wrapping com.mysql.cj.jdbc.ConnectionImpl@1d806de6] will not be managed by Spring
==>  Preparing: delete from tb_emp where id = ?
==> Parameters: 15(Integer)
<==    Updates: 0

在这里插入图片描述

SQL 注入 是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器攻击的方法

2 新增

// 增加员工数据 这里下划线使用驼峰代替
@Insert("insert into tb_emp(username, name, gender, image, job, dept_id, create_time, update_time) values (#{username},#{name},#{gender},#{image},#{job},#{deptId},#{createTime},#{updateTime});")
int insertEmp(Emp emp);

主键返回 :
在新增数据成功之后,需要获取插入数据库的数据的主键。

// 主键返回,会自动将生成主键值,赋值给emp.id属性返回
@Options(keyProperty = "id",useGeneratedKeys = true)

3 更新数据

// 更新数据
@Update("update tb_emp set username = #{username}, name=#{name} ,gender = #{gender} ,image =#{image},job=#{job} where id = #{id};")
public void updateEmp(Emp emp);

4 查询数据

// 查询数据
@Select("select * from tb_emp where id = #{id};")
Emp selectEmpById(Integer id);

数据封装
如果实体类属性名 和 数据库表查询返回的字段名一直,mybatis 会自动封装,否则不能自动封装

如若存在不一致的情况,如下解决方案

// 起个别名
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId, create_time createTime,  update_time updateTime from tb_emp where id = #{id};")
Emp selectEmpById(Integer id);

第二种方案 注解

// 通过Result 注解手动映射封装
@Results({
        @Result(column = "dept_id", property = "deptId"),
        @Result(column = "create_time", property = "createTime"),
        @Result(column = "update_time", property = "updateTime"),
})
@Select("select * from tb_emp where id = #{id};")
Emp selectEmpById(Integer id);

第三种方案 开启mybatis 的驼峰命名自动映射开关

# 配置mybatis的自动映射
mybatis.configuration.map-underscore-to-camel-case=true

查询多个条件的数据

// 查询多个条件的数据 这个地方是$符号,不是#符号,因为#符号是mybatis的占位符,$符号是字符串的占位符
@Select("select * from tb_emp where name like '%${name}%' and gender = #{gender} order by create_time desc;")
List<Emp> selectSearchEmp(String name,Short gender);

但是为了避免sql 注入 ,推荐 使用下面的方式concat 拼接函数

// select * from tb_emp where name like concat('%', '张', '%') and gender = 1 order by create_time desc;
@Select("select * from tb_emp where name like concat('%', #{name}, '%') and gender = #{gender} order by create_time desc;")
List<Emp> selectSearchEmp(String name,Short gender);

三 XML 映射文件

映射文件的名字必须与接口名称一致,同包同名

在这里插入图片描述

XML 配置文件可以查询官网 http://mybatis.p2hp.com/configuration.html

<?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="org.example.springbootmybatisquickstart.EmpMapper">
    <select id="selectSearchEmp" resultType="org.example.springbootmybatisquickstart.pojo.Emp">
        select * from tb_emp where name like concat('%', #{name}, '%') and gender = #{gender} order by create_time desc
    </select>
</mapper>


可以在插件市场 安装MyBatisX 插件 ,

四 动态SQL

动态SQL指的是在运行时根据条件构建SQL语句,而不是使用静态的SQL语句。它可以根据不同的条件生成不同的SQL语句,使得查询、更新或删除数据时能够根据具体情况进行灵活的处理。

1 作用
  • 1 >条件灵活:使用动态SQL可以根据不同的条件生成不同的SQL语句,满足各种查询、更新或删除需求。
  • 2> 查询优化:有时候在编写静态SQL语句时难以预料到查询条件的变化,而使用动态SQL可以根据运行时的条件动态调整查询语句,从而更好地适应实际情况,提高查询性能。
  • 3> 动态表名和字段名:有时候需要根据不同的场景来操作不同的表或字段,这时候就可以利用动态SQL来动态构建表名和字段名,实现灵活性和扩展性。
  • 4> 防止SQL注入:通过使用参数化查询或者绑定变量的方式来构建动态SQL,可以有效防止SQL注入攻击,提升系统的安全性。
2 常用标签

MyBatis通过一系列的动态SQL标签来实现动态SQL的功能,这些标签包括:

  • 1> :根据条件动态拼接SQL。该标签用于根据条件判断是否包含某段SQL片段。
  • 2> :用于处理集合,生成IN查询或者批量操作语句。
  • 3> sql 是定义可重用的SQL片段,include 是通过属性refid 指定包含sql片段
  • 4> :用于自动添加WHERE关键字,并去除多余的AND或OR。如果标签中的if条件都不满足,则标签没有任何功能;若条件满足,则标签会自动添加WHERE关键字,并将条件前面多余的AND或OR去掉。
  • 5> :用于动态更新语句中的SET部分,可以自动添加逗号并去除多余的逗号。
<mapper namespace="org.example.springbootmybatisquickstart.mapper.EmpMapper">
    <select id="selectSearchEmp" resultType="org.example.springbootmybatisquickstart.pojo.Emp">
        select * from tb_emp

        <where>
            <if test="name!= null and name!= ''">
                name like concat('%', #{name}, '%')
            </if>
            <if test="gender!= null">
                  gender = #{gender}
            </if>
            order by create_time desc
        </where>
    </select>
</mapper>

<!-- 定义查询所有员工信息的操作  -->

    <update id="update2">
        update tb_emp set
        <set>
        <if test="username!= null">
            username = #{username},
        </if>
        <if test="name!= null">
            name = #{name},
        </if>
        <if test="gender!= null">
            gender = #{gender},
        </if>
        <if test="image!= null">
            image = #{image},
        </if>
        <if test="job!= null">
            job = #{job}
        </if>
        </set>


        where id = #{id}

    </update>

for each

<!--  批量删除员工的操作-->
<!--
 collection=要遍历的集合
 item=遍历出来的元素
 separator = 分隔符
 open = 遍历开始前拼接的SQL片段
  close = 遍历结束后拼接的SQL片段 -->
<delete id="deleteEmpByIds">
    delete from tb_emp where id in
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>

</delete>

<sql id="commonSelectEmp">
    selcte id,username,name,gender,image,job,create_time from tb_emp
</sql>
<select id="selectSearchEmp" resultType="org.example.springbootmybatisquickstart.pojo.Emp">
    <include refid="commonSelectEmp"/>
    <where>
        <if test="name!= null and name!= ''">
            name like concat('%', #{name}, '%')
        </if>
        <if test="gender!= null">
              gender = #{gender}
        </if>
        order by create_time desc
    </where>
</select>


http://www.kler.cn/a/504933.html

相关文章:

  • camera 配置预览和拍照streams上报的可用尺寸列表
  • DevOps实用场景:在哪些业务中应用DevOps最有效
  • selenium操作指南,2万字总结
  • 【力扣Hot100】双指针
  • Linux磁盘存储与内存管理命令
  • 【C++学习篇】红黑树 从入门到进阶
  • Vue 开发者的 React 实战指南:表单处理篇
  • 微信小程序:跨页面数据修改全攻略
  • Web前端------HTML块级和行内标签之行内标签
  • Inxpect毫米波安全雷达:精准检测与动态保护,工业自动化可靠选择
  • 求 n 个数的最小公倍数(详解版)
  • Go语言编译的exe文件占用内存过大解决办法
  • HTTP中form-data、x-www-form-urlencoded、raw、binary的区别
  • L4-Prompt-Delta
  • 【零基础入门unity游戏开发——unity3D篇】URP 3D光源组件(Light)介绍、烘培灯光、实现太阳耀斑镜头光晕效果(基于unity6开发介绍)
  • 高等数学学习笔记 ☞ 不定积分与积分公式
  • JavaScript this、回调函数、事件流
  • 电脑电源灯一闪一闪开不了机 原因分析
  • 确保使用爬虫技术时的合法性
  • MAC上安装Octave