MyBatis最佳实践:提升数据库交互效率的秘密武器
第一章:框架的概述:
-
MyBatis 框架的概述:
- MyBatis 是一个优秀的基于 Java 的持久框架,内部对 JDBC 做了封装,使开发者只需要关注 SQL 语句,而不关注 JDBC 的代码,使开发变得更加的简单
- MyBatis 通过 XML 或者注解的方式将要执行的各种 Statement 对象配置起来,通过 Java 对象和 statement 中 SQL 后,最终将结果已 Java 对象返回
- MyBatis 采用了 ORM 的思想
-
ORM 思想:
- 在 web 阶段学习 JavaBean 更正确的叫法是:实体类
- ORM:object relational mapping 对象映射关系
- O:面向对象领域的 Object(JavaBean 对象)
- R:关系数据库领域的 Relational(表的结构)
- M:映射 Mapping(XML 的配置文件)、
- 让实体类和数据库表进行 一 一 对应关系
- 先让实体类和数据库表对应
- 再让实体类属性和表里面字段对应
- 不需要直接操作数据库表,直接操作表对应的实体类对象即可
-
推荐插件:

第二章:MyBatis 的入门程序(重点)
- 创建数据库和表结构:
create database mybatis_demo; use mybatis_demo; CREATE TABLE `user` (`id` int(11) NOT NULL auto_increment,`username` varchar(32) NOT NULL COMMENT '用户名称',`birthday` datetime default NULL COMMENT '生日',`sex` char(1) default NULL COMMENT '性别',`address` varchar(256) default NULL COMMENT '地址',PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'老王','2018-02-27 17:47:08','男','北京'), (2,'熊大','2018-03-02 15:09:37','女','上海'), (3,'熊二','2018-03-04 11:34:34','女','深圳'), (4,'光头强','2018-03-04 12:04:06','男','广州'); -
MyBatis 的入门程序:
- 创建 maven 项目,Java 工程即可
- 引入坐标:
- 引入 MyBatis 的 3.4.5 的版本的坐标
- 引入 MySQL 驱动的 jar 包,5.1.6 版本
- 引入 Junit 单元测试的 jar 包
- 引入 log4h 的 jar 包,1.2.12 版本(需要引入log4j.propertiees 的配置文件)
<dependencies><!--mybatis核心包--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!--mysql驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!-- 单元测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency><!-- 日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency> </dependencies>
- 编写 User 的实现类,属性尽量使用包装类型:
public class User implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';} } - 编写 UserMapper 的接口和方法(即 Spring 框架中 UserDao 接口):
public interface UserMapper {public List<User> selectAll; } - 在 resources 目录下,创建 mapper 文件夹。编写 Usermapper.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.qcby.mapper.UserMapper"><select id="findAll" resultType="com.qcby.model.User">select * from user;</select> </mapper>- mapper namespace="com.qcby.mapper.UserMapper":叫名称空间,表明以后查找 UserMapper 接口中的 findAll 方法
- select id = "findAll" 中的 id 属性编写的 UserMapper 接口中方法的名称,固定写法
- resultType = "com.qcby.model.User":表明的是 findAll 方法的返回值类型
- 编写配置文件,在 resources 目录下创建 SqlMapConfig.xml 的配置文件(名称可以任意),导入对应的约束,编写主配置文件
<?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><!-- 配置具体的环境 --><environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"></transactionManager><!-- 配置是否需要使用连接池, POOLED 使用,UNPOOLED 不适用--><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis_demo"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><!-- 加载映射的配置文件 --><mappers><mapper resource="Mapper/UserMapper.xml"/></mappers></configuration> - 编写入门程序(重点掌握入门的步骤):
import com.qcby.mapper.UserMapper; import com.qcby.model.User; 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 org.junit.Test;import java.io.IOException; import java.io.InputStream; import java.util.List;public class MyBatisDemo {@Testpublic void run() throws Exception {//加载主配置文件,目的是构建 SqlSessionFactory 的对象InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");//创建 SqlSSessionFactory 对象SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);//使用 SqlSessionFactory 工厂对象创建 SqlSession 对象SqlSession session = factory.openSession();//通过 session 创建 UserMapper 接口的代理对象UserMapper mapper = session.getMapper(UserMapper.class);//调用 findAll 方法List<User> list = mapper.findAll();//遍历集合并输出for (User u : list){System.out.println(u);}//释放资源session.close();in.close();} }
第三章:代理 Dao 方式的 CURD 操作
-
Dao 方式的增删改查:
- 创建项目
- 注意:除了查询方法之外,其他增删改操作需要进行 session.commit 提交
- UserMapper 接口代码:
public interface UserMapper {public List<User> findAll();//根据 id 查询public User findById(Integer id);// 插入public void insert(User user);//修改public void update(User user);//删除public void delete(int id);//根据姓名模糊查询public List<User> findByName(String username);//查询总数public Integer findByCount(); } - UserMapper.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.qcby.mapper.UserMapper"><!--保存操作--><insert id="insert" parameterType="com.qcby.model.User">/*keyProperty表示要返回的属性名称order取值AFTER表示插入数据后的行为resultType表示返回值的类型*/<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">select last_insert_id();</selectKey>insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})</insert><!-- 修改 --><update id="update" parameterType="com.qcby.model.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}</update><!-- 根据 id 删除 --><delete id="delete" parameterType="integer">delete from user where id = #{id}</delete><!-- 查询所有 --><select id="findAll" resultType="com.qcby.model.User" >select * from user;</select><!-- 根据 id 查询 --><select id="findById" resultType="com.qcby.model.User">select * from user where id=#{id};</select><!-- 根据姓名模糊查询--><select id="findByName" parameterType="string" resultType="com.qcby.model.User">/**第一种方式的 SQL 语句*/ -- select * from user where username like #{username}/**第二种 SQL 语句的编写,强调: '%${value}%' 不能修改,固定写法(推荐使用)注意:使用第二种 SQL 写法时需要把 SQL 中的注释全部删除否则会报错*/select * from user where username like %${value}%</select><!-- 查询总数量 --><select id="findByCount" resultType="java.lang.Integer">select count(*) from user;</select></mapper> - 测试代码:
public class MyBatisDemo {private InputStream in;private SqlSession session;private UserMapper userMapper;@Beforepublic void init() throws IOException {//加载配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//创建工厂对象SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);//创建 Session 对象session = factory.openSession();//获取到代理对象userMapper = session.getMapper(UserMapper.class);}@Afterpublic void dstory() throws IOException {in.close();session.close();}//查询所有@Testpublic void fundAll() throws IOException {List<User> users = userMapper.findAll();for (User u : users){System.out.println(u);}in.close();}//根据 id 查询@Testpublic void findById() throws IOException {User user = userMapper.findById(1);System.out.println(user);in.close();}//插入方法@Testpublic void insert() throws IOException {User user = new User();user.setAddress("河北");user.setBirthday(new Date());user.setSex("男");user.setUsername("张翰里");System.out.println(user);userMapper.insert(user);session.commit();in.close();}//修改方法@Testpublic void updage() throws IOException {User user = new User();user.setId(1);user.setAddress("河北");user.setBirthday(new Date());user.setSex("男");user.setUsername("张翰里");userMapper.update(user);session.commit();in.close();}//删除方法@Testpublic void delete() throws IOException {userMapper.delete(2);session.commit();in.close();}//模糊查询@Testpublic void findByName() throws IOException {List<User> list = userMapper.findByName("%张%");for(User u : list){System.out.println(u);}in.close();}//查询总量@Testpublic void findCount(){System.out.println(userMapper.findByCount());} }
相关文章:
MyBatis最佳实践:提升数据库交互效率的秘密武器
第一章:框架的概述: MyBatis 框架的概述: MyBatis 是一个优秀的基于 Java 的持久框架,内部对 JDBC 做了封装,使开发者只需要关注 SQL 语句,而不关注 JDBC 的代码,使开发变得更加的简单MyBatis 通…...
选择困难?直接生成pynput快捷键字符串
from pynput import keyboard# 文档:https://pynput.readthedocs.io/en/latest/keyboard.html#monitoring-the-keyboard # 博客(pynput相关源码):https://blog.csdn.net/qq_39124701/article/details/145230331 # 虚拟键码(十六进制):https:/…...
DeepSeek-R1:强化学习驱动的推理模型
1月20日晚,DeepSeek正式发布了全新的推理模型DeepSeek-R1,引起了人工智能领域的广泛关注。该模型在数学、代码生成等高复杂度任务上表现出色,性能对标OpenAI的o1正式版。同时,DeepSeek宣布将DeepSeek-R1以及相关技术报告全面开源。…...
国内优秀的FPGA设计公司主要分布在哪些城市?
近年来,国内FPGA行业发展迅速,随着5G通信、人工智能、大数据等新兴技术的崛起,FPGA设计企业的需求也迎来了爆发式增长。很多技术人才在求职时都会考虑城市的行业分布和发展潜力。因此,国内优秀的FPGA设计公司主要分布在哪些城市&a…...
3.日常英语笔记
screening discrepancies 筛选差异 The team found some screening discrepancies in the data. 团队在数据筛选中发现了些差异。 Don’t tug at it ,or it will fall over and crush you. tug 拉,拽,拖 He tugged the door open with all his might…...
基于RIP的MGRE实验
实验拓扑 实验要求 按照图示配置IP地址配置静态路由协议,搞通公网配置MGRE VPNNHRP的配置配置RIP路由协议来传递两端私网路由测试全网通 实验配置 1、配置IP地址 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 15.0.0.1 24 [R1]int LoopBack 0 [R1-LoopBack0]i…...
【开源免费】基于Vue和SpringBoot的美食推荐商城(附论文)
本文项目编号 T 166 ,文末自助获取源码 \color{red}{T166,文末自助获取源码} T166,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...
Pandas DataFrame 拼接、合并和关联
拼接:使用 pd.concat(),可以沿着行或列方向拼接 DataFrame。 合并:使用 pd.merge(),可以根据一个或多个键进行不同类型的合并(左连接、右连接、全连接、内连接)。 关联:使用 join() 方法,通常在设置了索引的 DataFrame 上进行关联操作。 concat拼接 按列拼接 df1 = …...
【Redis】Redis修改连接数参数
1.重启操作背景 Redis数据库连接数上限,需要修改配置文件里maxclients参数,修改后需重启数据库 1.1、修改操作系统open files参数 1.2、修改redis连接数 2.登录操作系统 登录堡垒机 ssh {ip}3.查看当前状态 3.1、查看操作系统配置 ulimit -a3.2、…...
scratch变魔术 2024年12月scratch三级真题 中国电子学会 图形化编程 scratch三级真题和答案解析
目录 scratch变魔术 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、 推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、py…...
51单片机开发:点阵屏显示数字
实验目标:在8x8的点阵屏上显示数字0。 点阵屏的原理图如下图所示,点阵屏的列接在P0端口,行接在74HC595扩展的DP端口上。 扩展口的使用详见:51单片机开发:IO扩展(串转并)实验-CSDN博客 要让点阵屏显示数字࿰…...
mysql DDL可重入讨论
mysql的bug:当执行 MySQL online DDL 时,期间如有其他并发的 DML 对相同的表进行增量修改,比如 update、insert、insert into … on duplicate key、replace into 等,且增量修改的数据违背唯一约束,那么 DDL 最后都会执…...
DAY01 面向对象回顾、继承、抽象类
学习目标 能够写出类的继承格式public class 子类 extends 父类{}public class Cat extends Animal{} 能够说出继承的特点子类继承父类,就会自动拥有父类非私有的成员 能够说出子类调用父类的成员特点1.子类有使用子类自己的2.子类没有使用,继承自父类的3.子类父类都没有编译报…...
127周一复盘 (165)玩法与难度思考
1.上午测试,小改了点东西, 基本等于啥也没干。 匆忙赶往车站。 从此进入春节期间,没有开发,而思考与设计。 2.火车上思考玩法与难度的问题。 目前的主流作法实际上并不完全符合不同玩家的需求, 对这方面还是要有自…...
【C语言常见概念详解】
目录 -----------------------------------------begin------------------------------------- 什么是C语言: 1. 基本数据类型 2. 变量与常量 3. 运算符与表达式 4. 控制结构 5. 函数 6. 指针 7. 数组与字符串 8. 结构体与联合体 9. 文件操作 结语 ----…...
弹性分组环——RPR技术
高频考点,考查20次: RPR与FDDI一样使用双环结构RPR环中的每一个节点都会执行SRP公平算法(非DPT、MPLS)传统的FDDI环,当源节点成功向目的结点发送一个数据帧后,这个数据帧由源结点从环中回收。但RPR环&#…...
定制Centos镜像
环境准备: 一台最小化安装的干净的系统,这里使用Centos7.9,一个Centos镜像,镜像也使用Centos7.9的。 [rootlocalhost ~]# cat /etc/system-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]# rpm -qa | wc -l 306 [rootloca…...
Java---判断素数的三种方法
我们首先先来了解一下什么是素数 素数:一个整数只能被1和自身整除 , 注意:0与1不是素数 目录 方法一:暴力法 方法二:除二法(优化) 方法三.根号法(最优法) 方法一:暴力法 最简单最暴力的方法就是根据定义,判断n是不是素数,让n除以2到n-1的所有数,只要遇到能除开…...
多级缓存(亿级并发解决方案)
多级缓存(亿级流量(并发)的缓存方案) 传统缓存的问题 传统缓存是请求到达tomcat后,先查询redis,如果未命中则查询数据库,问题如下: (1)请求要经过tomcat处…...
代理模式 - 代理模式的应用
引言 代理模式(Proxy Pattern)是一种结构型设计模式,它允许你提供一个代理对象来控制对另一个对象的访问。代理对象通常会在客户端和目标对象之间起到中介的作用,从而可以在不改变目标对象的情况下,增加额外的功能或控…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
