[JAVAee]MyBatis

news2024/11/23 17:10:52

目录

MyBatis简介

MyBatis的准备工作 

框架的添加

连接数据库字符串的配置

MyBatis中XML路径的配置

​编辑 MyBatis的使用

各层的实现 

进行数据库操作

增加操作

拓展 

修改操作

删除操作

查询操作 

结果映射

单表查询

多表查询 

like模糊查询

动态SQL

 

 /


MyBatis简介

MyBatis是基于JDBC的一个工具框架,能够更好帮助程序与数据库进行交互,也能更方便的进行数据库中数据的存储与读取.

MyBatis是一个ORM(Object Relational Mapping)框架,ORM即是对象关系映射.在编程语言中,将关系型数据库中的数据与对象建立映射关系,更方便的完成数据与对象间的转换.

一般的ORM映射关系:

 在加入了Mybatis的项目中,一般会为一张表创建一个类并进行映射,就使得像平常操作对象一般操作数据库中的数据.

MyBatis的准备工作 

框架的添加

在项目中添加Mysql数据库与MyBatis相关的框架.

如果是老的项目可以使用EditStarters插件进行添加 

连接数据库字符串的配置

在项目的配置文件中对数据库的连接进行配置,此处使用的是yml类型的配置文件.主要是作用是将项目与数据库能够进行连接.

记得对URL中的目标数据库进行修改.

spring:
    datasource:
      url: jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=false #连接数据库的地址
      username: root #数据库的用户名
      password: #数据库的密码
      driver-class-name: com.mysql.cj.jdbc.Driver

 将上述代码放置到yml配置文件中

注意事项 :

 检查mysql-connector-java的版本号,如果是 5.x 之前的使⽤的“com.mysql.jdbc.Driver”,如果是⼤于 5.x使⽤的是“com.mysql.cj.jdbc.Driver”

MyBatis中XML路径的配置

在resources的目录下创建一个目录(此处我命名为mybatis).

并在项目的配置文件中将刚刚创建的目录添加到mybatis的xml路径

最终配置文件大致为:

 MyBatis的使用

 一般的业务的后端开发思路为:

 我们只要跟着上面的开发思路来写代码就好了.

注意:

下面所创建的所有类都要跟启动类放到同一个文件夹之中.

各层的实现 

创建实体类

映射到一个数据库中的表.

@Data
public class User {
    private String name;
    private int age;
    private int id;
    private String sex;
}

创建Serveric类

@Service
public class UserService {
    @Autowired
    UserMapper userMapper;

    public User getUserByName(String name){
        return userMapper.getUserByName(name);
    }
}

创建Controller类

@Controller
public class UserController{
    @Autowired
    UserService userService;

    public User getUserByName(String name){
        return userService.getUserByName(name);
    }
}

创建Mapper

Mapper的组成为接口+XML

@Mapper
public interface UserMapper {
    User getUserByName(@Param("name") String name);
    //使用Param注解,将接口方法中的参数设置成为xml中传输的参数(不写也可以,写了更严谨可以尽量避免出现bug)
}

在之前的配置文件中配置mybatis的xml的目录中创建一个对应的xml 

(将下面的代码拷贝,更改对应的mapper标签中的namespace.在mapper标签中写上对应的sql语句)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
s.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.UserMapper">
    <!--    sql语句的实现-->
</mapper>

mapper标签中需要指定namespace属性,表示命名空间,为mapper接口的全限定名(包名+类名)去指定一个mapper. 

进行数据库操作

对应表的创建语句:

create table Users(name varchar(15),
                   age int,
                   id int primary key auto_increment,
                   sex varchar(6));

在MyBatis中的SQL语句都在XML文件中搭配对应的标签来实现.

可以在SpringBoot项目的配置文件中设置Mapper类的日志等级为debug,这样就可以在控制台中查看数据库操作的预处理语句,参数和受影响的行数了.

(此处为yml类型配置文件的语句) 

logging:
  level:
    com.example.demo.Mapper: debug  //此处是类的路径 + 日志的等级

增加操作

增加操作使用<insert>标签实现

controller类

@ResponseBody//记得添上@ResponseBody,表明返回的是一个数据而不是页面
    @PostMapping("/add")//POST由客户端上传数据至服务器
    public Integer add(@RequestBody User user){//@RequestBody标签将方法中的user参数获取请求body中的json格式
        return userService.add(user);
    }

Service类

public Integer add(User user){
        return userMapper.add(user);
    }

Mapper

最好要使用Integer做返回值噢

    //增加操作,返回受影响的行数
    //返回类型为Integer而不是int,是因为int的默认值为0,Integer的默认值为null
    //使用int就不知道语句是否对数据库造成了影响,
    //Integer可以区分未赋值与受影响行数为0的区别
    Integer add(User user);

xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
s.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.UserMapper">
    <!--sql语句的实现-->
    <insert id="add">
        insert into Users(name,age,sex) values(#{name},#{age},#{sex});
    <!--#{}中为对象的属性-->
    </insert>
</mapper>

可以看到返回值为受影响的行数. 

拓展 

返回受影响的行数据的主键

当我们在某些情况下想要获取对应的主键,可以在insert标签上进行设置.

useGeneratedKeys : 使用主键,默认值为false,

keyProperty : 主键的属性名为(实体类中的属性)

<insert id="add" useGeneratedKeys="true" keyProperty="id">
        insert into Users(name,age,sex) values(#{name},#{age},#{sex});
    <!--#{}中为对象的属性-->
</insert>

 然后我们就可以直接在方法中使用对象的主键属性了,先前都是默认自增值没有对其进行赋值,

@ResponseBody//记得添上@ResponseBody,表明返回的是一个数据而不是页面
    @PostMapping("/add")//POST由客户端上传数据至服务器
    public Integer add(@RequestBody User user){//@RequestBody标签将方法中的user参数获取请求body中的json格式
        Integer ret = userService.add(user);
        System.out.println("UserID为:" + user.getId());
        return ret;
    }

修改操作

使用<update>标签 

由于Controller类与Service类都大差不大就不展示啦. 

 Mapper

Integer update(User user);
<update id="update">
        update Users set age = #{age} where name = #{name};
</update>

删除操作

删除操作使用<delete>标签

Mapper

Integer delete(User user);
<delete id="delete">
        delete from Users where id = #{id};
</delete>

查询操作

结果映射

在上述的增加,删除以及修改操作中,一般的默认的返回值为受影响的行数.但其实可以不使用映射来接收这个参数的.

但对于查询操作来说,不得不接收返回的参数,不然会进行报错.

而在MyBatis中,实现结果映射的标签一共有两种<resultType>返回类型与<resultMap>返回字典映射

<resultType>返回类型

此标签能够适用于绝大多数的场景,其中resultType表明要返回的类型.

可以是一个类,也可以的基本类型或引用类型.

其中的resultType值可以为类名,或"string"或"java.lang.String"或"int"或"java.lang.Integer"...

<select id="getNameById" resultType="java.lang.String">
        select name from Users where id = #{id};
</select>

因为<resultMap>标签的使用比较麻烦也以及不常用了,就不再此处介绍了

单表查询

将Controller类的标签更改为get方法,并使用表单传输信息. 

User getNameById(@Param("id") Integer id);
<select id="getNameById" resultType="com.example.demo.model.User">
        select name from Users where id = #{id};
</select>
多表查询 

使用多表查询获取一对多,使用List来接收多个对象.但注意xml中的返回类型是单个对象的类型 

Mapper

List<BookVO> get(String name);

XML 

<select id="get" resultType="com.example.demo.model.VO.BookVO">
        select title,author_id,name from books left join Users on books.author_id = Users.id where Users.name = #{name};
</select>

like模糊查询

因为使用#{}会进行预处理编译,会把数据自动的加上单引号  zhangsan -> 'zhangsan'

如果直接使用模糊查询, like  '%#{name}%' 就会变成  ->  like '%'name'%' 显然是错误的,但如果使用${}字符串替换又会有sql注入的风险,

所以我们可以使用concat方法对%与参数进行连接.

<select id="getByName" resultType="com.example.demo.model.User">
        select * from Users where name like concat('%',#{name},'%');
</select>
动态SQL
<if>

我们之前可能在遇到过,填写个人信息表单的时候会出现非必填项.

此处就可以使用<if>标签来实现非必填项的方式

当我们填写name,age却不想写填写sex的时候,就可以使用<if>标签来拼接SQL语句

Mapper: 

Integer add2(User user);

XML: 

<insert id="add2">
        insert into Users(name,age<if test="sex != null">,sex</if>) values(#{name},#{age}<if test="sex != null">,#{sex}</if>);
    </insert>

其中<if>标签中的test属性填写的是传输参数的判断语句,sex是user对象的属性并非数据库中的字段.

如果传输的user对象中sex属性为空,则不填写<if>标签中的字符.

 对应的,因为<if>标签的作用,预处理后的语句也没有出现sex字段

 <trim>

上面的例子为单个非必填选项,那如果我每一个都是非必填呢?

因为SQL语句中字段间的分隔需要逗号来实现,所以单单依靠于<if>标签来实现是不可行的,这时候就出现了另一种标签:<trim>

<trim>标签与<if>标签搭配使用适用于多个字段都是非必填的场景.

<trim>标签中有如下属性:

  • prefix:表示整个语句块,以prefix的值作为前缀
  • suffix:表示整个语句块,以suffix的值作为后缀
  • prefixOverrides:表示整个语句块要去除掉的前缀
  • suffixOverrides:表示整个语句块要去除掉的后缀  
<insert id="add2">
        insert into Users
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null">name,</if>
            <if test="age != null">age,</if>
            <if test="sex != null">sex,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="name != null">#{name},</if>
            <if test="age != null">#{age},</if>
            <if test="sex != null">#{sex},</if>
        </trim>
    </insert>

在使用<trim>标签之后可传输的数据就会变得很灵活了 

 <where>/<set>

其中还有这两个标签,其实这两个标签都是<trim>的变形

<set>也是同样的,只是<set>等价于<trim prefix="set" suffixOverrides=",">

<foreach>

对集合进⾏遍历时可以使⽤该标签。<foreach>标签有如下属性:

  • collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
  • item:遍历时的每⼀个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串
<delete id="deleteByIds">
    delete from article
    where id in
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item}
        </foreach>
</delete>

就像java里的foreach遍历一样.

传输数组进行调试

预处理后的样子:

 

TIPS:

在后端类的属性与数据库中字段名不相同时,可以在SQL语句中使用as为字段起别名

<select id="getId" resultType="com.example.demo.model.Book">
        select author_id as authorID,title,content from books where title = #{title};
    </select>


 

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

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

相关文章

【超详细】Wireshark教程----Wireshark 分析ICMP报文数据试验

一&#xff0c;试验环境搭建 1-1 试验环境示例图 1-2 环境准备 两台kali主机&#xff08;虚拟机&#xff09; kali2022 192.168.220.129/24 kali2022 192.168.220.3/27 1-2-1 网关配置&#xff1a; 编辑-------- 虚拟网路编辑器 更改设置进来以后 &#xff0c;先选择N…

[Linux]Git

文章摘于GitHub博主geeeeeeeeek 文章目录 1.1 Git 简易指南创建新仓库工作流添加与提交推送改动 1.2 创建代码仓库git init用法讨论裸仓库 例子 git clone用法讨论仓库间协作 例子用法讨论栗子 1.3 保存你的更改git add用法讨论缓存区 栗子 git commit用法讨论记录快照&#xf…

数据统计-EXCEL中常用函数及操作

最近经常需要做一些数据统计工作&#xff0c;整理下EXCEL常用的函数及操作&#xff0c;总结及分享出来&#xff0c;后续会不断更新。 一、VLOOKUP函数 同表查询&#xff1a;VLOOKUP(A2,$A:$G,1,0) 跨表查询&#xff1a; VLOOKUP(A2,Sheet2!$A:$G,1,0) 跨工作薄&#xff1a; 跨…

GD32F10x的输出模式

1. 单片机型号的识别。 2. GPIO的输出模式。 1. 开漏模式 2.推挽模式 3.复用开漏模式 4.复用推挽模式。 开漏模式&#xff1a;&#xff08;写入位设置&#xff0c;输出数据寄存器来控制MOS&#xff09; 只有N-MOS管导通。PMOS不导通。 当N-MOS的栅极为0&#xff0c;N-MOS管…

Windows 下安装和配置 Redis (详细图文)

目录 下载 Redis安装 Redis配置 Redis修改密码(可选)配置环境变量注册系统服务 Redis 桌面管理工具附&#xff1a;开源项目微服务商城项目前后端分离项目 下载 Redis 访问 Redis 下载地址&#xff1a;https://github.com/tporadowski/redis/releases 下载 Redis 时&#xff0c…

unity 鼠标标记 左键长按生成标记右键长按清除标记,对象转化为子物体

linerender的标记参考 unity linerenderer在Game窗口中任意画线_游戏内编辑linerender-CSDN博客 让生成的标记转化为ARMarks游戏对象的子物体 LineMark.cs using System.Collections; using System.Collections.Generic; using UnityEngine;public class LineMark : MonoBeh…

二十二,加上各种贴图

使用pbr的各种贴图&#xff0c;albedo,金属度&#xff0c;ao,法线&#xff0c;粗糙度&#xff0c;可以更好的控制各个片元 1&#xff0c;先加上纹理坐标 texCoords->push_back(osg::Vec2(xSegment, ySegment)); geom->setVertexAttribArray(3, texCoords, osg::Array::BI…

【每日一题】花期内花的数目+【差分数组】+【二分枚举】

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;差分数组方法二&#xff1a;二分查找 写在最后 Tag 【差分数组】【二分查找】【数组】【2023-09-28】 题目来源 2251. 花期内花的数目 题目解读 每朵花都有自己的花期&#xff0c;有些花的花期会有重叠&#xff0c;也…

Turf处理等压线

Turf是一个用于空间分析的JavaScript库。它包括传统的空间操作、用于创建GeoJSON数据的辅助函数以及数据分类和统计工具。Turf可以作为客户端插件添加到您的网站&#xff0c;也可以使用Node.js在服务器端运行Turf。 Turf是一个模块化的js类库&#xff0c;所有的模块都是在packa…

【GDB】用 python 扩展 gdb

用 python 扩展 GDB .gdbinit 文件中实现自定义命令 mv 代码如下 define mvif $argc 2delete $arg0# 注意新创建的断点编号和被删除断点的编号不同break $arg1elseprint "输入参数数目不对&#xff0c;help mv 以获得用法"end end# (gdb) help mv 会输出以下帮助文…

搭建自己的搜索引擎之四

一、前言 搭建自己的搜索引擎之三 介绍了通过HTTP RESTful 对ES进行增删改查&#xff0c;这一般手工运维ES时使用&#xff0c;程序代码中最好还是使用Java API去操作ES会更容易维护&#xff0c;但ES API竟然贼多&#xff0c;本篇介绍一下 四种 API及其简单使用。 注&#xff…

深入理解二叉树:结构、遍历和实现

文章目录 &#x1f34b;引言&#x1f34b;什么是二叉树&#xff1f;&#x1f34b;二叉树的基本性质&#x1f34b;二叉树的遍历&#x1f34b;二叉树的实现&#x1f34b;结语 &#x1f34b;引言 在计算机科学中&#xff0c;二叉树是一种重要的数据结构&#xff0c;广泛应用于各种…

【密评】商用密码应用安全性评估从业人员考核题库(二)

商用密码应用安全性评估从业人员考核题库&#xff08;二&#xff09; 国密局给的参考题库5000道只是基础题&#xff0c;后续更新完5000还会继续更其他高质量题库&#xff0c;持续学习&#xff0c;共同进步。 251 多项选择题 根据《密码法》&#xff0c;核心密码、普通密码安全…

Linux常用命令(一)

目录 一、列出目录内容&#xff08;ls&#xff09; 二、切换目录&#xff08;cd&#xff09; 三、显示当前目录路径&#xff08;pwd&#xff09; 四、以树状结构显示目录内容&#xff08;tree&#xff09; 五、创建新目录&#xff08;mkdir&#xff09; 六、复制文件或目…

windows11 如何关闭 vbs

在Windows 11中&#xff0c;VBS是一种虚拟化安全功能&#xff0c;它可以防止恶意软件通过沙箱环境运行。 如果您想关闭VBS功能&#xff0c;方法如下&#xff1a; 点击底部开始菜单 在上方搜索 cmd &#xff0c;并点击以管理员身份运行 打开控制台后&#xff0c;在控制台输入…

文档图像处理:大模型的突破与新探索

前言 随着数字化时代的到来&#xff0c;文档图像处理技术在各行各业扮演着越来越重要的角色。在2023第十二届中国智能产业高峰论坛&#xff08;CIIS 2023&#xff09;的专题论坛上&#xff0c;合合信息智能技术平台事业部副总经理、高级工程师丁凯博士分享了当前文档图像处理面…

wallis匀色算法、直方图匹配、颜色转移方法比较

算法原理 这三种方法应该是比较基础的匀色处理算法 三个算法的原理比较简单&#xff0c;具体原理大家可以自己百度 &#xff08;1&#xff09;wallis匀色原理主要在于利用Wallis滤波器使原始图像的均值和标准差与参考影像相当&#xff0c;从而使原始影像和参考影像具有相近的色…

Oracle的递归公共表表达式

查询节点id为2的所有子节点的数据&#xff0c;包括向下级联 WITH T1 (id, parent_id, data) AS (SELECT id, parent_id, dataFROM nodesWHERE id 2UNION ALLSELECT t.id, t.parent_id, t.dataFROM nodes tJOIN T1 n ON t.parent_id n.id ) SELECT * FROM T1; --建表语句 C…

今天出门竟然忘了带套

今天是没有抢到票的打工人节前的最后一天&#xff0c;7点醒来&#xff0c;磨磨蹭蹭&#xff0c;解决完个人问题&#xff0c;7.35才出门&#xff0c;正常来说最晚7.30出门&#xff0c;骑上哈啰、挤上地铁才能保证打上卡。 说出来不怕各位同行笑话&#xff0c;谁能想到一个高速发…

打卡新“姿势”,多种打卡方式并行

打卡工具 路径 拓展 >> 工具 功能简介 在打卡工具 “班次管理”中&#xff0c;支持多种打卡方式。可同时选择「地点打卡」和「智能安全帽打卡」两种方式进行打卡。 注&#xff1a; 「地点打卡」可设置考勤地点&#xff1b; 「智能安全帽打卡」可设置电子围栏范围。…