MyBatis入门(上)---初识

        在应⽤分层学习时, 我们了解到web应⽤程序⼀般分为三层,即:Controller、Service、Dao . 之前的案例中,请求流程如下: 浏览器发起请求, 先请求Controller, Controller接收到请求之后, 调⽤ Service进⾏业务逻辑处理, Service再调⽤Dao, 但是Dao层的数据是Mock的, 真实的数据应该从数据库中读取. 我们学习MySQL数据库时,已经学习了JDBC来操作数据库, 但是JDBC操作太复杂了,所以我们要学习MyBatis的真正原因,它可以帮助我们更方便、更快速的操作数据库。

1. 什么是MyBatis

1、MyBatis是一块优秀的持久层框架,用于简化JDBC的开发

2、MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由Apache迁移到了google code,并且改名为MyBaits。2013年11月迁移到Github。

3、官网:MyBatis中文网

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

        MyBatis 是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库⼯具 ;

2. MyBatis入门

        MyBatis操作数据库的步骤:

1、准备工作(创建Spring Boot工程、数据库表准备、实体类)。

2、引入Mybatis的相关依赖,配置Mybatis(数据库连接信息)。

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

4、测试。

2.1 准备工作

2.1.1 创建工程

        创建Spring Boot 工程,并且导入MyBatis的起步依赖、MySQL驱动包。

         MyBatis是一个持久层框架,具体的数据存储和数据操作还是在MySQL中操作的,所以需要添加MySQL驱动。项目工程创建完成后,会自动在pom.xml文件中导入MyBatis依赖和MySQL驱动依赖,如图:

         它们的版本会随着SpringBoot版本发生变化,SpringBoot 3.X 对应 MyBatis版本为 3.X,对应关系参考:mybatis-spring-boot-autoconfigure – Introduction ,如图:

2.1.2 数据准备

        1、创建用户表,sql代码如下:

drop database if exists mybaties_test_0822;create database mybaties_test_0822 default character set utf8mb4;use mybaties_test_0822;
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 mybaties_test_0822.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'shangjialu', '111111', 18, 1, '15809211621' );
INSERT INTO mybaties_test_0822.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'shenmengyao', '222222', 18, 2, '18612340002' );
INSERT INTO mybaties_test_0822.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'yuanyiqi', '333333', 18, 2, '18612340003' );
INSERT INTO mybaties_test_0822.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zuojinyuan', '555555', 18, 2, '18612340004' );

        2、  创建对应的实体类,代码如下:

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

 2.2. 配置数据库连接字符串

        MyBatis中要连接数据库,需要数据库相关的参数配置:MySQL驱动类、登录名、密码、数据库连接字符串。

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

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybaties_test_0822?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: ******driver-class-name: com.mysql.cj.jdbc.Driver

          application.properties文件,配置内容如下:

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybaties_test_0822?
characterEncoding=utf8&useSSL=false
#连接数据库的⽤⼾名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=******

2.3 写持久层代码

        在项目中,创建持久层接口UserInfoMapper,如图:

代码如下:

package com.example.zxslzw_mybaties.mapper;import com.example.zxslzw_mybaties.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface UserInfoMapper {@Select("select * from userinfoS")List<UserInfo> getUserInfoAll();
}

        Mybatis的持久层接⼝规范⼀般都叫 XxxMapper :

        @Mapper注解:表⽰是MyBatis中的Mapper接⼝ :程序运⾏时, 框架会⾃动⽣成接⼝的实现类对象(代理对象),并给交Spring的IOC容器管理 ;

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

2.4 单元测试

        在Spring Boot工程下中,src下的test目录中,已经自动帮我们创建好了测试类,我们可以直接使用这个测试类来进行测试,代码如下:

package com.example.zxslzw_mybaties.mapper;import com.example.zxslzw_mybaties.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid getUserInfoAll() {List<UserInfo> userInfos = userInfoMapper.getUserInfoAll();System.out.println(userInfos);}
}

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

        运行结果如下:

        返回对应的结果,可以看到,只有SQL语句中查询的列中,只有和对应的列名一样,才会有显示(如果和数据库列名一样,就会有显示对应的信息;如果不一样,就不会显示对应信息的正确消息)。如图: 

2.4.1 使用IDEA自动成成测试类

        在你要测试的类中,鼠标右键 -> Generate -> Test -> 勾上对应要测试的方法,这里使用UserInfoMapper类做演示,如图:

          点击OK,会在test目录下生成对应的测试类,如图:

         测试类代码如下:

