MyBatis 操作数据库(⼊⻔)

前言

通过本篇博客,我们将学到以下内容

        1.使⽤MyBatis完成简单的增删改查操作,参数传递

        2.掌握MyBatis的两种写法: 注解和 XML⽅式

        3.掌握 MyBatis 相关的⽇志配置

什么是 MyBatis?

        MyBatis是⼀款优秀的 持久层 框架,⽤于简化JDBC(关于 JDBC 推荐看JAVA连接数据库 JDBC编程)的开发,通过 MyBatis 我们可以很简单的访问和操作数据库

MyBatis 使用流程

准备工作

        配置都是放到 application.properties 或者 application.yml 文件中

1.创建项目,引入依赖

        本篇博客使用 MyBatis 框架的是 springboot ⼯程,所以我们先要创建 springboot 项目,推荐看idea必装的插件 Spring Boot Helper 插件(创建 Spring Boot 项目),并导⼊ mybatis 的依赖、mysql 的驱动包

        如果是新创建的项目,在创建时直接导入即可

        如果是已经创建的项目可以通过 EditStarters 插件快速导入,推荐看idea必装插件EditStarters(快速引入依赖)

2.配置 MyBatis 连接数据库

        Mybatis要连接数据库,需要配置数据库的相关参数

•MySQL驱动

•登录名

•密码

•数据库连接字符串

配置内容如下:

#驱动类名称 
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库url(mybatis_test是数据库的名称)
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC
#数据库用户名
spring.datasource.username=root
#数据库密码
spring.datasource.password=xxx

        注意事项:如果使⽤MySQL是 5.x 之前的使⽤的是 com.mysql.jdbc.Driver,如果是⼤于 5.x 使⽤的是 com.mysql.cj.jdbc.Driver

3.配置 MyBatis 日志

        通过 MyBatis 日志,我们可以很好的观察 sql 语句的执行情况,配置内容如下:

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

4.准备测试数据

数据表 userinfo 的结构如下:

实体类的定义如下:

@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

通过注解进行数据库操作

1.通过注解实现 增(insert)

@Mapper //将 UserInfoMapper 接口的实现类的对象交给 Spring 的 IoC 容器进行管理
public interface UserInfoMapper {
    //1.增加用户信息
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into userinfo( username, password, age, gender, phone )"+
            "values(#{username},#{password},#{age},#{gender},#{phone})")
    public Integer insert(UserInfo userInfo);
}

        @Mapper 注解表示将 UserInfoMapper 接口的实现类的对象交给 Spring 的 IoC 容器进行管理,我们后面可以通过 @Autowired 注解来获取到 Spring 的 IoC 容器管理的对象,推荐看Spring IoC & DI 使⽤

        @Options 注解用来获得自增主键,因为我们在创建表的时候,主键 id 设置了AUTO_INCREMENT ,所以在插入数据的时候我们不需要指定 id 的值,mysql 会自动赋值,但我们插入数据以后可能需要知道插入的这条数据的自增 id 为多少,我们就可以通过@Options 注解来获取:

        useGeneratedKeys = true 表示需要 MyBatis 取出表中由数据库内部⽣成的主键

        keyProperty = "id"  表示 MyBatis 取出的主键数据赋值给哪个属性

         @Insert 注解内写的是插入的 sql 语句,调用 insert 方法就会执行 @Insert 注解内的 sql 语句,通过 #{} 的方式传参,参数直接写 userInfo 对象的属性名,Spring 会自动进行匹配

        执行 insert 方法调用 sql 语句后会返回受影响的数据行数,所以返回类型可以写为 Integer 

        扩展:可以通过 @Param 注解修改参数名 比如 insert(@Param("use")  UserInfo userInfo),修改以后传参就要用 #{use.username} 的形式传

