[JAVAee]MyBatis

目录

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 {@AutowiredUserMapper userMapper;public User getUserByName(String name){return userMapper.getUserByName(name);}
}

创建Controller类

@Controller
public class UserController{@AutowiredUserService 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 articlewhere 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.rhkb.cn/news/146500.html

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

相关文章

传输层协议—UDP协议

传输层协议—UDP协议 文章目录 传输层协议—UDP协议传输层再谈端口号端口号范围划分pidofnetstat UDP协议端格式UDP报文UDP特点UDP缓冲区基于UDP的应用层协议 传输层 在学习HTTP/HTTPS等应用层协议时&#xff0c;为了方便理解&#xff0c;可以简单认为HTTP将请求和响应直接发送…

【算法优选】双指针专题——贰

文章目录 &#x1f60e;前言&#x1f332;[快乐数](https://leetcode.cn/problems/happy-number/)&#x1f6a9;题目描述&#x1f6a9;题⽬分析&#xff1a;&#x1f6a9;算法思路&#xff1a;&#x1f6a9;代码实现&#xff1a; &#x1f38b;[盛水最多的容器](https://leetco…

CocosCreator3.8研究笔记(二十二)CocosCreator 动画系统-动画剪辑和动画组件介绍

国庆假期&#xff0c;闲着没事&#xff0c;在家研究技术~ 大家都知道在Cocos Creator3.x 的版本的动画编辑器中&#xff0c;可以实现不用写一行代码就能实现各种动态效果。 Cocos Creator动画编辑器中主要实现关键帧动画&#xff0c;不仅支持位移、旋转、缩放、帧动画&#xff…

【算法】算法基础课模板大全

一、基础算法 快速排序算法模板 void quick_sort(int q[], int l, int r) {//递归的终止情况if (l > r) return;//选取分界线。这里选数组中间那个数int i l - 1, j r 1, x q[l r >> 1];//划分成左右两个部分while (i < j){do i ; while (q[i] < x);do …

正点原子嵌入式linux驱动开发——TF-A初探

上一篇笔记中&#xff0c;正点原子的文档简单讲解了一下什么是TF-A&#xff0c;并且也学习了如何编译TF-A。但是TF-A是如何运行的&#xff0c;它的一个运行流程并未涉及。TF-A的详细运行过程是很复杂的&#xff0c;涉及到很多ARM处理器底层知识&#xff0c;所以这一篇笔记的内容…

PHP 反序列化漏洞:__PHP_Incomplete_Class 与 serialize(unserialize($x)) !== $x;

文章目录 参考环境声明__PHP_Incomplete_Class灵显为什么需要 __PHP_Incomplete_Class&#xff1f;不可访问的属性 serialize(unserialize($x)) $x;serialize(unserialize($x)) ! $x;雾现__PHP_Incomplete_Class 对象与其序列化文本的差异试构造 __PHP__Incomplete_Class 对象…

UE5.1编辑器拓展【二、脚本化资产行为,快速更改资产名字,1.直接添加前缀或后缀2.通过资产类判断添加修改前缀】

目录 了解相关的函数 第一种做法&#xff1a;自定义添加选择资产的前缀或后缀 代码 效果 第二种做法&#xff1a;通过映射来获取资产类型添加前缀和修改前缀 映射代码 代码 效果 在之前一章中&#xff0c;我们创建了插件&#xff0c;用来扩展编辑器的使用&#xff1a; …

VS Code 如何搭建 C/C++开发环境

目录 VScode是什么? VScode的下载和安装? 2.1 下载和安装 安装&#xff1a; 2.2 环境的介绍 环境介绍&#xff1a;​编辑 安装中文插件&#xff1a; VScode配置 C/C 开发环境 3.1 下载和配置MinGW-w64 编译器套件 下载&#xff1a; 配置MinGW64&#xff1a; 3.2 安…

加入PreAuthorize注解鉴权之后NullPointerException报错

记录一次很坑的bug&#xff0c;加入PreAuthorize注解鉴权之后NullPointerException报错&#xff0c;按理来说没有权限应该403报错&#xff0c;但是这个是500报错&#xff0c;原因是因为controller层的service注入失败&#xff0c;然而我去掉注解后service注入成功&#xff0c;并…

python之股票财务分析

#import akshare as ak import pandas as pd import matplotlib.pyplot as plt symbol1"资产负债表" symbol2"利润表" symbol3"现金流量表" #df1ak.stock_financial_report_sina(stock"601633",symbolsymbol1) #df2ak.stock_financial…

数据结构刷题(三十三):完全背包最小值情况。322. 零钱兑换、279. 完全平方数

题目一&#xff1a; 322. 零钱兑换https://leetcode.cn/problems/coin-change/ 思路&#xff1a;完全背包问题&#xff0c;求解最小组合数。dp[j]&#xff1a;凑足总额为j所需钱币的最少个数为dp[j]。同时需要确保凑足总金额为0所需钱币的个数一定是0&#xff0c;那么dp[0] 0…

001 Python开发环境搭建

1、下载python 2023/10 python-3.11.5-amd64.exehttps://www.python.org/ftp/python/3.11.5/python-3.11.5-amd64.exe 2、下载Visual Studio Code 2023/10 VSCodeSetup-x64-1.82.2.exehttps://code.visualstudio.com/docs/?dvwin64 3、安装python 双击打开python-3.11.5-a…

SpringCloud Alibaba - Sentinel 授权规则、自定义异常结果

目录 一、授权规则 1.1、什么是授权规则 1.2、授权规则的配置 1.2.1、配置信息介绍 1.2.2、如何得到请求来源 1.2.3、实现步骤 a&#xff09;给网关过来的请求添加请求头信息 b&#xff09;在 订单微服务 中实现 RequestOriginParser 接口中的 parseOrigin 方法 c&…

排序:外部排序算法分析

1.外存与内存之间的数据交换 1.外存&#xff08;磁盘&#xff09; 操作系统以“块”为单位对磁盘存储空间进行管理&#xff0c;如:每块大小1KB 各个磁盘块内存放着各种各样的数据。 2.内存 磁盘的读/写以“块”为单位数据读入内存后才能被修改修改完了还要写回磁盘。 2.外…

Jmeter分布式压力测试

目录 1、场景 2、原理 3、注意事项 4、slave配置 5、master配置 6、脚本执行 1、场景 在做性能测试时&#xff0c;单台机器进行压测可能达不到预期结果。主要原因是单台机器压到一定程度会出现瓶颈。也有可能单机网卡跟不上造成结果偏差较大。 例如4C8G的window server机…

2023-10-01 LeetCode每日一题(买卖股票的最佳时机)

2023-10-01每日一题 一、题目编号 121. 买卖股票的最佳时机二、题目链接 点击跳转到题目位置 三、题目描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一…

[NOIP2012 提高组] 国王游戏(贪心,排序,高精度)

[NOIP2012 提高组] 国王游戏 题目描述 恰逢 H 国国庆&#xff0c;国王邀请 n n n 位大臣来玩一个有奖游戏。首先&#xff0c;他让每个大臣在左、右手上面分别写下一个整数&#xff0c;国王自己也在左、右手上各写一个整数。然后&#xff0c;让这 n n n 位大臣排成一排&…

Mac程序坞美化工具 uBar

uBar是一款为Mac用户设计的任务栏增强软件&#xff0c;它可以为您提供更高效和更个性化的任务管理体验。 以下是uBar的一些主要特点和功能&#xff1a; 更直观的任务管理&#xff1a;uBar改变了Mac上传统的任务栏设计&#xff0c;将所有打开的应用程序以类似于Windows任务栏的方…

xilinx的原语的使用

xilinx的原语的使用 在学习FPGA实现千兆网时需要GMII转RGMII&#xff0c;这就涉及了原语的使用&#xff0c;特此记录&#xff01; 一、原语 与RGMII接口相关的原语&#xff1a; BUFG:全局时钟网络 BUFIO&#xff1a;只能采集IO的数据&#xff0c;采集IO数据的时候延时是最低的…

浅谈OV SSL 证书的优势

随着网络威胁日益增多&#xff0c;保护网站和用户安全已成为每个企业和组织的重要任务。在众多SSL证书类型中&#xff0c;OV&#xff08;Organization Validation&#xff09;证书以其独特的优势备受关注。让我们深入探究OV证书的优势所在&#xff0c;为网站安全搭建坚实的防线…