从头开始学MyBatis—02基于xml和注解分别实现的增删改查

首先介绍此次使用的数据库结构,然后引出注意事项。

通过基于xml和基于注解的方式分别实现了增删改查,还有获取参数值、返回值的不同类型对比,帮助大家一次性掌握两种代码编写能力。

目录

数据库

数据库表

实体类

对应的实体类如下:

注意事项

1)两种占位符的说明

①#{}

②${}

2)增、删、改的返回值说明

3)查询操作

①必须指定resultType或是resultMap

4)对应关系

①数据库名与类名不一致的情况

②字段名与属性名不一致的情况

1.获取参数值的方式

1.1基于xml

1.1.1单个参数

①mapper

②xml

③test

④结果

1.1.2多个参数

①mapper

②xml

写法一

写法二

③test

④结果

1.1.3map参数

①mapper

②xml

③test

④结果

1.1.4实体类参数

①mapper

②xml

③test

④结果

1.1.5使用@Param标识参数

①mapper

写法一

写法二

错误写法

②xml

③test

④结果

1.2基于注解

1.2.1单个参数

①mapper

写法一

写法二

②test

③结果

1.2.2多个参数

①mapper

 ②test

③结果

1.2.3map参数

①mapper

②test

③结果

1.2.4实体类参数

①mapper

②test

③结果

1.2.5使用@Param标识参数

①mapper

写法一

写法二

②test

③结果

2.各种操作功能

2.1基于xml

2.1.1增

①mapper

②mapper.xml

③test

④结果

主键id自增并返回值

mapper

mapper.xml

test

结果

2.1.2删

①mapper

②mapper.xml

③test

④结果

删除前

删除后

2.1.3改

①mapper

②mapper.xml

③test

④结果

修改前

修改后

2.1.4查

①mapper

②mapper.xml

③test

④结果

2.2基于注解

2.2.1增

①mapper

②test

③结果

主键id自增并返回结果

mapper

test

结果

2.2.2删

①mapper

②test

③结果

删除前

删除后

2.2.3改

①mapper

②test

③结果

修改前

修改后

2.2.4查

①mapper

②test

③结果

3.各种返回值类型

3.1基于xml

①查询单条数据

②查询多条数据

3.2基于注解

①查询单条数据

②查询多条数据


数据库

数据库表

此次实验的数据库表结构如下,包含主键id和三个属性

实体类

对应的实体类如下:

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** ClassName: Book* Package: com.ykx.domain* Description: mybatis学习的数据库表tbl_book对应的实体类*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tbl_book")
public class Book {private Integer id;private String type;private String name;private String description;
}

注意事项

1)两种占位符的说明

①#{}

传入的参数当成一个字符串,会给传入的参数加单引号

能够很大程度上防止sql注入

一般用于替换某个值

②${}

将传入的参数值直接显示生成在sql中,不会自动加引号

预编译之前就已经被变量替换,无法防止sql注入

一般用于替换表、字段名

2)增、删、改的返回值说明

返回值固定位Integer,表示受影响的行数

3)查询操作

①必须指定resultType或是resultMap

不配置别名的时候,值为类的全类名

返回值是集合的时候,只需指定集合的泛型即可,如

List<Book> getAll();<select id="getAll" resultType="com.ykx.pojo.Book">select * from tbl_book
</select>

4)对应关系

①数据库名与类名不一致的情况

②字段名与属性名不一致的情况

1.获取参数值的方式

MyBatis 提供了多种传递参数的方式到 SQL 。

理解参数传递的机制有助于提高代码的可读性、灵活性。

1.1基于xml

1.1.1单个参数

①mapper
Book getById(Integer id);
②xml

在单个字面量参数的情况下,{}内的名称可以任意取

如下面的代码可以把#{id} 改成 #{ID}亦或是其他

<select id="getById" resultType="com.ykx.domain.Book">select * from tbl_book where id = #{id}
</select>
③test
@Test
public void testSelect(){Book book = bookMapperXML.getById(1);System.out.println(book);
}
④结果

1.1.2多个参数

①mapper
Book check(String type,String name);
②xml
写法一
<select id="check" resultType="com.ykx.domain.Book">select * from tbl_book where type = #{type} and name = #{name}
</select>
写法二
<select id="check" resultType="com.ykx.domain.Book">select * from tbl_book where type = #{param1} and name = #{param2}
</select>
③test
@Test
public void testCheck(){Book book = bookMapperXML.check("java","mybatis数据");System.out.println(book);
}
④结果