测试代码

        我们可以通过在业务代码上右键选择 Generate->Test 编写当前类中指定方法的测试代码

        如下代码 userInfoMapper 调用 insert 方法将数据插入到表中后,会将自增主键赋值给userInfo 对象的 id 属性,通过 getId 方法获得该行数据的自增主键

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Test
    void insert() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("zhaoliu");
        userInfo.setGender(2);
        userInfo.setAge(21);
        userInfo.setPhone("18612340005");

        userInfoMapper.insert(userInfo);
        System.out.println(userInfo.getId());
    }
}

                @SpringBootTest ,在测试类中没有配置 SpringBoot 的环境,所以我们要想使用 Spring Boot 的相关机制,就要加上 @SpringBootTest 注解,引入 SpringBoot 的环境

2.通过注解实现 删(delete)

//2.通过 id 来删除数据
    @Delete("delete from userinfo where id=#{id}")
    public Integer delete(Integer id);

        @Delete 注解内写的是删除的 sql 语句,调用 delete 方法就会执行 @Delete 注解内的 sql 语句,通过 #{} 的方式传参

        执行 delete 方法调用 sql 语句后会返回受影响的数据行数,所以返回类型可以写为 delete

3.通过注解实现 改(update)

//3.通过 id 来修改 username
    @Update("update userinfo set username=#{username} where id=#{id};")
    public Integer update(Integer id,String username);

         @Update 注解内写的是修改的 sql 语句,调用 update 方法就会执行 @Update 注解内的 sql 语句,通过 #{} 的方式传参

        执行 update 方法调用 sql 语句后会返回受影响的数据行数,所以返回类型可以写为 delete

4.通过注解实现 查(select)

 //通过 id 来查找用户信息
    @Select("select id,username,password,age,gender,phone,delete_flag,create_time," +
            "update_time from userinfo where id=#{id};")
    public UserInfo select(Integer id);

        开发经验:关于 select 的 sql 语句尽量不要用 * ,需要什么字段就获取什么字段,要是都需要,就把所有的字段都填上

        @Select 注解内写的是查询的 sql 语句,调用 select 方法就会执行 @Select 注解内的 sql 语句,通过 #{} 的方式传参

        由于我们是通过 id 来查询数据,所以只会有一行数据,就只需要一个 UserInfo 对象接收即可,所以返回值类型为  UserInfo ,如果我们查询到多条数据,返回值类型就应该是 List<UserInfo> 要是依然用  UserInfo 来接收的话程序就会报错

测试代码

 void select() {
        UserInfo userInfo=new UserInfo();
        userInfo=userInfoMapper.select(3);
        System.out.println(userInfo.toString());
    }

        查询到数据以后,MyBatis 会根据表的字段名和  UserInfo 对象的属性名自动建立映射关系,但此时我们的代码会出现一些问题,查询以后得到的数据如下:

        如上图所示,查询到的该行数据中 delete_flag ,create_time,update_time 为null,说明这3个字段中的内容没有成功赋值给 userInfo 对象

这是因为数据表 userinfo 的字段为id,username,password,age,gender,phone,delete_flag,create_time,update_time

UserInfo 类的属性为

id,username,password,age,gender,phone,deleteFlag,,createTime,updateTime

        我们可以看到 id,username,password,age,gender,phone 这几个数据表的字段名和 UserInfo 类的属性名相同,所以 MyBatis 能够知道它们之间的映射关系,而delete_flag,create_time,update_time 这几个数据表的字段名和 UserInfo 类的属性名deleteFlag,,createTime,updateTime 不相同,所以 MyBatis 不知道它们之间的映射关系,就无法把对应的数据赋值到 userInfo 对象的这3个属性中

手动设置映射关系

        此时就需要我们通过 @Results 注解手动设置它们之间的映射关系,代码如下:

//通过 @Results 注解设置映射关系(当字段名和属性名不相同时才有必要设置)
    // id 表示为该映射关系命名,方便其他方法也可以使用该映射关系,value 表示具体的映射关系
    @Results(id = "UserInfoRes",value = {
            @Result(column = "delete_flag",property = "deleteFlag"),
            @Result(column = "create_time",property = "createTime"),
            @Result(column = "update_time",property = "updateTime")
    })
    @Select("select id,username,password,age,gender,phone,delete_flag,create_time," +
            "update_time from userinfo where id=#{id};")
    public UserInfo select2(Integer id);

        如上代码,我们通过  @Results 注解,手动设置了数据表的字段名和类的属性名之间的映射关系

      id 表示为该映射关系命名,以便后面的方法可以直接使用此处定义的映射关系,value 就表示具体的映射关系,映射关系有多条,所以  value 对应的值是数组,要用 {} 包裹

        通过 @Result 注解具体设置一条映射关系,column 翻译为列,表示数据表的字段名,property 翻译为属性,表示类的属性名,此时就为字段名和属性名建立了映射关系

        此时我们再测试 select2 方法,如下所示:

        userinfo 对象中的 deleteFlag,,createTime,updateTime 这3个属性被成功赋值