package com.example.zxslzw_mybaties.mapper;import com.example.zxslzw_mybaties.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface UserInfoMapper {@Select("select * from userinfo")List<UserInfo> getUserInfoAll();
}

 2.4.2 使用程序运行代码

        编写controller类,service类, controller类代码如下:

package com.example.zxslzw_mybaties.controller;import com.example.zxslzw_mybaties.model.UserInfo;
import com.example.zxslzw_mybaties.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RequestMapping("/user")
@RestController
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/getUserAll")public List<UserInfo> getUserAll() {return userService.getUserAll();}
}

  service类代码如下:

package com.example.zxslzw_mybaties.service;import com.example.zxslzw_mybaties.mapper.UserInfoMapper;
import com.example.zxslzw_mybaties.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Autowiredprivate UserInfoMapper userInfoMapper;public List<UserInfo> getUserAll() {return userInfoMapper.getUserInfoAll();}
}

浏览器访问127.0.0.1:8080/user/getUserAll:

ps:本文的内容到这里就结束了,如果对你有所帮助的话,就请一键三连哦!!!

--------------------------------

上嘉路 

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

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

相关文章

消化学科的领军人物陈烨教授在会议上作了《幽门螺杆菌的规范检测与质控》的专题报告

由广东省药学会主办的“第十九届消化疾病诊疗会暨胃肠疾病药物临床研究交流会”于2024年8月8日-9日在广东省深圳市召开。陈烨教授&#xff0c;作为消化学科的领军人物、中华医学会消化病学分会的常务委员&#xff0c;以及全国幽门螺杆菌学组的组长&#xff0c;在会议上作了《幽…

【仿真与实物设计】基于51单片机设计的打地鼠游戏机——程序源码原理图proteus仿真图PCB设计文档演示视频元件清单等(文末工程资料下载)

基于51单片机设计的打地鼠游戏机 演示视频&#xff1a; 基于51单片机设计的打地鼠游戏机 功能描述&#xff1a;使用 51单片机为核心制作一个打地鼠游戏机。按下启动开关&#xff0c;8盏LED流水点亮并闪烁2次&#xff0c;随即开始播放游戏音乐&#xff0c;直到开始选择模式。选…

CTF密码学小结

感觉没啥好总结的啊 基础的永远是RSA、流密码、哈希、对称密码、古典密码那一套&#xff08;密码学上过课都会&#xff09;&#xff0c;其他的就是数论的一些技巧 似乎格密码也很流行&#xff0c;以及一些奇奇怪怪的性质利用也很多 1、random设置种子后随机的性质&#xff1a…

ORM底层的原理

2.3.面试题3&#xff1a;请介绍什么是ORM思想&#xff1a; a.什么是ORM&#xff1a; 1.所谓的ORM是Dao层的一种思想&#xff0c;意思就是对象关系映射&#xff08;英语&#xff1a;Object Relational Mapping&#xff0c;简称ORM&#xff0c;或O/RM&#xff0c;或O/R mapping…

Excel技巧(一)

快捷键技巧 原文链接 选取某一行的数据直到最后一行&#xff1a;【CTRL SHIFT ↓ 】或者选取一行后按住SHIFT键&#xff0c;双击下边线就可以快速选取区域。 如果表格中有多行空行&#xff0c;可以先按CTRL SHIFT END&#xff0c;再按CTRL SHIFT 上下键调整&#xff0c;…

读懂 GraphRAG:提升LLM企业落地能力,智能问答革命

在企业中单纯的使用LLM并不会产生太好的效果&#xff0c;因为它们不会对有关组织活动的特定领域专有知识进行编码&#xff0c;而这些知识实际上会给信息对话界面带来价值萃取。很多企业尝试通过RAG来优化这个过程&#xff0c;并且越来越多的人在RAG的方向上不断的研究&#xff…

【蓝桥杯集训100题】scratch游泳时长 蓝桥杯scratch比赛专项预测编程题 集训模拟练习题第27题

目录 scratch游泳时长 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 scratc…

《黑神话.悟空》与人工智能AI重塑经典与探索未来的交织

"近期我偶然邂逅了一个极为出色的人工智能学习平台&#xff0c;它不仅内容深入浅出&#xff0c;讲解方式还风趣幽默&#xff0c;让人学习起来既轻松又高效。如此宝藏资源&#xff0c;我迫不及待想要与各位共享。即刻点击让我们一起进入这个精彩纷呈的学习网站吧&#xff0…

