当前位置: 首页 > news >正文

MyBatis:使用注解让数据库操作更简单

目录

一、简介

二、配置

三、基于注解的基本使用

四、测试

总结


一、简介

在Java开发中,数据库操作是一个常见而重要的任务。为了方便地执行SQL语句,获取结果集,处理异常等,我们通常需要使用JDBC(Java Database Connectivity)API,这是一个标准的数据库访问接口。然而,使用JDBC也有一些缺点,例如:

  • 我们需要编写大量的重复代码,如加载驱动,创建连接,关闭资源等。
  • 我们需要手动设置参数和获取结果集,这可能导致类型不匹配或空指针等错误。
  • 我们需要硬编码SQL语句,这可能导致可读性和维护性的问题。

为了解决这些问题,许多持久层框架(Persistence Framework)应运而生,它们可以提供更高层次的抽象和封装,使得数据库操作更加简单和方便。其中一个著名的持久层框架就是MyBatis。

MyBatis是一个开源的持久层框架,它支持自定义SQL,存储过程和高级映射。MyBatis可以通过简单的XML或注解来配置和映射原始类型,接口和Java POJO(Plain Old Java Objects)为数据库中的记录。MyBatis的主要特点有:

  • 简单易用:MyBatis可以消除几乎所有的JDBC代码和手动设置参数和获取结果集的工作。
  • 灵活强大:MyBatis可以使用动态SQL来适应各种复杂的查询需求,并且可以使用插件机制来扩展其功能。
  • 轻量高效:MyBatis占用资源少,运行速度快,并且可以与各种流行的数据库和缓存框架集成。

二、配置

要使用MyBatis,我们首先需要添加它的依赖到我们的项目中。如果我们使用Maven来管理项目,我们可以在pom.xml文件中添加如下代码:

<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.13</version>
</dependency>

然后,我们需要创建一个MyBatis的配置文件,通常命名为mybatis-config.xml。这个文件用于定义一些全局的属性和设置,例如数据源(DataSource),事务管理器(TransactionManager),日志实现(LogImpl)等。一个简单的配置文件示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="jdbc.properties"/><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><typeAliases><package name="com.example.domain"/></typeAliases><mappers><mapper class="com.example.mapper.UserMapper"/></mappers>
</configuration>

在上面的配置文件中,我们做了以下几件事:

  • 我们引入了一个外部的属性文件jdbc.properties,用于存储数据库连接相关的信息,如驱动类名(driverClassName),连接地址(url),用户名(username)和密码(password)等。
  • 我们设置了日志实现为STDOUT_LOGGING,表示将日志输出到标准输出流中。
  • 我们定义了一个类型别名(TypeAlias),表示将com.example.domain包下的所有类注册为别名,这样我们就可以在后面的映射文件中使用简短的类名,而不是完整的限定名。
  • 我们指定了一个映射器(Mapper),表示将com.example.mapper.UserMapper类作为一个映射器,用于定义SQL语句和结果映射等。

三、基于注解的基本使用