开启驼峰命名(推荐)

        由于在开发中,表的字段名通常都是蛇形的方法,例如:delete_flag,create_time,update_time

而实体类属性的命名通常都是小驼峰的方法,例如:deleteFlag,,createTime,updateTime,所以 MyBatis 提供了相关的配置项,可以直接将蛇形的字段名和小驼峰的属性名建立映射关系

配置如下:

mybatis.configuration.map-underscore-to-camel-case= true

        加上该配置以后,MyBatis 就知道了delete_flag,create_time,update_time 和deleteFlag,,createTime,updateTime 之间的映射关系

通过XML实现数据库操作

准备工作

        1.配置 mybatis xml 的⽂件路径

,配置代码如下

mybatis.mapper-locations=classpath:mapper/**Mapper.xml

        classpath 表示 resources 文件夹

        mapper/**Mapper.xml 是 xml 文件在 resources 文件夹下的具体路径,按上述配置,我们的 xml 文件可以放到下图中的位置

        2.MyBatis 的固定 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.example.springbootdemo.Mapper.UserInfoXMLMapper">

</mapper>

        上面的固定格式中,<mapper> 标签的 namespace 属性,表示命名空间,值为 mapper 接⼝(我们需要创建一个 mapper 接⼝来进行方法的声明)的全限定名,包括全包名.类名

1.通过XML实现 增 (insert)

        在 UserInfoXMLMappe 接口中方法的声明

@Mapper
public interface UserInfoXMLMapper {
    //插入数据
    Integer insert(UserInfo userInfo);
}

        在 UserInfoXMLMapper.xml 文件中写方法的实现( sql 语句)

 <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo(username,password,age,gender,phone)
        values(#{username},#{password},#{age},#{gender},#{phone});
 </insert>

         <insert> 标签表示定义插入的 sql 语句 其中 id 属性对应 UserInfoXMLMapper 中的方法名,通过 #{} 进行传参

        如果我们需要获得插入该行数据时产生的自增主键,设置 useGeneratedKeys 为 true 表示要获取自增主键,keyProperty 属性表示获取到的自增主键赋值给对象的哪个属性

2.通过XML实现 删 (delete)

        在 UserInfoXMLMappe 接口中方法的声明

 //根据 id 删除数据
    Integer delete(Integer id);

          在 UserInfoXMLMapper.xml 文件中写方法的实现( sql 语句)

<delete id="delete">
        delete from userinfo where id=#{id};
</delete>

        <delete> 标签表示定义删除的 sql 语句 其中 id 属性对应 UserInfoXMLMapper 中的方法名,通过 #{} 进行传参

3.通过XML实现 改 (update)

        在 UserInfoXMLMappe 接口中方法的声明

//根据 id 修改姓名
Integer update(Integer id,String username);

          在 UserInfoXMLMapper.xml 文件中写方法的实现( sql 语句)

<update id="update">
    update userinfo set username=#{username} where id=#{id};
</update>

        <update> 标签表示定义修改的 sql 语句 其中 id 属性对应 UserInfoXMLMapper 中的方法名,通过 #{} 进行传参

4.通过XML实现 查 (delete)

        在 UserInfoXMLMappe 接口中方法的声明

//查询所有的用户信息
List<UserInfo> select();

        在 UserInfoXMLMapper.xml 文件中写方法的实现( sql 语句)

<select id="select" resultType="com.example.springbootdemo.dao.UserInfo">
        select id,username,password,age,gender,phone,delete_flag,create_time,
</select>

        但我们通过 UserInfoXMLMappe 接口的实现类对象调用 select 方法我们同样会发现,出现了deleteFlag,createTime, updateTime,三个属性为 null ,没有赋值的问题

        这个问题的出现同样是因为,字段名和属性名不同,导致 MyBatis 不知道它们之间的映射关系,解决方法也和通过注解进行数据库操作差不多,其中开启驼峰命名这个方法是完全相同的,手动设置映射关系有点不同

手动设置映射关系

        通过 xml 文件操作数据库时,手动设置映射关系的代码如下:

<resultMap id="UseMap" type="com.example.springbootdemo.dao.UserInfo">
        <id column="id" property="id"></id>
        <result column="delete_flag" property="deleteFlag"></result>
        <result column="create_time" property="createTime"></result>
        <result column="update_time" property="updateTime"></result>
</resultMap>

        <resultMap> 在该标签中设置映射关系,id 属性表示为该映射关系命名,方便后续重复使用,type 属性表示映射关系对应的类的全限定名,包括全包名.类名

         <id> 标签表示设置主键的映射关系,column 属性对应字段名,property 属性对应属性名

        <result> 标签表示设置普通的映射关系 ,column 属性对应字段名,property 属性对应属性名

        设置好映射关系后,要将映射关系添加到代码实现中

    <select id="select" resultMap="UseMap">
        select id,username,password,age,gender,phone,delete_flag,create_time,
               update_time from userinfo;
    </select>

        如上图,通过 resultMap 属性,添加映射关系到具体代码实现中

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

推荐5款堪称神器的免费软件

​ 今天再次推荐5个良心好用的Windows神级软件&#xff0c;每一个都是完全免费&#xff0c;堪称神器&#xff0c;让你打开新世界的大门。 1.文件复制——SuperCopy ​ SuperCopy 是一款 Chrome 浏览器的扩展&#xff0c;可以帮助您解除网站上禁止复制、右键、全选、粘贴等限制…

Linux Docker图形化工具Portainer如何进行远程访问?

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具&#xff0c;可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…

easyExcle单元格合并

自定义单元格合并策略&#xff1a; /*** 自定义单元格合并策略** create: 2023-11-15 13:41**/ Data NoArgsConstructor AllArgsConstructor Slf4j public class EasyExcelCustomMergeStrategy implements RowWriteHandler {/*** 总数*/private Integer totalNum;//合并行计数…

填充每个节点的下一个右侧节点指针

题目链接 填充每个节点的下一个右侧节点指针 题目描述 注意点 给定一个 完美二叉树 解答思路 广度优先遍历一层层的遍历二叉树&#xff0c;将每一层节点的next指针都指向右侧节点 代码 class Solution {public Node connect(Node root) {if (root null) {return null;}…

[nlp] 损失缩放(Loss Scaling)loss sacle

在深度学习中,由于浮点数的精度限制,当模型参数非常大时,会出现数值溢出的问题,这可能会导致模型训练不稳定。为了解决这个问题,损失缩放(Loss Scaling)技术被引入,它通过缩放损失值来解决这个问题。 在深度学习中,损失缩放技术通常是通过将梯度进行缩放来实现的。具…

【ES6标准入门】JavaScript中的模块Module语法的使用细节:export命令和imprt命令详细使用,超级详细!!!

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;JavaScript进阶指南 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继…

Google codelab WebGPU入门教程源码<5> - 使用Storage类型对象给着色器传数据(源码)

对应的教程文章: https://codelabs.developers.google.com/your-first-webgpu-app?hlzh-cn#5 对应的源码执行效果: 对应的教程源码: 此处源码和教程本身提供的部分代码可能存在一点差异。运行的时候&#xff0c;点击画面可以切换效果。 class Color4 {r: number;g: numb…

Java面向对象(高级)-- static关键字的使用

文章目录 一、static关键字&#xff08;1&#xff09;类属性、类方法的设计思想&#xff08;2&#xff09; static关键字的说明&#xff08;3&#xff09;static修饰属性1. 复习变量的分类2. 静态变量2.1 语法格式2.2 静态变量的特点2.3 举例2.3.1 举例12.3.2 举例22.3.3 举例3…

linux套接字-Socket

1.概念 局域网和广域网 局域网&#xff1a;局域网将一定区域内的各种计算机、外部设备和数据库连接起来形成计算机通信的私有网络。广域网&#xff1a;又称广域网、外网、公网。是连接不同地区局域网或城域网计算机通信的远程公共网络。IPInternet Protocol&#xff09;&#…

无需云盘,不限流量实现Zotero跨平台同步:内网穿透+私有WebDAV服务器

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 无需云盘&#xff0c;不限流量实现Zotero跨平台同步&#xff1a;内网穿透私有WebDAV服务器 文章目…

系列八、堆(Heap)

一、概述 一个JVM实例只存在一个堆内存&#xff0c;堆内存的大小是可以手动调节的。类加载器读取了类文件后&#xff0c;需要把类、方法、常变量放到堆内存中&#xff0c;保存所有引用类型的真实信息&#xff0c;以方便执行器执行&#xff0c;堆内存分为三个部分&#xff0c;即…

高压开关柜实现无线测温监控关键点在哪里?

近年来&#xff0c;电力系统已发生多起因设备过热而发生火灾和大面积停电事故。据统计分析&#xff0c;我国每年发生的电力事故&#xff0c;有40&#xff05;是由高压电气设备过热所致&#xff1b;而在采用高压开关柜和电力电缆的供电系统中&#xff0c;有70&#xff05;以上的…

36、Flink 的 Formats 之Parquet 和 Orc Format

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

教育案例分享 | 安全狗云安全体系为高校提升立体化纵深防御能力

一、客户情况 某高校有服务器500台&#xff0c;对外站点200个&#xff0c;核心交换流量20G。 二、客户痛点 校园网系统分类较多&#xff0c;并且每类网站中安全级重要程度又各不相同&#xff0c;同时有多个网络出口(如&#xff1a;教育网、电信网、移动网等)&#xff0c;二级学…

你不懂API接口是什么?怎么和程序员做朋友

说到开发平台就一定离不开接口&#xff0c;作为PM&#xff0c;我们不需要对接口了解的特别细。只需要知道接口是什么&#xff0c;有什么用&#xff0c;有哪些要素就行。 1. 接口是什么 (1) 硬件接口 生活中我们经常会接触接口&#xff0c;最常见的就是HDMI接口和USB接口&…

软件测试/测试开发丨人工智能产品质量保障:挑战与创新

点此领取人工智能课程 人工智能产品的质量保障与测试是当前软件开发领域最具挑战性的任务之一。随着人工智能技术的迅猛发展&#xff0c;产品日益复杂&#xff0c;传统测试方法逐渐显得力不从心。在这个背景下&#xff0c;我们需要创新性地思考并采用新的策略&#xff0c;以确…

使用 Java 枚举和自定义数据类型

介绍 在 Java 编程领域&#xff0c;理解并有效利用枚举和自定义数据类型对于编写健壮、可维护且高效的代码至关重要。这篇文章旨在深入研究 Java 枚举和自定义数据类型的概念&#xff0c;提供见解和示例&#xff0c;以增强您的编码技能和知识。 理解 Java 中的枚举 枚举是枚…

十秒钟学会Mac系统和Linux之间的文件传输

前言 在我们的mac系统上&#xff0c;大家应该要先学会用我们的终端远程连接Linux的虚拟机或者云服务器&#xff0c;教程在这篇博客&#xff1a;http://t.csdnimg.cn/KQzgc 大家如果想安装iterm2和on-my-zsh&#xff08;非常推荐&#xff0c;很好用&#xff09;的话&#xff0c;…

CentOS中安装常用环境

一、CentOS安装 redis ①&#xff1a;更新yum sudo yum update②&#xff1a;安装 EPEL 存储库 Redis 通常位于 EPEL 存储库中。运行以下命令安装 EPEL 存储库 sudo yum install epel-release③&#xff1a;安装 Redis sudo yum install redis④&#xff1a;启动 Redis 服…

java 批量更改

直接上代码 void batchUpdateSpecificationId(Param("infos") List<GoodsInfo> infos);<update id"batchUpdateSpecificationId">update goods_infoset specification_id <foreach collection"infos" item"info" open&…