认识 MyBatis + MyBatis如何使用 (MyBatis操作数据库)

news2024/11/24 13:36:51

前言

本篇介绍了什么是MyBatis,MyBatis的前期配置,MyBatis操作数据库的两种方式:.xml文件 / 注释,使用MyBatis的一些注意,如有错误,请在评论区指正,让我们一起交流,共同进步!


文章目录

  • 前言
  • 1. 什么是MyBatis?
  • 2. 使用MyBatis - 前期准备
  • 3. MyBatis 操作数据库:
    • 方式一:定义接口 + 实现.xml文件(实现接口)- 实现操作数据库
    • 方式二:定义接口 + 注释 - 实现操作数据库
  • 4. 使用MyBatis注意事项
      • 获取自增主键
      • 使用like查询
  • 总结

本文开始

1. 什么是MyBatis?

MyBatis(ORM: 对象关系映射框架): 一个持久层框架,也是一个工具实现程序与数据库交互,从而更简单的操作数据库的框架;

为什么使用MyBatis ?
MyBatis 省略了复杂的JDBC操作,可以通过.xml文件的方式 或 注释的方式实现数据库的快速操作;

2. 使用MyBatis - 前期准备

在之前创建的spring boot项目上 + 添加依赖MyBatis + 它操作的数据库(MySQL Driver)

运行程序验证项目是否创建成功:

问题:直接运行MyBatis,会报错;

在这里插入图片描述

  • 原因:未设置要连接的具体MySQL信息;

解决方式:需要先配置数据库信息 + MyBatis信息;
在application.properties文件下配置:

  • 数据库连接配置:
