MyBatis操作数据库(1)

前言

在应用分层的学习时, 我们了解到web应用程序一般分为三层,即Controller, Service, Dao.

之前的案例中, 请求流程如下: 浏览器发起请求, 先请求Controller, Controller接受到请求后,调用Service进行业务逻辑处理, Service再调用Dao, 但是Dao层的数据是Mock的, 真实的数据是从数据库中读取.

我们学习MySQL数据库时, 已经学习了用JDBC操作数据库, 但是JDBC过于复杂. 因此我们可以使用MyBatis以更方便, 更快速的操作数据库.

什么是MyBatis

MyBatis 是一款优秀的持久层框架, 用于简化JDBC的开发.

持久层: 指的就是持久化操作的层, 通常指数据访问层(dao), 是用来操作数据库的.

MyBatis入门

MyBatis操作数据库的步骤:

1.准备工作(创建Springboot工程, 数据库表准备, 实体类)

2.引入MyBatis相关依赖.

3.编写SQL语句(注解/XML).

4.测试 

准备工作

创建工程

创建springboot工程, 并导入mybatis的起步依赖, mysql的驱动包

 Mybatis是一个持久层框架, 具体的数据存储和数据操作还是在MySQL中操作的, 所以需要添加MySQL驱动. 

项目工程创建完成后, 自动在pom.xml文件中, 导入Mybatis依赖和MySQL驱动依赖.

版本会随着SpringBoot版本发生变化, 无需关注. 

数据准备 

创建用户表, 并创建对应的实体类User.

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`username` VARCHAR ( 127 ) NOT NULL,
`password` VARCHAR ( 127 ) NOT NULL,
`age` TINYINT ( 4 ) NOT NULL,
`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
`phone` VARCHAR ( 15 ) DEFAULT NULL,
`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
-- 添加⽤⼾信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

创建对应的实体类UserInfo

实体类的属性名与表中的字段名一一对应. 

import lombok.Data;

import java.util.Date;

@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;
}

 配置数据库连接字符串

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

MySQL驱动类

登录名

密码

数据库连接字符串

如果是application.yml文件, 配置内容如下:

# 数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: 550407
    driver-class-name: com.mysql.cj.jdbc.Driver

写持久层代码

按如下格式创建:

import com.bit.mybatis.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface UserInfoMapper {
    //查询所有用户
    @Select("Select username, password, age, gender, phone from userinfo")
    public List<UserInfo> queryAllUser();
}

MyBatis的持久层接口规范一般都叫XxxMapper

@Mapper注解: 表示的是MyBatis中的Mapper接口

程序运行时, 框架会自动生成接口的实现类对象(代理对象), 并交给Spring的IOC容器管理.

@Select注解: 代表的就是select查询, 也就是注解对应方法的具体实现内容. 

 单元测试

在创建出来的SpringBoot工程中, 在src的test目录下, 已经自动创建好了测试类, 可直接使用这个测试类来进行测试了.

@SpringBootTest
class MybatisApplicationTests {
	@Autowired
	private UserInfoMapper userInfoMapper;

	@Test
	void contextLoads() {
		List<UserInfo> userInfoList = userInfoMapper.queryAllUser();
		System.out.println(userInfoList);
	}

}

测试类上添加了注解@SpringBootTest, 该测试类在运行时, 就会自动加载Spring的运行环境. 我们通过@Autowired这个注解, 注入我们要测试的类, 就可以开始进行测试了. 

运行结果:

 使用idea自动生成测试类

除此之外, 也可以使用idea自动生成测试类.

在需要测试的Mapper接口中, 右键 -> Generate -> Test

MyBatis的基础操作

上面我们学习了MyBatis的查询操作, 接下来我们来学习MyBatis的增删改操作.

在学习这些操作之前, 我们先来学习MyBatis日志的打印.

打印日志

在MyBatis我们可以借助日志, 查看到sql语句的执行, 传递的参数以及执行结果.