有了配置文件后,我们就可以开始使用MyBatis来操作数据库了。MyBatis的核心接口是SqlSession,它表示和数据库的一次会话,可以用来执行SQL语句,提交或回滚事务,获取映射器等。我们可以通过SqlSessionFactory来创建SqlSession,而SqlSessionFactory可以通过SqlSessionFactoryBuilder来构建,传入配置文件的输入流即可。以下是一个创建SqlSession的示例:

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.InputStream;public class MyBatisUtil {private static SqlSessionFactory sqlSessionFactory;static {try {// 读取配置文件InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");// 构建SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (Exception e) {e.printStackTrace();}}// 获取SqlSessionpublic static SqlSession getSqlSession() {return sqlSessionFactory.openSession();}
}

有了SqlSession后,我们就可以通过它来执行SQL语句了。MyBatis提供了两种方式来执行SQL语句:一种是通过XML映射文件来定义SQL语句和结果映射;另一种是通过注解来定义SQL语句和结果映射。我们以第二种方式为例,介绍如何使用MyBatis进行增删改查操作。

首先,我们需要定义一个实体类(Entity Class),用于表示数据库中的一张表。例如,我们有一张用户表(user),其结构如下:

idnameageemail
1Tom18tom@gmail.com
2Bob20bob@qq.com
3Alice19alice@163.com

我们可以定义一个User类来对应这张表,代码如下:

package com.example.domain;import java.io.Serializable;public class User implements Serializable {private Integer id;private String name;private Integer age;private String email;// 省略构造方法,getter和setter方法,toString方法
}

然后,我们需要定义一个持久层接口(DAO Interface),用于声明对User表的操作方法。在这个接口中,我们可以使用MyBatis提供的注解来编写SQL语句,并指定参数和返回值类型。例如,我们可以定义一个UserMapper接口,代码如下:

package com.example.mapper;import com.example.domain.User;
import org.apache.ibatis.annotations.*;import java.util.List;public interface UserMapper {// 查询所有用户@Select("select * from user")List<User> findAll();// 根据id查询用户@Select("select * from user where id = #{id}")User findById(Integer id);// 添加用户@Insert("insert into user (name, age, email) values (#{name}, #{age}, #{email})")void insert(User user);// 修改用户@Update("update user set name = #{name}, age = #{age}, email = #{email} where id = #{id}")void update(User user);// 删除用户@Delete("delete from user where id = #{id}")void delete(Integer id);}

在上面的代码中,我们使用了@Select, @Insert, @Update, @Delete四个注解来分别表示查询,插入,更新和删除操作。在注解中,我们可以直接写SQL语句,并且可以使用#{参数名}来表示占位符。MyBatis会自动将参数对象的属性值替换到占位符中,并且会根据返回值类型进行结果集的映射。

四、测试

最后,我们需要编写测试类(Test Class),用于调用UserMapper接口中的方法,并验证其功能。我们可以使用JUnit来编写测试类,代码如下:

package com.example.test;import com.example.domain.User;
import com.example.mapper.UserMapper;
import com.example.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.util.List;public class UserMapperTest {private SqlSession sqlSession;private UserMapper userMapper;@Beforepublic void init() {// 获取SqlSessionsqlSession = MyBatisUtil.getSqlSession();// 获取UserMapper接口的代理对象userMapper = sqlSession.getMapper(UserMapper.class);}@Afterpublic void destroy() {// 提交事务sqlSession.commit();// 关闭资源sqlSession.close();}// 测试查询所有用户@Testpublic void testFindAll() {// 调用findAll方法List<User> users = userMapper.findAll();// 遍历打印结果for (User user : users) {System.out.println(user);}}// 测试根据id查询用户@Testpublic void testFindById() {// 调用findById方法,传入id为1User user = userMapper.findById(1);// 打印结果System.out.println(user);}// 测试添加用户@Testpublic void testInsert() {// 创建一个User对象,设置其属性值User user = new User();user.setName("Jack");user.setAge(22);user.setEmail("jack@outlook.com");// 调用insert方法,传入user对象userMapper.insert(user);// 打印结果,可以看到id已经自动赋值System.out.println(user);}// 测试修改用户@Testpublic void testUpdate() {// 先根据id查询一个用户,得到一个User对象User user = userMapper.findById(2);// 修改该对象的属性值user.setName("Bobo");user.setAge(21);user.setEmail("bobo@qq.com");// 调用update方法,传入user对象userMapper.update(user);// 打印结果,可以看到属性值已经更新System.out.println(user);}// 测试删除用户@Testpublic void testDelete() {// 调用delete方法,传入id为3userMapper.delete(3);// 查询所有用户,可以看到id为3的用户已经删除testFindAll();}
}

在上面的代码中,我们使用了@Before和@After两个注解来分别在每个测试方法执行前后进行一些初始化和销毁的操作,例如获取SqlSession,提交事务,关闭资源等。然后,我们使用@Test注解来标记每个测试方法,并在方法体中调用UserMapper接口中的相应方法,并打印结果。运行测试类,我们可以看到控制台输出了正确的结果,说明我们的数据库操作成功了。

总结

本文介绍了MyBatis这个持久层框架的简介,配置和基于注解的基本使用。通过MyBatis,我们可以方便地执行SQL语句,并将结果集映射为Java对象。MyBatis还提供了许多高级特性,如动态SQL,缓存,插件等,使得数据库操作更加灵活和高效。

相关文章:

MyBatis:使用注解让数据库操作更简单

目录 一、简介 二、配置 三、基于注解的基本使用 四、测试 总结 一、简介 在Java开发中&#xff0c;数据库操作是一个常见而重要的任务。为了方便地执行SQL语句&#xff0c;获取结果集&#xff0c;处理异常等&#xff0c;我们通常需要使用JDBC&#xff08;Java Database …...

基于PyTorch深度学习遥感影像地物分类与目标检测、分割及遥感影像问题深度学习优化

我国高分辨率对地观测系统重大专项已全面启动&#xff0c;高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成&#xff0c;将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB&#xff0c;遥感大数据时…...

4.网络设计与redis、memcached、nginx组件(一)

网络组件系列文章目录 第四章 网络设计与redis、memcached、nginx组件 文章目录 网络组件系列文章目录文章的思维导图前言一、网络相关的问题&#xff0c;网络开发中要处理那些问题&#xff1f;网络操作IO连接建立连接断开消息到达消息发送网络操作IO特性 二、网络中IO检测IO函…...

leetcode分类刷题:矩阵顺时针模拟

1、这种题目是对代码熟练度考察&#xff0c;模拟顺时针建立或访问矩阵&#xff0c;需要注意矩阵是否为方阵 2、具体思路&#xff1a;以圈数为循环条件&#xff0c;每一圈都坚持左闭右开的区间规则&#xff1b;当小的行列值为奇数&#xff0c;最后一圈为一行或一列或一个数字的不…...

Java8新特性整理记录

1、list实体集合根据某个属性分组后求和 方法一&#xff1a; list.stream().collect(Collectors.groupingBy(e -> e.getId())).values().stream().map(d -> {DemoEntity sampleData d.get(0);sampleData.setPremium(d.stream().map(s -> new BigDecimal(s.getPrem…...

43.227.196.1 RAID技术有什么意义?

RAID&#xff08;Redundant Array of Inexpensive Disks&#xff09;技术是一种数据存储技术&#xff0c;它通过将多个硬盘组合在一起&#xff0c;来提高数据存储的性能、可靠性和容错性。 RAID技术的主要意义包括&#xff1a; 提高数据读写性能&#xff1a;RAID技术可以将多…...

c++ qt--信号与槽(一) (第三部分)

c qt–信号与槽(一) &#xff08;第三部分&#xff09; 一.用qt自带的方法添加信号槽 1.第一种 1.如何添加 2.在何处进行绑定 2.第二种 1.如何添加 2.在何处进行绑定 而且会在mainwindow.h中添加槽函数的声明&#xff0c;在mainwindow.cpp中添加槽函数的定义 在mainwindow…...

LLM学习《Prompt Engineering for Developer》

Prompt 如何构造好的Prompt 分割符&#xff1a;分隔符就像是 Prompt 中的墙&#xff0c;将不同的指令、上下文、输入隔开&#xff0c;避免意外的混淆。你可以选择用 &#xff0c;“”"&#xff0c;< >&#xff0c; &#xff0c;: 等做分隔符&#xff0c;只要能明确…...

nginx-获取客户端IP地址

上有服务器与客户端中间是有nginx代理服务器的&#xff0c;上游服务器如何获取客户端真实ip地址&#xff1f; nginx代理服务器设置X-Forwarded-For的header参数&#xff0c;代理服务器通过remote_addr获取客户端ip地址&#xff0c;将ip地址写入nginx代理服务器的X-Forwarded-Fo…...

Redis 高可用之集群搭建和数据分片

Redis 高可用之集群搭建和数据分片 一、简介1. Redis 集群&#xff1a;2. 集群搭建&#xff1a; 二、Redis 集群搭建1. 单机 Redis 升级为 Redis Clustera. 搭建方法b. 搭建方式说明 2. 环境准备3. 配置修改4. 启动集群 三、Redis数据分片的实现Redis数据分片概念说明数据分片的…...

兄弟,王者荣耀的段位排行榜是通过Redis实现的?

目录 一、排行榜设计方案1、数据库直接排序2、王者荣耀好友排行 二、Redis实现计数器1、什么是计数器功能&#xff1f;2、Redis实现计数器的原理&#xff08;1&#xff09;使用INCR命令实现计数器&#xff08;2&#xff09;使用INCRBY命令实现计数器 三、通过Redis实现“王者荣…...

Linux系统编程--文件编程--打开创建文件

创建文件需要包含以下3个头文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> 打开、创建文件有以下3个API open的返回值——文件描述符&#xff08;索引作用&#xff09;&#xff0c;是一个小的非负整数 int open(const char*pathn…...

http协议与apache

http概念&#xff1a; 互联网&#xff1a;是网络的网络&#xff0c;是所有类型网络的母集 因特网&#xff1a;世界上最大的互联网网络。即因特网概念从属于互联网概念 万维网&#xff1a;万维网并非某种特殊的计算机网络&#xff0c;是一个大规模的、联机式的信息贮藏库&…...

搜索二叉树的算法解析与实例演示

目录 一.搜索二叉树的特性与实现1.特点2.实现二.搜索二叉树的性能 一.搜索二叉树的特性与实现 1.特点 二叉搜索树是特殊的二叉树&#xff0c;它有着更严格的数据结构特点&#xff1a; &#xff08;1&#xff09;非空左子树的所有键值小于其根结点的键值。 &#xff08;2&…...

研磨设计模式day13组合模式

目录 场景 不用模式实现 代码实现 有何问题 解决方案 代码改造 组合模式优缺点 思考 何时选用 场景 不用模式实现 代码实现 叶子对象 package day14组合模式;/*** 叶子对象*/ public class Leaf {/*** 叶子对象的名字*/private String name "";/**…...

Linux命令(73)之zip

linux命令之zip 1.zip介绍 linux命令zip是用来压缩文件及解压缩文件名称后缀为".zip"的文件 2.zip用法 zip [参数] filename[.zip] zip常用参数 参数说明-r压缩递归处理-d从压缩文件内删除指定的文件-T检查备份文件是否正确无误-u更换较新的文件到压缩文件内-q不…...

深入理解Reactor模型的原理与应用

1、什么是Reactor模型 Reactor意思是“反应堆”&#xff0c;是一种事件驱动机制。 和普通函数调用的不同之处在于&#xff1a;应用程序不是主动的调用某个 API 完成处理&#xff0c;而是恰恰相反&#xff0c;Reactor逆置了事件处理流程&#xff0c;应用程序需要提供相应的接口并…...

微信小程序开发的投票评选系统设计与实现

摘要 越来越多信息化融入到我们生活当中的同时&#xff0c;也在改变着我们的生活和学习方式&#xff0c;当然&#xff0c;变化最明显的除了我们普通民众之外&#xff0c;要数高校学生的生活方式以及校园信息化的变革。智慧是改变生活和生产的一种来源&#xff0c;那么智慧的体…...

【校招VIP】算法考点之堆排

考点介绍&#xff1a; 排序算法属于数据结构和算法的基础内容&#xff0c;并且也是大厂笔试中的高频考点。 堆排序是使用一棵树存储序列这个课树只保证跟节点是这棵树中的最小值&#xff0c;但并不保证其他节点是按顺序的。因此他的排序是每次从堆中取得堆顶&#xff0c;取得 n…...

关于yarn安装时报“node“ is incompatible with this module的解决办法

前提&#xff1a; 在用vue写一个h5页面时&#xff0c;当在用yarn安装时&#xff0c;提示如下错误&#xff1a; The engine “node” is incompatible with this module. Expected version "^14.18.0 || ^16.14.0 || >18. 解决办法 我是使用命令忽略错误&#xff1a…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...