[java][代码]使用java在mongodb上传下载文件

建立java项目新建lib包&#xff0c;导入jar包 3.链接mongdo数据库代码 /** * 1.获取连接 * 2.上传文件 * 3.下载文件 * 4.删除文件 * */ public static GridFS GetMongoGridFS(){ List<ServerAddress> adds new ArrayList<>(); ServerAddress serverAddress new…

Python | Leetcode Python题解之第352题将数据流变为多个不想交区间

题目&#xff1a; 题解&#xff1a; from sortedcontainers import SortedDictclass SummaryRanges:def __init__(self):self.intervals SortedDict()def addNum(self, val: int) -> None:intervals_ self.intervalskeys_ self.intervals.keys()values_ self.intervals…

C# SolidWorks 二次开发-103.模拟库拖拽

最近躺平状态&#xff0c;所有没有更新。 为了搜索量再高一点&#xff0c;我决定让排名上升一个名次&#xff0c;今天来写一篇关于如何假装自己有个库。 如上图&#xff0c;进行一个拖拽示例&#xff0c;从自己的窗体中将文件带入solidworks中打开 或者 装配动作。与手动从文…

多商户平台后台上传不了文件

错误&#xff0c;点击上传没反应&#xff0c;也无错误提示 解决方法&#xff1a; 检查商城域名配置&#xff0c;http 和 https&#xff0c;与访问的http或https是否一致&#xff1b;

iOS App上架审核被拒——2.3.3 - Performance - Accurate Metadata

iOS上架审核被拒——Guideline 2.3.3 - Performance - Accurate Metadata 噢&#xff0c;又被拒了… 文章目录 iOS上架审核被拒——Guideline 2.3.3 - Performance - Accurate Metadata被拒原因解决 被拒原因 大概翻译了下&#xff1a;预览图问题&#xff0c;只因某张预览图加了…

UDP服务端、TCP的c/s模式

一、UDP服务端 socket bind //绑定 recvfrom ssize_t recvfrom(int sockfd, socket的fd void *buf, 保存数据的一块空间的地址 …

C语言 | Leetcode C语言题解之第350题两个数组的交集II

题目&#xff1a; 题解&#xff1a; int cmp(const void* _a, const void* _b) {int *a _a, *b (int*)_b;return *a *b ? 0 : *a > *b ? 1 : -1; }int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size,int* returnSize) {qsort(nums1, nums1Size, s…

8.16-ansible的应用

ansible ansible是基于模块工作的&#xff0c;本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块&#xff0c;ansible只是提供一种框架。 格式 ansible 主机ip|域名|组名|别名 -m ping|copy|... 参数 1.ping模块 m0 # 查看有没有安装epel ​ [rootm0 ~]#…

[000-01-022].第06节:RabbitMQ中的交换机介绍

1.什么是Exchanges(交换机&#xff09;: 1.RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上&#xff0c;通常生产者甚至都不知道这些消息传递传递到了哪些队列中2.生产者只能将消息发送到交换机(exchange)&#xff0c;交换机工作的内容非常…

【Qt】输入类控件QTextEdit

目录 输入类控件QTextEdit 例子&#xff1a;获取多行输入框的内容 例子&#xff1a;验证输入框的各种信号 输入类控件QTextEdit QTextEdit表示多行输入框&#xff0c;也是一个富文本&markdown编辑器。 并且能在内容超出编辑框范围时自动提供滚动条 在Qt中&#xff0c;有俩…

arcgis打开不同tif格式编码的栅格数据

1、如下图&#xff0c;将文件包包解压打开&#xff0c;看到【2020年GDP数据】。 2、点击进入【2020年GDP数据】文件夹如下图所示。接着去打开arcgis软件。 3、按照步骤来&#xff0c;在arcgis【目录】里面添加【文件夹】然后选中你刚刚解压的【GDP文件夹数据】&#xff0c;最…

QT-贪吃蛇小游戏

QT-贪吃蛇小游戏 一、演示效果二、核心代码三、下载链接 一、演示效果 二、核心代码 #include "Food.h" #include <QTime> #include <time.h> #include "Snake.h"Food::Food(int foodSize):foodSize(foodSize) {coordinate.x -1;coordinate.…