Mybatis入门

Mybatis入门

一、mybatis的快速入门

1、创建springboot项目
  • 直接选择必须的依赖:MyBatis FrameworkMySQL Driver
  • 在项目下创建pojo包,用来存放数据库表对应的实体类
2、配置连接信息
  • 在springboot项目的配置文件中application.properties写入一下信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/exe01
spring.datasource.username=root
spring.datasource.password=123456
3、在项目中再创建一个mapper
  • 内部用来存放创建实体类对应的实现接口(操作数据库

示例

@Mapper // 在运行时,会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理
public interface StudentMapper {// 查询所有用户信息@Select("select * from ghr_student")public List<Student> list();
}
4、进行测试这个快速入门程序
  • springboot项目的Test程序下
    • 通过@Autowired注入我们写的操作数据库的mapper接口
    • 创建一个测试方法,使用注入的接口获取数据库中的信息,并遍历打印出来

示例

@SpringBootTest
class SpringMybatisQuickstartApplicationTests {@Autowiredprivate StudentMapper studentMapper;@Testvoid contextLoads() {List<Student> list = studentMapper.list();for (Student student : list) {System.out.println(student);}}}

运行这个测试方法,就可以看到:

在这里插入图片描述

数据库中的信息被遍历出来了!

二、数据库连接池

  • 数据库连接池是个容器,负责分配、管理数据库连接(Connection)
  • 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
  • 释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏

优势

  • 资源重用
  • 提升系统响应速度
  • 避免数据库连接遗漏
数据库连接池的切换
  • 目前springboot项目自带的是Hikari连接池,如果需要切换连接池则可以通过
方法一:添加依赖

pom文件中添加其他数据库连接池的依赖即可。

示例

如果要切换成Druid数据库连接池,只需要在pom文件中添加:

<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.20</version>
</dependency>
方法二:修改配置文件

springboot的配置文件application.properties的数据库配置信息修改成:

spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/exe01
spring.datasource.druid.username=root
spring.datasource.druid.password=123456

三、使用lombok工具包

  • 使用lombok工具包简化pojo包中的实体类
  • Lombok一个实用的Java类库,能通过注解的形式自动生成构造器、getter/setterequalshashcodetoString等方法,并可以自动化生成日志变量,简化java开发、提交效率。
注解作用
@Getter/@Setter为所有的属性提供get/set方法
@ToString会给类自动生成易阅读的toString 方法
@EqualsAndHashCode根据类所拥有的非静态字段自动重写equals方法和hashcode方法
@Data提供了更综合的生成代码功能(@Getter+@Setter+@ToString+@EqualsAndHashCode)
@NoArgsConstructor为实体类生成无参的构造器方法
@AllArgsConstructor为实体类生成除了static修饰的字段之外带有各参数的构造器方法
  • 但是在springboot项目中使用时,需要在pom文件中添加依赖:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>

这样我们就可以完成简化实体类的目的了:

import lombok.*;//@Getter
//@Setter
//@ToString
//@EqualsAndHashCode
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {private String Sno;private String Sname;private String Ssex;private Integer Sage;private String Sdept;}

注意:@Data中不包括空参构造和有参构造,因此自己添加相应的注解!

四、增删改查操作

1、参数占位符
  • #{…}
    • 执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值
    • 使用时机:参数传递,都使用#{…}
  • ${…}
    • 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题,而且每次都需要重新编译
    • 使用时机:如果对表名、列表进行动态设置时使用
2、删除操作
  • 接口的定义
@Delete("delete from emp where id = #{id}")
public void delete(Integer id);
// 如果定义的返回值是int 则返回的是受影响的行数

注意事项

​ 如果mapper接口方法形参只有一个普通类型的参数,#{…}里面的属性名可以随便写,如:#{id}、#{value}。但是还是建议不要修改。

  • 像这种根据形参动态改变SQL语句的,使用的是预编译SQL,在sql语句中的占位符就是#{…}(类似于JDBC中的?占位符)
  • 要查看sql语句的执行过程,可以将mybatis的日志打印出来:application.properties中,添加配置信息,打开mybatis的日志,并指定输出到控制台
# 指定mybatis输出日志的位置,输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

这样之后,我们运行测试示例,就可以在控制台看到:

在这里插入图片描述

3、新增操作
  • 如果插入的为多个参数,我们可以使用实体类对象来将多个参数封装起来,然后在sql语句中我们就可以使用#{…}的形式来获取这个对象当中的属性
  • 接口的定义
@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);
4、主键回显
  • 描述:在数据添加成功后,需要获取插入数据库数据的主键
  • 实现