在配置文件中进行配置即可.

mybatis:
  configuration: 
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

重新运行程序, 可以看到SQL的执行内容, 以及传递参数和执行结果.

参数传递

需求: 查找 id = 4的用户, 对应的SQL就是: select * from userinfo where id = 4;


@Select("select username, password, age, gender, phone from userinfo where id = 4")
UserInfo queryById();

但是这样的话, 只能查找id=4的数据, 所以SQL语句中的id值不能写成固定的数值, 需要转变为动态的数值.

解决方案: 在queryById方法中添加一个参数(id), 将方法中的参数, 传给SQL语句.

使用#{}的方式获取方法中的参数.

@Select("select username, password, age, gender, phone from userinfo where id = #{id}")
UserInfo queryById(Integer id);

如果mapper的接口方法形参只有一个普通类型的参数, #{...}里面的属性名可以随便写, 如:#{id}, #{value}. 建议和参数名保持一致. 

添加测试用例:

    @Test
    void queryById() {
        UserInfo userInfo = userInfoMapper.queryById(4);
        System.out.println(userInfo);
    }

运行结果:

也可以通过@Param, 设置参数的别名, 如果使用@Param设置别名, #{...}里面的属性名必须和@Param设置的一样.

@Select("select username, password, age, gender, phone from userinfo where id = #{userid}")
UserInfo queryById(@Param("userid") Integer id);

增(Insert)

SQL语句:

insert into userinfo (username, `password`, age, gender, phone) values
("zhaoliu","zhaoliu",19,1,"18700001234")

把SQL中的常量转换为动态的参数:

Mapper接口:

@Insert("insert into userinfo (username, password, age, gender, phone) values (#{username}, #{password}, #{age}, #{gender}, #{phone})")
Integer insert(UserInfo userInfo);

 直接使用UserInfo 对象来获取参数.

测试代码:

    @Test
    void insert() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhangsan");
        userInfo.setPassword("123456");
        userInfo.setAge(18);
        userInfo.setGender(1);
        userInfo.setPhone("129830218213");
        userInfoMapper.insert(userInfo);
    }

运行后, 观察数据库执行结果.

 

返回主键

Insert语句默认返回的是受影响的行数.

但有些情况下, 数据插入之后, 还需要有后续的关联操作, 需要获取到新插入数据的id.

比如订单系统

当我们下完订单以后, 需要通知物流系统, 库存系统, 结算系统等, 这时候就需要拿到订单ID. 

要想要拿到自增id, 需要在Mapper接口的方法上添加一个Options的注解.

@Options(useGeneratedKeys = true, keyProperty = "id")

useGeneratedKey:  这会令MyBatis使用JDBC的getGeneratedKeys方法来取出数据库内部生成的主键(比如: 像MySQL和SQL Server这样的关系型数据库管理系统的自动递增字段), 默认值: false.

keyProperty: 指定能够唯一识别对象的属性, MyBatis会使用getGeneratedKeys的返回值或insert语句的selectKey子元素设置它的值, 默认值: 未设置. 

测试数据:

    @Test
    void insert() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("3128937");
        userInfo.setAge(22);
        userInfo.setGender(0);
        userInfo.setPhone("323830218213");
        Integer count = userInfoMapper.insert(userInfo);
        System.out.println("添加数据条数:" + count + ", 数据ID" + userInfo.getId());
    }

注意: 设置useGeneratedKeys=true之后, 方法的返回值依然是受影响的行数, 自增id会设置在上述KeyProperty指定的属性中. 

删(Delete)

 SQL语句: 

delete from userinfo where id = 6

把SQL中的常量替换成动态的参数

Mapper接口.

    @Delete("delete from userinfo where id = #{id}")
    void delete(Integer id);

改(Update)

SQL语句:

update userinfo set username="zhaoliu" where id = 5

Mapper接口

    @Update("update userinfo set username = #{username} where id = #{id}")
    void update(UserInfo userInfo);

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

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

