MyBatis 入门使用(二)

MyBatis的开发有两种方式:注解和XML,上一期我们学习了使用注解的方式,这期我们学习XML的方式。

使用注解主要是用来完成一些简单的增删改查功能,如果需要实现复杂的SQL功能,建议使用XML来配置映射语句。

1. 使用步骤

1.1 配置连接字符串和MyBatis

在配置文件中填写以下配置信息:

spring:application:name: J20240402-MyBatis
#数据库连接配置datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:mapper-locations: classpath:mapper/**Mapper.xml

mapper-locations: classpath:mapper/**Mapper.xml

mapper-locations: 用于指定Mapper XML文件的位置。

classpath:mapper/**Mapper.xml:classpath表示resources文件夹,表示把xm文件夹放在resource文件夹下的mapper文件夹中,并且xml文件必须是Mapper.xml结尾,**表示通配符。

1.2 接口定义

和使用注解相同我们同样需要先定义接口和方法:

package com.example.mybatis.mapper;import com.example.mybatis.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserInfoXMLMapper {Integer insert(UserInfo userInfo);
}

1.3 接口实现

我们需要在1.1中指定的路径中创建一个符合要求的xml文件:

然后在xml文件中实现接口中的方法:

在此之前我们需要先在xml文件中填写固定的xml格式:

<?xml version="1.0" encoding="UTF-8"?> <!--xml版本和编码格式--><!--用于指定XML文档类型及其DTD(文档类型定义)的位置-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--指定了该Mapper XML文件所属的命名空间,即com.example.demo.mapper.UserInfoXMLMapper,我们定义的接口的路径-->
<mapper namespace="com.example.mybatis.mapper.UserInfoXMLMapper"></mapper>

接下来我们只需在mapper标签中实现对应的方法:

<mapper namespace="com.example.mybatis.mapper.UserInfoXMLMapper"><insert id="insert">insert into userinfo (username, password, age, gender)values (#{username}, #{password}, #{age}, #{gender})</insert>
</mapper>

SQL语句的构造和使用注解的方式相同

单元测试:

@SpringBootTest
class UserInfoXMLMapperTest {@AutowiredUserInfoXMLMapper userInfoXMLMapper;@Testvoid insert() {UserInfo userInfo = new UserInfo();userInfo.setUsername("liHua");userInfo.setPassword("liHua");userInfo.setAge(20);userInfo.setGender(2);System.out.println(userInfoXMLMapper.insert(userInfo));}
}

运行代码:

2. 基本操作

前面已经演示了xml如何使用,接下来的增删改查操作我们就简单看一下代码:

@Mapper
public interface UserInfoXMLMapper {Integer insert(UserInfo userInfo);Integer delete(Integer id);Integer update(UserInfo userInfo);List<UserInfo> select();
}
<mapper namespace="com.example.mybatis.mapper.UserInfoXMLMapper"><insert id="insert">insert into userinfo (username, password, age, gender)values (#{username}, #{password}, #{age}, #{gender})</insert><delete id="delete">delete from userinfo where id = #{id}</delete><update id="update">update userinfo set username = #{username}, password = #{password}, age = #{age}, gender = #{gender} where id = #{id}</update><select id="select" resultType="com.example.mybatis.model.UserInfo">select * from userinfo</select>
</mapper>

由于select的返回类型不唯一,所以需要指定返回类型

@SpringBootTest
class UserInfoXMLMapperTest {@AutowiredUserInfoXMLMapper userInfoXMLMapper;@Testvoid insert() {UserInfo userInfo = new UserInfo();userInfo.setUsername("liHua");userInfo.setPassword("liHua");userInfo.setAge(20);userInfo.setGender(2);System.out.println(userInfoXMLMapper.insert(userInfo));}@Testvoid delete() {System.out.println(userInfoXMLMapper.delete(10));}@Testvoid update() {UserInfo userInfo = new UserInfo();userInfo.setId(11);userInfo.setUsername("Hua");userInfo.setPassword("Hua");userInfo.setAge(25);userInfo.setGender(1);System.out.println(userInfoXMLMapper.update(userInfo));}@Testvoid select() {System.out.println(userInfoXMLMapper.select());}
}

注意:使用xml的方式查询时依然存在字段名不相同无法赋值的情况,解决方法仍然有三种:

1. 起别名(和使用注解相同)

2.结果映射

3.驼峰自动转换(和使用注解相同)

结果映射:

<mapper namespace="com.example.mybatis.mapper.UserInfoXMLMapper"><resultMap id="resultMap" type="com.example.mybatis.model.UserInfo"><id column="id" property="id"></id><result column="delete_flag" property="deleteFlag"></result><result column="create_time" property="createTime"></result><result column="update_time" property="updateTime"></result></resultMap><select id="select" resultMap="resultMap">select * from userinfo</select>
</mapper>

主键映射一般使用 id ,其他使用result

3. 其他查询操作

3.1 多表查询 

数据准备:

我们已经有了一张工作表,我们再来建一张文章表:

-- 创建⽂章表
DROP TABLE IF EXISTS articleinfo;
CREATE TABLE articleinfo (
id INT PRIMARY KEY auto_increment,
title VARCHAR ( 100 ) NOT NULL,
content TEXT NOT NULL,
uid INT NOT NULL,
delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
create_time DATETIME DEFAULT now(),
update_time DATETIME DEFAULT now()
) DEFAULT charset 'utf8mb4';
-- 插⼊测试数据
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'Java', 'Java正⽂', 1
);

准备对应的类:

package com.example.mybatis.model;import lombok.Data;
import java.util.Date;@Datapublic class ArticleInfo {private Integer id;private String title;private String content;private Integer uid;private Integer deleteFlag;private Date createTime;private Date updateTime;
}

需求:查询文章信息和对应的作者信息:

创建接口:

package com.example.mybatis.mapper;import com.example.mybatis.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface ArticleInfoMapper {List<ArticleInfo> getArticleAndUser(Integer id);
}

我们发现,如果我们使用 ArticleInfo 接收结果的话是行不通的,因为查询结果还包含了UserInfo的数据,所以我们可以创建一个新类来接收,或者在ArticleInfo中添加UserInfo中的属性:

package com.example.mybatis.model;import lombok.Data;
import java.util.Date;
@Data
public class ArticleInfo {private Integer id;private String title;private String content;private Integer uid;private Integer deleteFlag;private Date createTime;private Date updateTime;//UserInfoprivate String username;private Integer age;private Integer gender;
}

xml:

<?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.mybatis.mapper.ArticleInfoMapper"><select id="getArticleAndUser" resultType="com.example.mybatis.model.ArticleInfo">select a.* b.username, b.age, b.genderfrom articleinfo a left join userinfo b on a.uid = b.id where a.id = #{id};</select>
</mapper>

单元测试:

3.2 #{} 和 ${} 

MyBatis 参数赋值有两种方式,前面我们使用了 #{},接下来我们介绍 ${},以及它们的区别

3.2.1 ${}使用 

${}的使用方式和 #{}相同,都是用来框选参数。

我们分别运行这两个方法:

我们对比发现: 前者的SQL语句是使用的 ?进行占位,这种SQL我们称为预编译SQL,后者则是直接把 参数拼接上去,我们称为即时SQL。如果我们把参数类型换为 String类型会出现一个问题:

我们发现使用 #{}能运行成功,使用${}发生了报错信息,我们观察报错语句中的SQL,发现 SQL中没有给admin加引号,所以导致了错误,现在我们在${}外面加上引号再次运行:

 正常运行。

3.1.2 #{} 和 ${} 的区别

#{}和${}的区别就是预编译SQL和即时SQL的区别

1.性能

当服务器接收到一条SQL之后会发生以下流程:

 大多数情况下,一条SQL语句会被反复执行,只是每次的参数有个别不同,如果每次都要完整的经历上述步骤,那么会大大降低效率,预编译SQL编译一次之后会将编译后的SQL语句缓存起来,后面执行时再次执行到这条语句时不会再次编译,直接把参数替换后直接执行。即时SQL则每次都是一条全新的SQL会完整经历每个步骤。

2. 安全

使用${}有被SQL注入攻击的风险:

用刚才的代码举例:由于${}是拼接的方式来构造SQL,如果输入时输入:' or 1='1,这时我们的SQL语句就变成了:select * from userinfo where username = '' or 1='1'  那么此时会把我们所有的内容都查出来,因为 1 一定等于 1,所以我们能使用 #{}的场景都尽量使用 #{}

3.3 ${} 使用场景

有时候我们可能需要输入 SQL语句的非参数部分来作为参数,此时就不需要加引号也就要用到 ${},例如排序场景:

 

此时我们传入 desc 或者 asc 来决定升序或降序是不能加引号的

3.4 like查询

分别运行两个方法:

 

这里的参数是不能加引号的所以#{}运行失败,不过我们可以使用SQL中的字符串拼接函数:

4. 数据库连接池

SprintBoot使用了数据库连接池技术避免了频繁的创建连接,销毁连接。

数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接(类似于线程池),程序启动时,会在数据库连接池中创建一定数量的Connection对象,当客户请求数据库连接时,会从数据库连接池中获取Connection对象,然后执行SQL,SQL语句执行完,再把Connection归还给连接池。

常见的数据库连接池有:

  • C3P0
  • DBCP
  • Druid
  • Hikari

目前比较流行的是:Hikari,Druid,SpringBoot默认使用的是Hikari

我们如果想更换数据库连接池只需引入相关依赖即可。

5. MySQL 开发企业规范

  1. 表名,字段名使用小写字母或数字,单词之间以下划线分割,尽量避免数字开头或者两个下划线中间只出现数字,数据库字段名的修改代价很大,所以字段名需要慎重考虑。
  2. 表必备三个字段:id(主键),create_time,update_time
  3. 在表查询中,避免使用 * ,标明哪些字段需要查询

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

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

相关文章

性能优化 - 你能说一说,为什么做了骨架屏,FCP的指标还是没有提升吗

难度级别:中高级及以上 提问概率:80% FCP的全程是First Contentful Paint,是衡量网页性能的一个重要指标,很多人把FCP理解为元素内容首次渲染到浏览器上的时间。但由于现在比较流行的Vue或是React项目中,HTML文档最初只有一个id为app的DIV…

篮球竞赛|基于Springboot的篮球竞赛预约平台系统设计与实现(源码+数据库+文档)

篮球竞赛预约平台目录 基于Springboot的篮球竞赛预约平台系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、前台&#xff1a; 2、后台 管理员功能 用户功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff…

武汉星起航深入分析市场动态,赢得跨境市场的高度认可

随着全球跨境电商的蓬勃发展&#xff0c;武汉星起航以其独到的市场洞察和深度合作模式在行业中崭露头角。公司凭借对市场趋势、消费者需求和竞争格局的敏锐洞察而声名鹊起&#xff0c;不仅成功跟随市场脉搏&#xff0c;更在竞争激烈的跨境电商领域中脱颖而出。 武汉星起航在制…

阿里云服务器可以干嘛?阿里云服务器八大用途介绍

阿里云服务器可以干嘛&#xff1f;能干啥你还不知道么&#xff01;简单来讲可用来搭建网站、个人博客、企业官网、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云百科aliyunbaike.com整理阿里云服务器的用途&#xff1a; 阿里云服务器活动 aliyunbaike.com…

Sharding

Sharding操作 什么是ShardingSharding-JDBC一、引入maven依赖 &#xff08;sharding-jdbc-spring-boot-starter&#xff09;二、水平分表操作&#xff08;一个库多个相同结构表&#xff09;其他的maven依赖版本 &#xff08;shardingsphere-jdbc-core-spring-boot-starter&…

JavaScript - 请问你是如何中断forEach循环的

难度级别:中高级及以上 提问概率:65% forEach与原始for循环不同的是,并不能通过简单的break或是return中断循环,意思就是不管需要循环的数组有多长,一旦使用了,就会将数组所有元素循环一遍才会结束。其实回答这道题,就要想到forEach的使…

使用GDAL进行简单的坐标系转换

使用GDAL进行简单的坐标系转换 使用python GDAL进行简单的坐标系转换&#xff0c;暂时不考虑不同基准坐标系转换的精度问题。 安装环境 使用UbuntuAnaconda python 环境 conda install gdal 定义坐标系 from osgeo import gdal from osgeo import osrsrs_wgs84 osr.Spati…

Linux系统下关闭Java进程

关闭Java进程具体分为两步&#xff1a; 1.ps查进程ID 2.kill杀进程 具体的命令如下&#xff1a; ps查进程ID&#xff1a;ps -ef | grep java kill杀进程&#xff1a;kill -9 对应进程号 linux下解除被占用的端口号&#xff1a; 1.查看8088端口是否被占用&#xff1a; netsta…

开源区块链系统/技术 总结(欢迎补充,最新)

1. FISCO BCOS FISCO BCOS 2.0 技术文档 — FISCO BCOS 2.0 v2.9.0 文档https://fisco-bcos-documentation.readthedocs.io/ 2. ChainMaker&#xff08;长安链&#xff09; 文档导航 — chainmaker-docs v2.3.2 documentationhttps://docs.chainmaker.org.cn/v2.3.2/html/in…

基于ssm办公用品管理系统开发与设计论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本办公用品管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

Composer Windows 安装

Composer 的下载地址为&#xff1a;Composer 1 运行安装程序 当启动安装程序后单击下一步继续。 选择 PHP 路径 如果你的计算机上没有安装 PHP 的话&#xff0c;Composer 的安装无法继续。 你需要选择你本地安装的 PHP 路径。 配置代理地址 默认的情况下&#xff0c;可以不…

酷开科技|酷开系统帮你找到快乐时光的正确打开方式!|酷开会员

在难得的周末假期中&#xff0c;你是否也希望自己的生活变得更加多彩呢&#xff1f;在闲暇时间里&#xff0c;你是否计划好了如何度过&#xff1f;小朋友们自然希望能够有父母陪伴在身边&#xff0c;而大朋友们也希望能给这个时节留下不一样的回忆。不论你对生活的期待是什么&a…