1.1.3map参数

①mapper
Book checkByMap(Map<String,String> map);
②xml
<select id="checkByMap" resultType="com.ykx.domain.Book">select * from tbl_book where type = #{type} and name = #{name}
</select>
③test
@Test
public void testCheckByMap(){Map<String,String> map = new HashMap<>();map.put("type","java");map.put("name", "mybatis数据");Book book = bookMapperXML.checkByMap(map);System.out.println(book);
}
④结果

1.1.4实体类参数

①mapper
Integer insert(Book book);
②xml
<insert id="insert">insert into tbl_book (type,name,description) values(#{type},#{name},#{description})
</insert>
③test
@Test
public void testInsert(){Book book = new Book(null,"计算机视觉","三维重建","基于深度学习的三维重建");Integer ans = bookMapperXML.insert(book);System.out.println("受影响的行数:" + ans);
}
④结果

1.1.5使用@Param标识参数

 在字段名和属性名对不上或是参数名和字段名对不上的时候很有用

①mapper
写法一
Book check(@Param("type") String type, @Param("name") String name);
写法二
Book check(@Param("type") String type2, @Param("name") String name2);
错误写法
Book check(String type2, String name2);
②xml
<select id="check" resultType="com.ykx.domain.Book">select * from tbl_book where type = #{type} and name = #{name}
</select>
③test
@Test
public void testCheck(){Book book = bookMapperXML.check("java","mybatis数据");System.out.println(book);
}
④结果

1.2基于注解

1.2.1单个参数

①mapper

单个参数的情况下,接口的参数名和注解里的sql语句参数可以不一致

写法一
@Select("select * from tbl_book where id = #{id}")
Book getById(Integer id);
写法二
@Select("select * from tbl_book where id = #{aa}")
Book getById(Integer id);
②test
@Test
public void testSelect(){Book book = bookMapper.getById(78);System.out.println(book);
}
③结果

1.2.2多个参数

①mapper

注:在未使用@Param的情况下,参数名不对应或是顺序不一样会导致查询失败

@Select("select * from tbl_book where type = #{type} and name = #{name}")
Book getOne(String type,String name);
 ②test
@Test
public void testGetOne(){Book book = bookMapper.getOne("计算机视觉","三维重建");System.out.println(book);
}
③结果

1.2.3map参数

①mapper
@Select("select * from tbl_book where type = #{type} and name = #{name}")
Book getByMap(Map<String, String> map);
②test

注:map里的key值要和#{}里的值对应,否则出现查询失败的情况

@Test
public void testByMap(){Map<String,String> map = new HashMap<>();map.put("type","java");map.put("name", "mybatis数据");Book book = bookMapper.getByMap(map);System.out.println(book);
}
③结果

1.2.4实体类参数

①mapper
@Insert("insert into tbl_book (id,type,name,description) " +"values(#{id},#{type},#{name},#{description})")
Integer insert(Book book);
②test
@Test
public void testInsert(){Book book = new Book(null,"新增数据","测试新增","不带id的新增测试");Integer ans = bookMapper.insert(book);System.out.println("受影响的行数:" + ans);
}
③结果

1.2.5使用@Param标识参数

只需要#{}里的值和@Param()里的值一样就行

①mapper
写法一
@Select("select * from tbl_book where type = #{type} and name = #{name}")
Book getOne(@Param("type") String type,@Param("name") String name);
写法二
@Select("select * from tbl_book where type = #{type} and name = #{name}")
Book getOne(@Param("type") String typeaa,@Param("name") String nameaa);
②test
@Test
public void testGetOne(){Book book = bookMapper.getOne("计算机视觉","三维重建");System.out.println(book);
}
③结果

2.各种操作功能

2.1基于xml

2.1.1增

①mapper
//增:实体对象新增数据
Integer insert(Book book);
②mapper.xml
<insert id="insert">insert into tbl_book (id,type,name,description) values(#{id},#{type},#{name},#{description})
</insert>

:这里设置了id主键自增的话,可以不设置和传入id

③test
//增:实体对象新增数据
@Test
public void testInsert(){Book book = new Book(71,"计算机视觉","三维重建","基于深度学习的三维重建");Integer ans = bookMapperXML.insert(book);System.out.println("受影响的行数:" + ans);
}
④结果

主键id自增并返回值

关键点:在xml里需要带上useGeneratedKeys和keyProperty

mapper
Integer autoId(Book book);
mapper.xml
<insert id="autoId" useGeneratedKeys="true" keyProperty="id">insert into tbl_book (type,name,description) values(#{type},#{name},#{description})
</insert>
test
//增:主键自增且返回值
@Test
public void testAutoId(){Book book = new Book(null,"测试id自增","返回主键id","是否成功获取id的值");Integer ans = bookMapperXML.autoId(book);System.out.println("受影响的行数:" + ans);System.out.println("获取主键自增的id值:" + book.getId());
}
结果

2.1.2删

①mapper
//删:根据id删除数据
Integer delete(Integer id);
②mapper.xml
<delete id="delete">delete from tbl_book where id = #{id};
</delete>
③test
//删:根据id删除数据
@Test
public void testDelete(){Integer ans = bookMapperXML.delete(68);System.out.println("受影响的行数:" + ans);
}
④结果

删除前

删除后

2.1.3改

①mapper
//改:根据id修改数据
Integer update(Book book);
②mapper.xml
<update id="update">update tbl_book set type = #{type},name = #{name},description = #{description} where id = #{id};
</update>
③test
//改:根据id修改数据
@Test
public void testUpdate(){Book book = new Book(58,"测试修改","mybatis修改","基于xml的修改操作");Integer ans = bookMapperXML.update(book);System.out.println("受影响的行数:" + ans);
}
④结果

修改前

修改后

2.1.4查

①mapper
@Mapper
public interface BookMapperXML {//查:根据id查询数据Book getById(Integer id);//查:查询所有数据List<Book> getAll();}
②mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ykx.mapper.BookMapperXML"><select id="getById" resultType="com.ykx.domain.Book">select * from tbl_book where id = #{id}</select><select id="getAll" resultType="com.ykx.domain.Book">select * from tbl_book</select>
</mapper>
③test
@SpringBootTest
public class XMLMybatisTest {@Autowiredprivate BookMapperXML bookMapperXML;//查:根据id查询数据@Testpublic void testSelect(){Book book = bookMapperXML.getById(1);}//查:查询所有数据@Testpublic void testGetAll(){List<Book> books = bookMapperXML.getAll();for(Book book : books){System.out.println(book);}}}
④结果

2.2基于注解

2.2.1增

①mapper
@Insert("insert into tbl_book (id,type,name,description) " +"values(#{id},#{type},#{name},#{description})")
Integer insert(Book book);
②test
//增:实体对象新增数据
@Test
public void testInsert(){Book book = new Book(11,"新增数据","测试新增","带id的新增测试");Integer ans = bookMapper.insert(book);System.out.println("受影响的行数:" + ans);
}
③结果

主键id自增并返回结果

关键点:在mapper对应的方法上面加上@Options注解,并设置useGeneratedKeys和keyProperty的属性值。这个只能搭配insert语句使用!

mapper
@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into tbl_book (type,name,description) " +"values(#{type},#{name},#{description})")
Integer autoId(Book book);
test
//增:主键自增且返回值
@Test
public void testAutoId(){Book book = new Book(null,"新增数据2","测试新增2","不带id的新增测试");Integer ans = bookMapper.autoId(book);System.out.println("受影响的行数:" + ans);System.out.println("获取主键自增的id值:" + book.getId());
}
结果

2.2.2删

①mapper
//删:根据id删除数据
@Delete("delete from tbl_book where id = #{id}")
Integer delete(Integer id);
②test
//删:根据id删除数据
@Test
public void testDelete(){Integer ans = bookMapper.delete(8);System.out.println("受影响的行数:" + ans);
}
③结果

删除前

删除后

2.2.3改

①mapper
//改:根据id修改数据
@Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
Integer update(Book book);
②test
//改:根据id修改数据
@Test
public void testUpdate(){Book book = new Book(62,"测试修改","mybatis修改","基于注解的修改操作");Integer ans = bookMapper.update(book);System.out.println("受影响的行数:" + ans);
}
③结果
修改前

修改后

2.2.4查

①mapper
//查:根据id查询数据
@Select("select * from tbl_book where id = #{id}")
Book getById(Integer id);//查:查询所有数据
@Select("select * from tbl_book")
List<Book> getAll();
②test
//查:根据id查询数据
@Test
public void testSelect(){Book book = bookMapper.getById(71);System.out.println(book);
}//查:查询所有数据
@Test
public void testGetAll(){List<Book> books = bookMapper.getAll();for(Book book : books){System.out.println(book);}
}
③结果

3.各种返回值类型

对于增、删、改操作一般返回值类型为integer,表示数据表受影响的行数。对于查询操作,一般返回值类型为实体类或是集合类型。

前面已经对增、删、改返回integer进行了测试,这里就不再赘述,下面对查询操作的返回值进行一个总结。

3.1基于xml

①查询单条数据

mapper层接口用对应的实体类接收

//查:根据id查询数据
Book getById(Integer id);

xml文件设置resultType为具体的实体类类型

<select id="getById" resultType="com.ykx.domain.Book">select * from tbl_book where id = #{id}
</select>

②查询多条数据

mapper层接口用List集合接收,其泛型为对应的实体类类型

//查:查询所有数据
List<Book> getAll();

xml文件设置resultType为具体的实体类类型

<select id="getAll" resultType="com.ykx.domain.Book">select * from tbl_book
</select>

3.2基于注解

①查询单条数据

mapper层接口的返回值类型设置为对应的实体类类型即可

//查:根据id查询数据
@Select("select * from tbl_book where id = #{id}")
Book getById(Integer id);

②查询多条数据

mapper层接口的返回值类型设置为List集合,其泛型为对应的实体类类型即可

//查:查询所有数据
@Select("select * from tbl_book")
List<Book> getAll();

原创内容 未经同意禁止转载 如有引用请标明出处

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

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

相关文章

Vue2 qrcode+html2canvas 实现二维码的生成和保存

1.安装 npm install qrcode npm install html2canvas 2.引用 import QRCode from qrcode import html2canvas from html2canvas 效果&#xff1a; 1. 二维码生成&#xff1a; 下载二维码图片&#xff1a; 二维码的内容&#xff1a; 实现代码&#xff1a; <template>…

重学SpringBoot3-SpringApplicationRunListener

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-SpringApplicationRunListener 1. 基本作用2. 如何实现2.1. 创建SpringApplicationRunListener2.2. 注册SpringApplicationRunListener2.3. 完整示例 3.…

初始爬虫5

响应码&#xff1a; 数据处理&#xff1a; re模块&#xff08;正则表达式&#xff09; re模块是Python中用于正则表达式操作的标准库。它提供了一些功能强大的方法来执行模式匹配和文本处理。以下是re模块的一些常见用法及其详细说明&#xff1a; 1. 基本用法 1.1 匹配模式 …

大势智慧与山东省国土测绘院签署战略合作协议

9月6日&#xff0c;山东省国土测绘院&#xff08;后简称山东院&#xff09;与武汉大势智慧科技有限公司&#xff08;后简称大势智慧&#xff09;签署战略合作协议。 山东院院长田中原、卫星应用中心主任相恒茂、基础测绘中心主任魏国忠、卫星应用中心高级工程师张奇伟&#xf…

记一次实战中对fastjson waf的绕过

最近遇到一个fastjson的站&#xff0c;很明显是有fastjson漏洞的&#xff0c;因为type这种字符&#xff0c;fastjson特征很明显的字符都被过滤了 于是开始了绕过之旅&#xff0c;顺便来学习一下如何waf 编码绕过 去网上搜索还是有绕过waf的文章&#xff0c;下面来分析一手&a…

性能测试-断言+自学说明(十二)

一、响应断言 需求;jmeter请求百度&#xff0c;断言响应结果中是否包含“百度一下&#xff0c;你就知道” 1、位置&#xff1a; http请求-断言-响应断言 2、类型 响应文本&#xff1a;断言响应体中包含的字符串 响应代码&#xff1a;断言响应状态码 3、断言步骤&#xf…

全文带你轻松备考OCM

OCM&#xff0c;作为Oracle公司授予的顶级专业认证&#xff0c;是数据库领域从业者梦寐以求的技术巅峰标志。它不仅是对个人技术深度与广度的全面肯定&#xff0c;更是职业道路上的一块重要里程碑。在踏上这段挑战之旅前&#xff0c;深入洞察OCM认证的精髓、考试细节及备考策略…

想要快速准备好性能数据?方法这不就来了!

性能测试的一般流程 收集性能需求——>编写性能脚本——>执行性能测试——>分析测试报告——>系统性能调优。 在收集性能需求后&#xff0c;我们会思考&#xff1a; 1.负载测试时并发时需要多少数据&#xff1f;例&#xff1a;登录&#xff1b; 2.DB数据是否和…

Spring-cloud-gateway报错问题总结

1. 访问接口出现 There was an unexpected error (typeService Unavailable, status503).Unable to find instance for order 假设我们有服务 spring-appication-name: order 但命名路由id 也为order 就会出现这类错误 因为 gateway 有默认路由

喜讯!和鲸科技荣获「2024 爱分析·数据智能优秀厂商」

9 月 13 日&#xff0c;2024 爱分析第六届数据智能高峰论坛圆满举办。会上正式公布了“2024 爱分析数据智能优秀厂商”&#xff0c;和鲸科技凭借在数据智能领域内的卓越成果与创新应用成功入选。 2024爱分析数据智能优秀厂商奖项旨在评选出在数据智能领域&#xff0c;综合实力突…

用Druid连接池,出现系统找不到指定路径的解决方案

运行时抛出异常&#xff08;系统找不到指定路径&#xff09;&#xff1a; 解决方法&#xff1a; 用 . 代替项目名就可以成功运行

Weblogic部署

要安装weblogic&#xff0c;首先要有java环境&#xff0c;因此需要先安装jdk。 这里需要注意&#xff0c;weblogic版本不同&#xff0c;对应的jdk版本也不同&#xff0c;我在这里就踩了很多坑&#xff0c;我这里下载的是fmw_12.2.1.4.0_wls_lite_generic.jar对应的是jdk-8u333…

冯诺依曼体结构与系统

冯诺依曼结构 我们的计算机&#xff0c;以及服务器&#xff0c;还有我我们日常使用的洗衣机都遵循冯诺依曼体结构。 以我们日常使用qq聊天时举例&#xff0c;冯诺依曼体结构可以这样画 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成 输入单元…

SpringBoot Jar 包加密防止反编译实战

今天给大家分享一个 SpringBoot 程序 Jar 包加密的方式&#xff0c;通过代码加密可以实现无法反编译。 应用场景就是当需要把公司的产品部署到友方公司或者其他公司时&#xff0c;可以防止客户直接反编译出来源码&#xff0c;大大提升代码的安全性。 版本 springboot 2.6.8j…

rabbitmq容器化部署

需求 容器化部署rabbitmq服务 部署服务 找到如下官网信息版本 官网版本发布信息 这里看到最新版本是3.13版本&#xff0c;这里在3.13中找一个版本下载容器镜像即可。 找到dockrhub.com中 找到3.13.2版本镜像。 容器服务安装此处省略 现在下载容器镜像需要配置容器代理 ~#…

Java静态代理和动态代理

通过一个小案例整理描述静态代理和动态代理 给大家举个简单例子。在一个公司中&#xff0c;老板处于上层&#xff0c;客户在下层。因每天来访客户众多&#xff0c;老板本应只考虑战略和赚钱&#xff0c;却被一些不重要的客户耽误不少时间。于是老板招聘了一个秘书&#xff0c;专…

大模型进行Query改写时如何提升性能

Query改写方法有子问题拆解、短语提取、回溯检索、虚拟文档等方法。见&#xff1a;https://blog.csdn.net/qq_43814415/article/details/138606669 llama-index的实现见&#xff1a;https://zhaozhiming.github.io/2024/05/13/query-rewrite-rag/ 这里总结实际使用大模型改写时…

Day09-StatefuleSet控制器

Day09-StatefuleSet控制器 0、昨日内容回顾1、StatefulSets控制器1.1 StatefulSet概述1.2 StatefulSets控制器-网络唯一标识之headless1.3 StatefulSets控制器-独享存储 2、metric-server2.1 metric-server概述2.2 部署metric-server:2.3 hpa案例 3、helm概述3.1 安装helm3.2 h…

并行程序设计基础——并行I/O(5)

目录 一、分布式数组文件的存取 1.1 MPI_TYPE_CREATE_DARRAY 1.2 MPI_TYPE_CREATE_SUBARRAY 二、小结 上一节我们对并行I/O中共享文件的存取操作进行了介绍,本节继续介绍MPI-2并行I/O的最后内容:分布式数组文件的存取。 一、分布式数组文件的存取 许多情况下,M…

ModbusTCP/RTU转Ethernet/IP(CIP)-Modbus设备与罗克韦尔AB的PLC之间通讯

IGT-DSER智能网关模块支持西门子、三菱、欧姆龙、罗克韦尔AB等各种品牌的PLC之间通讯&#xff0c;同时也支持PLC与Modbus协议的工业机器人、智能仪表、变频器等设备通讯。网关有多个网口、串口&#xff0c;也可选择WIFI无线通讯。无需PLC内编程开发&#xff0c;只要在IGT-DSER智…