相关文章

JavaWeb后端——Mybatis

概述 Mybatis&#xff1a;Java程序来对数据库进行操作&#xff0c;一款优秀的持久层框架&#xff0c;用于简化JDBC的开发 SSM&#xff1a;SpringMVC、Spring、Mybatis 快速入门 步骤2&#xff1a;注意数据库连接的四要素 application.properties&#xff1a;springboot 的默…

pytorch 演示 tensor并行

pytorch 演示 tensor并行 一.原理二.实现代码 本文演示了tensor并行的原理。如何将二个mlp切分到多张GPU上分别计算自己的分块,最后做一次reduce。 1.为了避免中间数据产生集合通信,A矩阵只能列切分,只计算全部batch*seqlen的部分feature 2.因为上面的步骤每张GPU只有部分featu…

布隆过滤器详解及java实现

什么是布隆过滤器&#xff1f; 布隆过滤器&#xff08;Bloom Filter&#xff09;是一种数据结构&#xff0c;用于判断一个元素是否属于一个集合。它的特点是高效地判断一个元素是否可能存在于集合中&#xff0c;但是存在一定的误判率。 布隆过滤器的基本原理是使用一个位数组…

【STL学习】(4)vector的模拟

前言 本文将模拟实现vector的常用功能&#xff0c;目的在于更深入理解vector。 一、前置知识 在模拟之前先对vector的结构和常用接口学习&#xff0c;有一个大致了解。看源码&#xff0c;本文参考的源码是SGI版本的stl3.0。 技巧&#xff1a; 看源码不要一行一行的看&#xff…

Severt

severt是让我们自己写一些类,然后把这些类给加载Tomcat中&#xff0c;后续Tomcat收到HTTP请求(来自于浏览器)&#xff0c;就会执行到咱们上面写的代码.从而通过这些代码,完成一定的业务逻辑. 创建项目 此处创建的是一种新的项目的形式称为Maven项目,Maven是Java 中的一个的构建…

libVLC 音频立体声模式切换

在libVLC中&#xff0c;可以使用libvlc_audio_set_channel函数来设置音频的立体声模式。这个函数允许选择不同的音频通道&#xff0c;例如立体声、左声道、右声道、环绕声等。 /*** Set current audio channel.** \param p_mi media player* \param channel the audio channel…

Datacom HCIP笔记-路由策略与路由控制 之二

路由策略和策略的区别&#xff1f; 路由策略&#xff1a; 操作的对象是路由表条目&#xff0c; 实现路由过滤&#xff0c;从而实现访问控制&#xff0c;引入时过滤&#xff0c;发送和接收路由时过滤。 通过配置cost&#xff0c;来实现路径的控制。 策略路由&#xff1a; 对…

【Python】还在用print进行调试,你Out了!!!

1. 引言 Python 中最常用的函数是什么&#xff1f;像在大多数编程语言中&#xff0c;print() 函数是最常用的。我相信大多数开发者都会像我一样&#xff0c;在开发过程中多次使用它将信息进行打印。 当然&#xff0c;没有其他方法可以完全取代print()函数。不过&#xff0c;当…

QA测试开发工程师面试题满分问答9: Python中内存管理的概念、原理、使用

概念原理 Python中的内存管理是由解释器自动处理的&#xff0c;它使用引用计数和垃圾回收机制来管理内存。以下是Python内存管理的一些关键概念、设计原理和最佳实践&#xff0c;以帮助您高效使用和管理内存&#xff1a; 引用计数&#xff1a;Python使用引用计数来追踪对象的引…

谷歌浏览器如何截全屏图片?

有时候想要截取浏览器全屏&#xff0c;谷歌浏览器自带截取全屏命令&#xff0c;操作步骤如下&#xff1a; 1、按住键盘的F12或者是空白处点击鼠标右键找到检查项 2、按住ctrlshiftp&#xff0c;会出现搜索框的界面 3、搜索框中输入screen&#xff0c;选中Capture full size scr…