​ 只需在注解的sql语句上,新加一个注解@Options(keyProperty="id", useGeneratedKets=true),这样就会将自动生成的主键值,赋值给自定义对象的id属性,这样就可以通过新创建的这个自定义对象的GetId()方法获取此主键值

@Options(keyProperty = "id", useGeneratedKeys = true)
@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);
5、更新操作
  • 更新操作其实也和新增操作差不多,可以将需要修改的属性值封装到一个实体类对象中,然后可以在sql语句中使用#{…}的形式来获取这个对象当中的属性
  • 接口的定义
@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);
6、查询操作
  • 根据id查询该员工的所有数据,则可以将函数返回的数据类型改为相应的实体类对象即可
  • 接口的定义
@Select("select * from emp where id = #{id}")
public Emp select(Integer id);

注意:

  • 如果实体类中的属性名和表的字段名不一致时,可能会导致该属性为空值,请看第7点即可
7、数据封装
  • 实体类属性名和数据库查询返回的字段名一致,mybatis会自动封装

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

  • 解决方法

方案一给sql语句的字段起别名,让别名与实体类属性一致

@Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
public Emp select(Integer id);

方案二通过@Results@Result注解手动映射封装

@Results({@Result(column = "dept_id", property = "deptId"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})
@Select("select * from emp where id = #{id}")
public Emp select(Integer id);

映射关系:column是表中的字段名,property是类中的属性名

方案三开启mybatis的驼峰命名自动映射开关(a_cloumn --> aCloumn)

只需在主配置文件application.properties中写入:

mybatis.configuration.map-underscore-to-camel-case=true
8、条件查询
  • 如果遇到要进行多个条件查询时,可以通过and进行连接
  • 接口的定义
@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);

注意:

  • 字符串中不能直接使用#{…}

  • 当参数占位符涉及到在引号内部时,(例如上面name的模糊查询)此时不能使用#{…}这个参数占位符,它不可以变成?,所以我们需要使用${…}这个占位符,拼接我们的sql语句(例如:如果传入的name是张,则拼接后就是like '%张%',就会达到目的)

  • 如果要想使用#{…}的话,可以使用sql语句的concat()字符串拼接函数:
