MyBatis精讲(八)MyBatis注解用法之DAO数据注解对象实战代码详解
ztj100 2025-01-07 17:22 16 浏览 0 评论
大家好,我是 @老K玩代码。
本期是关于MyBatis基础教程讲义的最后一讲了,我们要来说说MyBatis的一个特性——注解。
MyBatis里有很多功能注解,我们可以通过这些注解,实现各种映射器接口,替代mapper.xml类文件的作用。
到底应该怎么做呢?我们一起开看一下。
之前的内容可以通过下面的链接查看:
- 老K玩代码:MyBatis精讲(一)MyBatis基础配置及持久层连接创建代码实战
- 老K玩代码:MyBatis精讲(二)常用工具MyBatisUtils类的实现
- 老K玩代码:MyBatis精讲(三)一篇文章让你学会如何用MyBatis获取数据
- 老K玩代码:MyBatis精讲(四)查询数据方法精讲及实战代码集合
- 老K玩代码:MyBatis精讲(五)CRUD操作及实战代码精讲
- 老K玩代码:MyBatis精讲(六)一对多数据查询实战分享
- 老K玩代码:MyBatis精讲(七)动态SQL查询方法实战代码讲解
这一讲对的内容有点多,建议可以先收藏起来,慢慢读,慢慢消化。
一、准备工作
通过maven新建项目,以及在pom文件里配置依赖库相关的步骤就不介绍了,有需要的可以看《MyBatis精讲(一)MyBatis基础配置及持久层连接创建代码实战》。
项目配置好后,我们先把数据库通过sql语句的方式导入到项目里:
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`depart` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`salary` decimal(10, 2) NOT NULL,
`age` int NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
`did` int UNSIGNED NOT NULL AUTO_INCREMENT,
`depart` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`member` int NULL DEFAULT NULL,
PRIMARY KEY (`did`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
INSERT INTO `employee` VALUES (5001, '赵乾', '销售部', 6000.00, 28);
INSERT INTO `employee` VALUES (5002, '孙礼', '销售部', 7000.00, 34);
INSERT INTO `employee` VALUES (6001, '周武', '技术部', 6500.00, 27);
INSERT INTO `employee` VALUES (6002, '郑望', '技术部', 7500.00, 40);
INSERT INTO `department` VALUES (1, '销售部', 5);
INSERT INTO `department` VALUES (2, '技术部', 6);
在项目路径下创建一个dao目录(本例中的完整路径为./src/main/java/koder/mybatis/dao)。
DAO是Data Annotation Objects的首字母,表示数据注解对象实体。
然后在mybatis-config.xml进行如下配置(注:mybatis-config.xml文件路径参考《MyBatis精讲(一)MyBatis基础配置及持久层连接创建代码实战》中的内容。)
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="True"/>
</settings>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/javasql?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="koder.mybatis.dao"/>
</mappers>
</configuration>
- <package>是用来配置映射器包的标签,一般是包含映射器接口的目录位置。
二、查询数据
我们首先在映射器包(本例中该路径为./src/main/java/koder/mybatis/dao)下新建一个接口类——HRDao.java,并编写以下内容:
- HRDao.java
import koder.mybatis.dto.EmployeeDTO;
import koder.mybatis.entity.Employee;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface HRDao {
@Select("select * from employee where id = #{value}")
public Employee selectById(@Param("value") Integer id);
}
- koder.mybatis.dto.EmployeeDTO是后面案例会用到的数据传输对象类,在这里先导入;
- org.apache.ibatis.annotations是mybatis的注解类;
- 用@Select注解,定义sql查询语句;
- 对于sql查询语句中的可变参数,用#{value}表示,这里的value是自定义的,可以是任何变量名称;
- 用@Param注解定义变量参数,便是该参数对应在sql查询语句中的名称,本例中表示java方法参数id就是sql语句中的value值。
这样,一个数据注解对象、也就是注解映射器就写好了,接下来我们编写测试用例:
- MyBatisTest.java(文件路径和基本配置参见《MyBatis精讲(三)一篇文章让你学会如何用MyBatis获取数据》)
@Test
public void TestDaoSelectById() {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSession();
HRDao hrDao = sqlSession.getMapper(HRDao.class);
Employee emp = hrDao.selectById(6001);
System.out.println(emp.getName());
}catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtils.closeSession(sqlSession);
}
}
- 通过SqlSession的getMapper方法获取数据注解对象类,本例中为HRDao的class;
- 调用HRDao的查询方法,就能直接对应映射的sql语句,执行查询,返回对应数据类型;
上述代码运行后的结果为:
周武
三、插入数据
插入数据的映射接口,可以用@Insert注解器实现:
- HRDao.java
@Insert("insert into employee(name, depart, salary, age) values (#{name}, #{depart}, #{salary}, #{age})")
@SelectKey(statement = "select last_insert_id()", keyProperty = "id", keyColumn = "id", before = false, resultType = Integer.class)
public int insert(Employee employee);
- 上述代码内容,应写在HRDao接口内,是HRDao的内部方法;
- @Insert可以接收sql的插入语句,如果传入的是实体对象(如Employee),@Insert注解器会自动将实体类的成员变量通过驼峰转换传入sql语句;
- @SelectKey相当于MyBatis的xml语法中的<selectKey>功能一致,定义的sql语句会和主语句一起被执行。statement参数接收sql语句,keyProperty接受java类中的成员变量名,keyColumn接受数据库中的字段列名,before表示该语句是在主语句之前还是之后执行,resultType是将执行后得到的数据存入那个数据类型中;
然后在MyBatisTest.java中写入测试用例:
- MyBatisTest.java
@Test
public void TestDaoInsert() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
Employee employee = new Employee();
employee.setAge(34);
employee.setDepart("技术部");
employee.setName("储纬");
employee.setSalary(7700.0f);
HRDao hrDao = session.getMapper(HRDao.class);
hrDao.insert(employee);
session.commit();
System.out.println(employee.getId());
} catch (Exception e) {
if (session != null) {
session.rollback();
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
- 由于映射器接口中insert方法传入的参数是Employee,所以我们先实例化一个Employee实例,传入到HRDao.insert方法中;
- insert方法使用事务机制,所以完成方法调用后,需要commit才能生效,并且失败后需要rollback。
执行上述代码后,得到结果如下:
6003
并且,查看数据库也能发现新的数据被录入成功!
四、修改数据
编写映射接口。
- HRDao.java
@Update("update employee set name = #{name}, depart = #{depart}, salary = #{salary}, age = #{age} where id = #{id}")
public int update(Employee employee);
- @Update是更新数据的注解方法,语法特征与@Insert类似。
而测试用例编写如下:
- MyBatis.java
@Test
public void TestDaoUpdate() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
HRDao hrDao = session.getMapper(HRDao.class);
Employee employee = hrDao.selectById(6001);
employee.setSalary(7900f);
hrDao.update(employee);
session.commit();
System.out.println(employee.getId());
} catch (Exception e) {
if (session != null) {
session.rollback();
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
- 由于修改数据,需要先从数据库中获取,我们用查询方法select ById获取Employee实例;
- 调用HRDao的update方法,执行更新数据的操作;
- 由于是事务机制,所以需要添加commit和rollback语句;
执行上述代码后,可以发现数据库中对应条目的薪酬已改为7900.00。
五、删除数据
编写映射接口:
- HRDao.java
@Delete("delete from employee where id = #{value}")
public int delete(@Param("value") Integer id);
- @Delete是删除数据的注解类,注意要点与@Update、@Insert一致;
- 参数用@Param进行映射匹配;
测试用例编写如下:
- MyBatis.java
@Test
public void TestDaoDelete() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
HRDao hrDao = session.getMapper(HRDao.class);
hrDao.delete(6003);
session.commit();
} catch (Exception e) {
if (session != null) {
session.rollback();
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
执行上述代码后,可以发现,之前插入的数据“储纬”已被删除;
六、自定义ResultMap链表查询
之前讲过通过mapper.xml语法连表查询需要用到resultMap标签,那么,如果用数据注解对象,如何解决链表查询的问题呢?
首先在HRDao.java编写接口:
- HRDao.java
@Select("select e.*, d.* from employee e, department d where e.depart = d.depart")
@Results({
@Result(property="employee.id", column="id", id = true),
@Result(property="employee.name", column="name"),
@Result(property="employee.salary", column="salary"),
@Result(property="employee.depart", column="depart"),
@Result(property="employee.depart", column="depart"),
@Result(property="employee.age", column="age"),
@Result(property="department.did", column="did"),
@Result(property="department.member", column="member")
})
public List<EmployeeDTO> selectDTO();
- 我们先用@Select编写链表查询的语句;
- 利用@Results注解定义当前方法的结果类;
- 在@Results中通过@Result对数据属性进行映射,参数property接收java类中的成员变量,参数column接收数据库中的字段列名,id表示该字段是否作为id索引;
测试用例:
- MyBatis.java
@Test
public void TestDaoSelectDto() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
HRDao hrDao = session.getMapper(HRDao.class);
List<EmployeeDTO> emps = hrDao.selectDTO();
for (EmployeeDTO emp: emps) {
System.out.println(emp.getEmployee().getName() + "所在的部门有"+emp.getDepartment().getMember() + "人。");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
- DTO链表查询和普通查询代码逻辑一样;
执行上述代码,获得如下结果:
赵乾所在的部门有5人。
孙礼所在的部门有5人。
周武所在的部门有6人。
郑望所在的部门有6人。
以上,就是MyBatis的数据注解对象DAO常见的使用方法。
DAO相比起xml映射器,代码的可读性更强,对java工程师更友好,而且java编译器能提供语法支持,更便于工程师们排查错误。
熟练掌握DAO映射接口的写法,对高效使用MyBatis有很大的帮助!
感谢你看到这里。
如果你对老K分享的内容有任何疑问,欢迎随时在评论区留言或者私信我。
正在学习的小伙伴记得给老K一个赞哦,你的支持是我持续输出课程内容最大的动力。
结束语
我是专注于开发领域的@老K玩代码,会持续生产关于如何学习编程语言的优质内容。
如果你对编程和项目开发有兴趣,可以关注我。
相关推荐
- 30天学会Python编程:16. Python常用标准库使用教程
-
16.1collections模块16.1.1高级数据结构16.1.2示例...
- 强烈推荐!Python 这个宝藏库 re 正则匹配
-
Python的re模块(RegularExpression正则表达式)提供各种正则表达式的匹配操作。...
- Python爬虫中正则表达式的用法,只讲如何应用,不讲原理
-
Python爬虫:正则的用法(非原理)。大家好,这节课给大家讲正则的实际用法,不讲原理,通俗易懂的讲如何用正则抓取内容。·导入re库,这里是需要从html这段字符串中提取出中间的那几个文字。实例一个对...
- Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)
-
实现功能:Python数据分析实战-利用正则表达式提取文本中的URL网址和邮箱...
- python爬虫教程之爬取当当网 Top 500 本五星好评书籍
-
我们使用requests和re来写一个爬虫作为一个爱看书的你(说的跟真的似的)怎么能发现好书呢?所以我们爬取当当网的前500本好五星评书籍怎么样?ok接下来就是学习python的正确姿...
- 深入理解re模块:Python中的正则表达式神器解析
-
在Python中,"re"是一个强大的模块,用于处理正则表达式(regularexpressions)。正则表达式是一种强大的文本模式匹配工具,用于在字符串中查找、替换或提取特定模式...
- 如何使用正则表达式和 Python 匹配不以模式开头的字符串
-
需要在Python中使用正则表达式来匹配不以给定模式开头的字符串吗?如果是这样,你可以使用下面的语法来查找所有的字符串,除了那些不以https开始的字符串。r"^(?!https).*&...
- 先Mark后用!8分钟读懂 Python 性能优化
-
从本文总结了Python开发时,遇到的性能优化问题的定位和解决。概述:性能优化的原则——优化需要优化的部分。性能优化的一般步骤:首先,让你的程序跑起来结果一切正常。然后,运行这个结果正常的代码,看看它...
- Python“三步”即可爬取,毋庸置疑
-
声明:本实例仅供学习,切忌遵守robots协议,请不要使用多线程等方式频繁访问网站。#第一步导入模块importreimportrequests#第二步获取你想爬取的网页地址,发送请求,获取网页内...
- 简单学Python——re库(正则表达式)2(split、findall、和sub)
-
1、split():分割字符串,返回列表语法:re.split('分隔符','目标字符串')例如:importrere.split(',','...
- Lavazza拉瓦萨再度牵手上海大师赛
-
阅读此文前,麻烦您点击一下“关注”,方便您进行讨论和分享。Lavazza拉瓦萨再度牵手上海大师赛标题:2024上海大师赛:网球与咖啡的浪漫邂逅在2024年的上海劳力士大师赛上,拉瓦萨咖啡再次成为官...
- ArkUI-X构建Android平台AAR及使用
-
本教程主要讲述如何利用ArkUI-XSDK完成AndroidAAR开发,实现基于ArkTS的声明式开发范式在android平台显示。包括:1.跨平台Library工程开发介绍...
- Deepseek写歌详细教程(怎样用deepseek写歌功能)
-
以下为结合DeepSeek及相关工具实现AI写歌的详细教程,涵盖作词、作曲、演唱全流程:一、核心流程三步法1.AI生成歌词-打开DeepSeek(网页/APP/API),使用结构化提示词生成歌词:...
- “AI说唱解说影视”走红,“零基础入行”靠谱吗?本报记者实测
-
“手里翻找冻鱼,精心的布局;老漠却不言语,脸上带笑意……”《狂飙》剧情被写成歌词,再配上“科目三”背景音乐的演唱,这段1分钟30秒的视频受到了无数网友的点赞。最近一段时间随着AI技术的发展,说唱解说影...
- AI音乐制作神器揭秘!3款工具让你秒变高手
-
在音乐创作的领域里,每个人都有一颗想要成为大师的心。但是面对复杂的乐理知识和繁复的制作过程,许多人的热情被一点点消磨。...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 30天学会Python编程:16. Python常用标准库使用教程
- 强烈推荐!Python 这个宝藏库 re 正则匹配
- Python爬虫中正则表达式的用法,只讲如何应用,不讲原理
- Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)
- python爬虫教程之爬取当当网 Top 500 本五星好评书籍
- 深入理解re模块:Python中的正则表达式神器解析
- 如何使用正则表达式和 Python 匹配不以模式开头的字符串
- 先Mark后用!8分钟读懂 Python 性能优化
- Python“三步”即可爬取,毋庸置疑
- 简单学Python——re库(正则表达式)2(split、findall、和sub)
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)