项目架构MVC,DDD学习

写在前面 本文一起看下项目架构DDD&#xff0c;MVC相关的内容。 1&#xff1a;MVC 不管我们做什么项目&#xff0c;自己想想其实只是做了三件事&#xff0c;如下&#xff1a; 其实&#xff0c;这三件事完全在一个类中做完也可以可以正常把项目完成的&#xff0c;就像下面这…

Redis简介、常用命令

目录 一、关系数据库​​与非关系数据库​​ 1.1. 关系型数据库 1.2 非关系型数据库 1.3.关系数据库与非关系型数据库区别 1.3.1. 数据存储方式不同 1.3.2. 扩展方式不同 1.3.3.对事务性的支持不同 1.4.非关系型数据库产生背景 二、Redis 2.1.Redis简介 2.2.Redis的…

如何使用开源情报跟踪一个人?在线访问网站以及使用方法介绍

如何使用开源情报跟踪一个人&#xff1f;在线访问网站以及使用方法介绍。 开源情报&#xff08;OSINT&#xff09;是一门关于收集和分析公开可用信息的独特技艺&#xff0c;它致力于构建个人或团体的详尽档案。 这一过程中&#xff0c;信息搜集者会利用多元化的信息源&#xff…

火山方舟大模型服务平台调用Demo测试(豆包)

豆包得后台大模型支持为字节得火山方舟&#xff0c;所以想使用豆包的API&#xff0c;直接从这里就可以。 一、首先注册账号&#xff1a; 火山引擎-云上增长新动力 注册完成之后&#xff0c;控制台-账户-API访问密钥 二、找到API测试用例&#xff1a; Skylark-chat API调用…

Linux实验3 shell命令进阶

一&#xff1a;实验目的 学习Linux下的文件系统结构&#xff0c;了解最基本的Linux下的shell命令操作&#xff0c;例如ls, cd, cat等各种指令操作。 学习vim编辑器的使用方式&#xff0c;学习如何使用ssh连接远程服务器。 二&#xff1a;实验内容 1&#xff0e;利用ls命令查找…

记一次Debug与Release版程序输出不一致的问题解决

问题叙述&#xff1a; 在x86平台下无论Debug还是Release都没问题&#xff0c;而在arm平台下Debug版本程序无问题&#xff0c;Release版本程序&#xff08;-O3编译&#xff09;发现输出值不正确&#xff0c;怀疑值被篡改&#xff0c;于是在调用前后分别使用printf打印出参数值&…

pdf操作器(图片转文字、PDF转word、PDF拆分、图片jpg、png互转)

pdf操作器&#xff08;不用联网图片转文字、PDF转word、PDF拆分、图片jpg、png互转&#xff09;介绍目前该软件实现了以下功能 pdf转wordpdf拆分图片&#xff0c;图片导出在桌面的一个文件夹里图片合并为pdf压缩、转换图片格式&#xff08;jpg和png&#xff09;OCR图片转文字&…

Leetcode刷题-哈希表详细总结(Java)

哈希表 当我们想使⽤哈希法来解决问题的时候&#xff0c;我们⼀般会选择如下三种数据结构。 数组set &#xff08;集合&#xff09;map&#xff08;映射&#xff09; 当我们遇到了要快速判断⼀个元素是否出现集合⾥的时候&#xff0c;就要考虑哈希法。如果在做⾯试题⽬的时候…

【Frida】【Android】 10_爬虫之WebSocket协议分析

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

鸿蒙HarmonyOS 与 Android 的NDK有什么不一样?

1. 序言 就像开发Android要用Android Studio一样&#xff0c;Android Studio&#xff08;简称AS&#xff09;其实是基于IDEAgradle插件android插件开发而来。 鸿蒙系统&#xff0c;你可以认为它和android有点像&#xff0c;但又是超越android的存在&#xff0c;除了手机&…