@Select("select * from emp where name like concat('%', #{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);

五、XML映射文件

  • 可以写Mapper接口相应的XML映射文件,用来封装sql语句(这样面对复杂的sql语句时,就比注解显得更有优势了)

  • XML映射文件的规范

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

      • resources目录下创建相同的包

      • 在相同的包下,创建文件,名字与对应的Mapper一样,后缀为.xml

      • 并且在这个xml文件中写入:

      • <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        
    • XML映射文件的namespace属性为Mapper接口全限定名一致

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

六、动态SQL

  • 随着用户输入或外部条件的变化而变化的SQL语句,我们称之为:动态SQL

  • 例如:当多个条件查询语句时,只填写单个条件时,即仅进行这个条件的查询,所以此时就需要动态SQL实现

我们可以将上述EmpMapper.xml文件进行修改成:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.springboot.springmybatisstart01.mapper.EmpMapper">
<!--    resultType:单条记录所封装的类型--><select id="list" resultType="com.springboot.springmybatisstart01.pojo.Emp">select * from emp<where><if test="name != null">name like concat('%', #{name}, '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time desc</select>
</mapper>

注意:and不要去除!

  • 例如:当进行更新数据操作时,需要选择性的修改数据,此时也要使用到动态SQL

在上面的<mapper>标签中加入:

<select id="update">update emp<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><if test="entrydate != null">entrydate = #{entrydate},</if><if test="deptId != null">dept_id = #{deptId},</if><if test="updateTime != null">update_time = #{updateTime}</if></set>where id = #{id}</select>
  • 例如:进行批量删除操作时,需要通过多个id进行删除,此时也要使用到动态SQL

在上面的<mapper>标签中加入:

<delete id="deleteByIds">delete from emp where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
</delete>

其中的<if><where><set><foreach>标签:

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

  • wherewhere元素只会在子元素有内容的情况下才插入where子句。而且会自动去除子句的开头的ANDOR

  • set:动态地在行首插入SET关键字,并会删掉额外的逗号

  • foreach:用于遍历集合元素,内部包含五个属性(一般用于一些批量操作当中)

    • collection:集合名称
    • item:集合遍历出来的元素/项
    • separator:每一次遍历使用的分隔符
    • open:遍历开始前拼接的片段
    • close:遍历结束后拼接的片段
  • 例如:当面对一些重复的sql语句时,我们可以通过<sql><include>标签进行sql语句的复用

<sql id="commonSelect">select * from emp
</sql><!--    resultType:单条记录所封装的类型-->
<select id="list" resultType="com.springboot.springmybatisstart01.pojo.Emp"><include refid="commonSelect"/><where><if test="name != null">name like concat('%', #{name}, '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time desc
</select>
  • sql:定义可复用的SQL片段,定义id用于唯一性标识
  • include:通过属性refid,指定包含的sql片段

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8062.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

消息队列篇--通信协议篇--MQTT(通配式主题,消息服务质量Qos,EMQX的Broker,MqttClient示例,MQTT报文等)

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的消息协议。它基于发布/订阅模式&#xff0c;专为低带宽、高延迟或不可靠网络设计。它主要用于物联网&#xff08;IoT&#xff09;设备之间的通信&#xff0c;但也广泛应用于其他需要高效消息传递…

dmfldr实战

dmfldr实战 本文使用达梦的快速装载工具&#xff0c;对测试表进行数据导入导出。 新建测试表 create table “BENCHMARK”.“TEST_FLDR” ( “uid” INTEGER identity(1, 1) not null , “name” VARCHAR(24), “begin_date” TIMESTAMP(0), “amount” DECIMAL(6, 2), prim…

基于OSAL的嵌入式裸机事件驱动框架——消息队列osal_msg

参考B站up主【架构分析】嵌入式祼机事件驱动框架 感谢大佬分享 消息队列 消息分为hdr和bdy&#xff0c;把消息的头dhr和内容bdy做了一个分离的设计 dhr包括指向下一个消息的指针next&#xff0c;len在创建消息的时候使用&#xff0c;dest_id即目标任务&#xff0c;将消息和任务…

关于MySQL InnoDB存储引擎的一些认识

文章目录 一、存储引擎1.MySQL中执行一条SQL语句的过程是怎样的&#xff1f;1.1 MySQL的存储引擎有哪些&#xff1f;1.2 MyIsam和InnoDB有什么区别&#xff1f; 2.MySQL表的结构是什么&#xff1f;2.1 行结构是什么样呢&#xff1f;2.1.1 NULL列表&#xff1f;2.1.2 char和varc…

单相可控整流电路——单相桥式全控整流电路

以下是关于单相桥式整流电路的介绍&#xff1a; 电路构成&#xff08;带阻性负载的工作情况&#xff09; - 二极管&#xff1a;是电路0的核心元件&#xff0c;通常采用四个同型号或根据需求选择不同型号的二极管&#xff0c;如1N4001、1N4007等&#xff0c;如图Vt1和Vt4是一对…

Linux(Centos、Ubuntu) 系统安装jenkins服务

该文章手把手演示在Linux系统下如何安装jenkins服务、并自定义jenkins数据文件位置、以及jenkins如何设置国内镜像源加速&#xff0c;解决插件下载失败问题 安装方式&#xff1a;war包安装 阿里云提供的war下载源地址&#xff1a;https://mirrors.aliyun.com/jenkins/war/?s…

力扣算法题——11.盛最多水的容器

目录 &#x1f495;1.题目 &#x1f495;2.解析思路 本题思路总览 借助双指针探索规律 从规律到代码实现的转化 双指针的具体实现 代码整体流程 &#x1f495;3.代码实现 &#x1f495;4.完结 二十七步也能走完逆流河吗 &#x1f495;1.题目 &#x1f495;2.解析思路…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】 1.3 广播机制:维度自动扩展的黑魔法

1.3 《广播机制&#xff1a;维度自动扩展的黑魔法》 前言 NumPy 的广播机制是 Python 科学计算中最强大的工具之一&#xff0c;它允许不同形状的数组进行运算&#xff0c;而无需显式地扩展数组的维度。这一机制在实际编程中非常有用&#xff0c;但初学者往往对其感到困惑。在…

Semantic Kernel - Kernel理解

目录 一、关于Kernel 二、案例实战 三、运行截图 一、关于Kernel 微软的 Semantic Kernel 项目中,Semantic Kernel 是一个工具框架,旨在使得开发人员能够更容易地将大语言模型(如GPT)集成到不同的应用中。它通过提供一组接口、任务模板和集成模块,使开发者能够轻松地设计…

【MySQL】--- 复合查询 内外连接

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; MySQL &#x1f3e0; 基本查询回顾 假设有以下表结构&#xff1a; 查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还要满足他们的姓名首字母为…

Qt Designer and Python: Build Your GUI

1.install pyside6 2.pyside6-designer.exe 发送到桌面快捷方式 在Python安装的所在 Scripts 文件夹下找到此文件。如C:\Program Files\Python312\Scripts 3. 打开pyside6-designer 设计UI 4.保存为simple.ui 文件&#xff0c;再转成py文件 用代码执行 pyside6-uic.exe simpl…

openlayer getLayerById 根据id获取layer图层

背景&#xff1a; 在项目中使用getLayerById获取图层&#xff0c;这个getLayerById()方法不是openlayer官方文档自带的&#xff0c;而是自己封装的一个方法&#xff0c;这个封装的方法的思路是&#xff1a;遍历所有的layer&#xff0c;根据唯一标识【可能是id&#xff0c;也可能…

Qt 控件与布局管理

1. Qt 控件的父子继承关系 在 Qt 中&#xff0c;继承自 QWidget 的类&#xff0c;通常会在构造函数中接收一个 parent 参数。 这个参数用于指定当前空间的父控件&#xff0c;从而建立控件间的父子关系。 当一个控件被设置为另一控件的子控件时&#xff0c;它会自动成为该父控…

SOME/IP--协议英文原文讲解1

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 一、SOM…

Ansible自动化运维实战--script、unarchive和shell模块(6/8)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件&#xff0c;其提供了一…

【模型】RNN模型详解

1. 模型架构 RNN&#xff08;Recurrent Neural Network&#xff09;是一种具有循环结构的神经网络&#xff0c;它能够处理序列数据。与传统的前馈神经网络不同&#xff0c;RNN通过将当前时刻的输出与前一时刻的状态&#xff08;或隐藏层&#xff09;作为输入传递到下一个时刻&…

《FreqMamba: 从频率角度审视图像去雨问题》学习笔记

paper&#xff1a;FreqMamba: Viewing Mamba from a Frequency Perspective for Image Deraining GitHub&#xff1a;GitHub - aSleepyTree/FreqMamba 目录 摘要 1、介绍 2、相关工作 2.1 图像去雨 2.2 频率分析 2.3 状态空间模型 3、方法 3.1 动机 3.2 预备知识 3…

iic、spi以及uart

何为总线&#xff1f; 连接多个部件的信息传输线&#xff0c;是部件共享的传输介质 总线的作用&#xff1f; 实现数据传输&#xff0c;即模块之间的通信 总线如何分类&#xff1f; 根据总线连接的外设属于内部外设还是外部外设将总线可以分为片内总线和片外总线 可分为数…

Android WebView 中网页被劫持的原因及解决方案

文章目录 一、原因分析二、解决方案一览三、解决方案代码案例3.1 使用 HTTPS3.2 验证 URL3.3 禁用 JavaScript3.4 使用安全的 WebView 设置3.5 监控网络请求3.6 使用安全的 DNS 四、案例深入分析4.1 问题4.2 分析 五、结论 在 Android 应用开发中&#xff0c;WebView 是一个常用…

Linux——网络(udp)

文章目录 目录 文章目录 前言 一、upd函数及接口介绍 1. 创建套接字 - socket 函数 2. 绑定地址和端口 - bind 函数 3. 发送数据 - sendto 函数 4. 接收数据 - recvfrom 函数 5. 关闭套接字 - close 函数 二、代码示例 1.服务端 2.客户端 总结 前言 Linux——网络基础&#xf…