//配置数据库连接信息
spring.datasource.url= jdbc:mysql://localhost:3306/数据库名称?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=xxx
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  • MyBatis配置保存路径 + 保存的命名格式;
//设置MyBatis的xml保存路径 和 命名格式
mybatis.mapper-locations=classpath:mybatis/*Mapper.xml
//1.classpath:根目录, mybatis : 保存文件夹名称 - 可以任意起名(resoures文件之下的文件都会生成到根目录中)
//2.命名格式作用:读取mybatis文件下所有以 Mapper.xml为后缀的文件;

#配置 MyBatis 执行时打印SQL
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#配置打印MyBatis执行的SQL - 设置默认日志级别
logging.level.com.example.demo=debug

3. MyBatis 操作数据库:

方式一:定义接口 + 实现.xml文件(实现接口)- 实现操作数据库

1.接口:定义接口,方法的声明 - 给Service层调用

  • 定义接口过程:
    1.在数据持久层定义一个接口类
    2.实现定义接口 - 接口类只能定义接口,不能实现;
    3.如果接口参数需要实体类,还需要在model实体层创建对应类;
    4.实体类实现的属性,与之对应操作的数据库相应表的属性值一样;
@Mapper // MyBatis中的接口使用注释Mapper - 数据持久层标识
public interface UserMapper {
    //接口只声明即可
    List<Userinfo> getUser();
}

2.XML:实现接口,对数据库进行具体操作增删改查等等;

  • xml实现接口过程:
    1.根据定义的MyBatis XML中的命名的文件夹名称mybatis
    2.在对应的文件夹(mybatis)下创建对应的xxxMapper.xml文件;
    3.配置xml文件格式,通过namespace实现对应接口路径(也就是之前声明的文件) - 参数为包名+类名;
    4.在文件中写sql标签,select, delete等等;再为标签设置属性 id: 方法的名称, resultType: 设置对应接口的返回类型;
    5.写正常的sql语句,不用加分号;
<?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.demo.dao.UserMapper">
    <select id="getUser" resultType="com.example.demo.model.Userinfo">
        select * from userinfo
    </select>
</mapper>

实现时创建的目录示例:

在这里插入图片描述

方式二:定义接口 + 注释 - 实现操作数据库

示例:注解方式实现 单表 或 多表 查询 (update,detele等等操作数据库的方式也可以)
1.定义接口: 与方法一样,在mapper / dao包地下定义接口即可;
2.写对应注释:在定义的接口上,写上要操作数据库的sql语句;

@Select("select * from articleinfo where id=#{id}")
  List<Articleinfo> getListByUid(@Param("id")Integer id);
  
@Select("select a.*,u.username from articleinfo a " +
            "left join userinfo u on a.uid=u.id")
    List<Articleinfo> getAllInfo();

4. 使用MyBatis注意事项

对于参数注入有两种:${}, #{}
① ${xxx} :及时执行,不安全,会发生sql注入;
执行过程:将 ${}位置直接替换;直接执行;
② #{xxx}:预执行;安全可以防止SQL注入;
执行过程:将#{}替换为占位符 ? 并且 ?不能为sql语句;

  • 问题1:SQL注入问题: 在登录时,正常是通过正确的用户+密码,而sql注入,可以通过非法的用户+密码正确登录;

示例:查询数据库时, 输入非法密码,使用${}直接替换而产生问题;

select * from userinfo where username='${username}' and password='${password}';

//输入密码为 ' or 1='1
//sql进行替换
...where username='user_name' and password='' or 1 ='1';
//判断就变为了,密码为假,但是1='1'为真,从而登录成功;

【注】${} 使用场景:业务需要传递sql命令时使用, 结果可以被穷举;

  • 问题2:MyBatis通过名称进行映射,当 类中属性数据库的表中字段名 不一致时,查询结果为null

解决方法:
1.将类中属性名称 与 数据库中表中的字段名保存一样;
2.使用sql语句 as 进行字段名重命名,字段名==属性名;
3.定义一个resultMap, 将属性名 与 字段名手动映射;
主键使用 < id > 标签,column是字段名,property是属性名;

在这里插入图片描述

获取自增主键

1.定义接口,与正常方式一样;
2.实现接口:需要设置两个属性
useGeneratedKeys: 是否开启自增;
keyConlumn: 数据库中自增的字段名称 ;
keyProerty: 数据库自增的id赋值给此属性;

 <insert id="add2" useGeneratedKeys="true" keyProperty="id">
        insert userinfo(username, password)
        values(#{username}, #{password})
    </insert>

使用like查询

1.定义接口:
List getLikeList(@Param(“name”)String name);
2.实现接口:使用数据库中的函数 concat 拼接参数
示例:获取的最终结果:‘%name%’

<select id="getLikeList" resultType="com.example.demo.model.User">
        select * from user where
       	name like concat('%',#{name},'%')
    </select>

总结

✨✨✨各位读友,本篇分享到内容如果对你有帮助给个👍赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI 一键去水印:教你无限量使用商业图片的技巧

场景再现 刚开始注册账号(啥账号具体不表了&#xff0c;小编不喜欢的那个)&#xff0c;想弄个闪亮&#xff0c;好看&#xff0c;有个性化的 Logo。作为一名非专美工小白人员&#xff0c;网上翻了很久作图工具&#xff0c;要么就是不好用&#xff0c;好用的大部分都收费。最后没…

如何从零开始配置前端环境以及安装必备的软件插件

文章目录 前言一、VSCode&#xff08;Visual Studio Code&#xff09;1.1 VSCode介绍与安装1.2 VSCode 常用插件安装1.3 VSCode代码格式化 二、Node.js2.1 Node的介绍与安装2. yarn的安装 三、Webpcak3.1 Webpcak的介绍与安装 四、Vue CLI4.1 Vue CLI的安装与介绍 五、初始化Vu…

设计模式-迭代器模式在Java中使用示例

场景 为开发一套销售管理系统&#xff0c;在对该系统进行分析和设计时&#xff0c;发现经常需要对系统中的商品数据、客户数据等进行遍历&#xff0c; 为了复用这些遍历代码&#xff0c;开发人员设计了一个抽象的数据集合类AbstractObjectList&#xff0c;而将存储商品和客户…

MaskedTextBox基本用法

作用&#xff1a;是一个文本输入框&#xff0c;可以指定文本的输入规则。 常用属性&#xff1a; 规定输入的格式 输入字符的占位符&#xff0c;获取输入的数据后留意处理 常用事件&#xff1a; 当输入字符不符合规则时发生 后台代码示范&#xff1a; //掩码文本控件输入不满…

快速实现一个div的水平垂直居中

效果 实现 给父盒子宽高和flex&#xff0c;子盒子margin&#xff1a;auto 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sc…

管理类联考——写作——论说文——实战篇——行文篇——通用性强,解释多种现象的经典理论——谈必要

前言 本节内容涉及“社会分工理论”“资源稀缺性”“瓶颈理论”等理论。这些理论一般用在“利大于弊式结构”中“整体有必要”的部分&#xff0c;也可用于“AB二元类”题目“谈好处”的部分。 需要注意的是&#xff0c;“有好处”一般指有它更好&#xff1b;“有必要”一般指没…

基于人工智能的中医图像分类系统设计与实现

华佗AI 《支持中医,永远传承古老文化》 本存储库包含一个针对中药的人工智能图像分类系统。该项目的目标是通过输入图像准确识别和分类各种中草药和成分。 个人授权许可证 版权所有 2023至2050特此授予任何获得华佗AI应用程序(以下简称“软件”)副本的人免费许可,可根据以…

285 · 高楼大厦

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; 题解&#xff1a; 1.从左往右维护一个单调递减&#xff0c;栈的长度就是&#xff0c;可以看到最多的高楼 2.从右往后也是维护一个单调递减的栈 class Solution { public:/*** param arr:…

Python中的PDF文本提取:使用fitz和wxPython库(带进度条)

引言&#xff1a; 处理大量PDF文档的文本提取任务可能是一项繁琐的工作。本文将介绍一个使用Python编写的工具&#xff0c;可通过简单的操作一键提取大量PDF文档中的文本内容&#xff0c;极大地提高工作效率。 import wx import pathlib import fitzclass PDFExtractor(wx.Fr…

谷歌、Edge等浏览器截图长图的方法

目录 序 谷歌浏览器 步骤1&#xff1a;打开开发者工具&#xff08;右上角->更多开发工具->开发工具&#xff09;也可以直接按F12 步骤2&#xff1a;按组合键CtrlShiftP&#xff0c;打开浏览器的console功能菜单的指令搜索栏 步骤3&#xff1a;搜索框输入full,找到Cap…

LeetCode--HOT100题(19)

目录 题目描述&#xff1a;54. 螺旋矩阵&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;54. 螺旋矩阵&#xff08;中等&#xff09; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 Le…

socker套接字

1.打印错误信息 2.socketaddr_in结构体 结构体&#xff1a; &#xff08;部分库代码&#xff09; (宏中的##) 3.manual TCP: SOCK_STREAM &#xff1a; 提供有序地&#xff0c;可靠的&#xff0c;全双工的&#xff0c;基于连接的流式服务 UDP: 面向数据报

C语言单链表OJ题(较易)

一、移除链表元素 leetcode链接 题目描述&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 思路&#xff1a; 正常遍历&#xff0c;找到value的值与题目中相同的结点去fr…

Statefulset 实战 3

上一部分我们说到如何使用 Statefulset 部署有状态的应用&#xff0c;Statefulset 可以做到部署的 每一个 pod 能够独立的拥有一个持久卷声明和持久卷 之前我们 用 Statefulset 和 ReplicaSet 对比&#xff0c;自然他们是有相似之处和不同之处&#xff0c;不同之处前面的文章已…

【云原生】K8S二进制搭建三:高可用配置

目录 一、部署CoreDNS二、配置高可用三、配置负载均衡四、部署 Dashboard 一、部署CoreDNS 在所有 node 节点上操作 #上传 coredns.tar 到 /opt 目录中 cd /opt docker load -i coredns.tar在 master01 节点上操作 #上传 coredns.yaml 文件到 /opt/k8s 目录中&#xff0c;部…

vue2-vue实例挂载的过程

1、思考 new Vue()这个过程中究竟做了什么&#xff1f;过程中是如何完成数据的绑定&#xff0c;又是如何将数据渲染到视图的等等。 2、分析 首先找到vue的构造函数。 源码位置&#xff1a;/src/core/instance/index.js options是用户传递过来的配置项&#xff0c;如data、meth…

通讯协议032——全网独有的OPC HDA知识一之聚合(一)

本文简单介绍OPC HDA规范的基本概念&#xff0c;更多通信资源请登录网信智汇(wangxinzhihui)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化&#xff0c;以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&#xff…

Maven出现报错 ; Unable to import maven project: See logs for details错误的多种解决方法

问题现象; IDEA版本&#xff1a; Maven 版本 &#xff1a; 3.3.9 0.检查 maven 的设置 &#xff1a;F:\softeware\maven\apache-maven-3.9.3\conf 检查setting.xml 配置 本地仓库<localRepository>F:\softeware\maven\local\repository</localRepository>镜像…

观察者模式(C++)

定义 定义对象间的一种一对多(变化)的依赖关系&#xff0c;以便当一个对象(Subject)的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并自动更新。 ——《设计模式》GoF 使用场景 一个对象&#xff08;目标对象&#xff09;的状态发生改变&#xff0c;所有的依赖对…

信息论之从熵、惊奇到交叉熵、KL散度和互信息

一、熵&#xff08;PRML&#xff09; 考虑将A地观测的一个随机变量x&#xff0c;编码后传输到B地。 这个随机变量有8种可能的状态&#xff0c;每个状态都是等可能的。为了把x的值传给接收者&#xff0c;需要传输⼀个3⽐特的消息。注意&#xff0c;这个变量的熵由下式给出: ⾮…