ORM、Mybatis和Hibernate、Mybatis使用教程、parameterType、resultType、级联查询案例、resultMap映射
DAY21.1 Java核心基础
ORM
Object Relationship Mapping 对象关系映射
面向对象的程序到—关系型数据库的映射
比如java – MySQL的映射
ORM框架就是实现这个映射的框架
Hibernate、Mybatis、MybatisPlus、Spring Data JPA、Spring JDBC
Spring Data JPA的底层就是Hibernate
Mybatis和Hibernate
Mybatis是一个JDBC封装的工具,是帮助开发者实现数据持久化 工作的框架
Mybatis和Hibernate的区别?
Mybatis:半自动框架,Mybatis没有实现java对象到数据库表的映射,只实现了java程序和sql之间的映射
Hibernate:全自动框架,开发者只需要调用接口就可以完成相关的操作,整个框架已经封装好,不需要开发者关注
但是全自动框架不灵活,有些业务场景实现并不方便,半自动框架灵活,可以根据具体业务来写sql,更适合现代企业级项目的开发
Mybatis的优缺点
优点:
- 极大简化了JDBC的开发
- 更好上手,有更好的灵活性
- 通过定义sql在xml文件里面降低程序的耦合度
- 支持动态sql,可以根据业务灵活实现需求
缺点:
- 数据库迁移的时候需要更改大量的sql语句
- 相较于Hibernate,需要完成更多的工作,定义sql,设置sql与数据库表的关系
使用教程
使用原生接口:
创建maven工程,导入相关依赖
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.31</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.8</version></dependency>
创建实体类User
@Data
public class User {private Integer id;private String name;private String pwd;private String email;
}
在resource创建一个config.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 配置MyBatis运行环境 --><environments default="development"><environment id="development"><!-- 配置JDBC事务管理 --><transactionManager type="JDBC"></transactionManager><!-- 数据源 --><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mytest1"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments>
</configuration>
两种使用方式:
-
使用原生接口
-
使用mapper代理
使用原生接口
创建mapper文件
namespace:通常设置为文件所在包名和文件
UserMapper.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.shuwu.mapper.UserMapper"><select id="get" parameterType="int" resultType="com.shuwu.entity.User">select * from user where id = #{id}</select>
</mapper>
在配置文件添加注册mapper,让配置文件可以扫描到
<mappers><mapper resource="com/shuwu/mapper/UserMapper.xml"></mapper>
</mappers>
测试用例:
public class Test {public static void main(String[] args) {// 找到类加载器,通过配置文件的输入流然后创建一个SqlSession工厂InputStream resourceAsStream = Test.class.getClassLoader().getResourceAsStream("com/mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);// 获取sqlsessionSqlSession sqlSession = build.openSession();// 调用Mybatis原生接口执行sqlString statement = "com.shuwu.mapper.UserMapper.get";User user = sqlSession.selectOne(statement, 1);System.out.println(user);}
}
测试结果:

要确保数据库里面有对应的表结构
1、通过配置文件创建 MyBatis 环境(数据源、Mapper)
2、构建环境需要使用 SqlSessionFactory
使用mapper代理实现自定义接口
自定义接口,开发者只需要定义,不需要实现
定义mapper接口
public interface UserMapper {public User getUserById(Integer id);public List<User> getAllUser();
}
mapper接口映射的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.shuwu.mapper.UserMapper"><select id="getUserById" resultType="com.shuwu.entity.User">select * from user where id = #{id}</select><select id="getAllUser" resultType="com.shuwu.entity.User">select * from user</select>
</mapper>
要注意!!
- namespace需要指定到mapper接口的文件
- 方法名和xml里面的id必须一致
- 返回值的resultType的放回类型必须一致
- 方法传递参数名字必须对应,如果不一致可以用@Param来声明参数名字
比如:
public User getUserById(@Param("id") Integer id2);
增加、删除、修改用户
<?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.shuwu.mapper.UserMapper"><insert id="addUser">insert into user(name,pwd,email) values(#{name},#{pwd},#{email})</insert><update id="updateUser" parameterType="com.shuwu.entity.User">update user set name=#{name},pwd=#{pwd},email=#{email} where id = #{id}</update><delete id="deleteUser" parameterType="integer">delete from user where id = #{id}</delete><select id="getUserById" resultType="com.shuwu.entity.User">select * from user where id = #{id}</select><select id="getAllUser" resultType="com.shuwu.entity.User">select * from user</select>
</mapper>
public interface UserMapper {public User getUserById(@Param("id") Integer id2);public List<User> getAllUser();public int addUser(User user);public int deleteUser(@Param("id") Integer id);
}
public static void main(String[] args) {// 找到类加载器,然后创建一个工厂InputStream resourceAsStream = Test.class.getClassLoader().getResourceAsStream("com/mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);// 获取sqlsessionSqlSession sqlSession = build.openSession();// 获取接口的代理对象UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 添加用户mapper.addUser(new User(null,"shuwu","123","123@qq.com"));// 根据id删除用户mapper.deleteUser(4);// 根据User的id修改用户信息mapper.updateUser(new User(1,"shuwu","123","123@qq.com"));// 提交事务sqlSession.commit();
}
增删改 数据库的时候要注意需要提交事务,不然MySQL只会保存不会添加进数据库
sqlSession.commit();
Mapperxml
全局配置文件 mybatis-config.xml
Mapper 配置文件 UserMapper.xml
mybatis-config.xml:主要用来定义数据源信息和一些基本配置,事务管理、打印 SQL,开启二级缓存、设置延迟加载
UserMapper.xml:定义对应接口方法的 SQL 实现,需要在 mybatis-config.xml 中进行注册才可以使用
半自动化的 ORM 框架,SQL 需要开发者自定义,MyBatis 关注的是 Java 对象和 SQL 之间的关系,SQL 语句是在 Mapper.xml 中定义
parameterType
参数数据类型介绍
包装类型
Integer类型
public int deleteUser(@Param("id") Integer id);
<delete id="deleteUser" parameterType="integer">delete from user where id = #{id}
</delete>
用户的SQL语句是where id = #{id},这里的id可能是int或Integer。如果调用这个方法时传入的是单个参数,比如Integer,MyBatis会自动识别参数类型,不需要显式指定parameterType。
String类型
public User getByUserName(@Param("name") String name);
<select id="getByUserName" resultType="com.shuwu.entity.User">select * from user where name=#{name}
</select>
基本数据类型
int、flout、double…
public User getByAge(int age);
<select id="getByAge" parameterType="int" resultType="com.southwind.entity.User">select * from user where age = #{age}
</select>
实体类
public List<User> getAllUser();
<select id="getAllUser" resultType="com.shuwu.entity.User">select * from user
</select>
5、多个参数
public User getUsernameAndAge(String username,Integer age);
<select id="getUsernameAndAge" resultType="com.southwind.entity.User">select * from user where username = #{param1} and age = #{param2}
</select>
resultType
返回类型
1、基本数据类型
public int getCount();
<select id="getCount" resultType="int">select count(*) from user
</select>
2、包装类
public Integer getCount2();
<select id="getCount2" resultType="java.lang.Integer">select count(*) from user
</select>
3、String
public String getUsernameById(Integer id);
<select id="getUsernameById" parameterType="java.lang.Integer" resultType="java.lang.String">select username from user where id = #{id}
</select>
4、实体类
public User getById(Integer id);
<select id="getById" parameterType="java.lang.Integer" resultType="com.southwind.entity.User">select * from user where id = #{id}
</select>
级联查询
实际开发中常见的是一对多和多对多关系
如果要查询学生信息和班级信息的关系呢?
SELECT student.id sid, student.`name` sname,class.id cid,class.`name` cname from student,class where student.cid = class.id
怎么在java程序中实现呢
先定义一个可以接收这个参数的student对象
@Data
public class Student {private Integer id;private String name;private Class clazz;
}
@Data
public class Class {private Integer id;private String name;
}
但是有时候这个字段和数据库里面的字段不匹配怎么办呢?
这个clazz怎么和数据库对应呢?
这个时候就需要写一个字段映射了
mapper接口
public List<Student> getAllStudent();
xml映射
通过使用 resultMap="StudentMap"来设置一个返回值的字段映射
<resultMap id="StudentMap" type="com.shuwu.entity.Student"><id property="id" column="sid"/><result property="name" column="sname"/><association property="clazz" javaType="com.shuwu.entity.Class"><id property="id" column="cid"/><result property="name" column="cname"/></association></resultMap><select id="getAllStudent" resultType="com.shuwu.entity.Student" resultMap="StudentMap">SELECT student.id sid, student.`name` sname,class.id cid,class.`name` cname from student,class where student.cid = class.id
</select>
测试输入:
System.out.println(mapper.getAllStudent());

相关文章:
ORM、Mybatis和Hibernate、Mybatis使用教程、parameterType、resultType、级联查询案例、resultMap映射
DAY21.1 Java核心基础 ORM Object Relationship Mapping 对象关系映射 面向对象的程序到—关系型数据库的映射 比如java – MySQL的映射 ORM框架就是实现这个映射的框架 Hibernate、Mybatis、MybatisPlus、Spring Data JPA、Spring JDBC Spring Data JPA的底层就是Hiber…...
简历EasyExcel相关
系列博客目录 文章目录 系列博客目录1.在easyExcel的基础上,应用多线程对数据进行分块有用吗为什么使用多线程对数据进行分块有用?实现方式示例:多线程与 EasyExcel 导出结合的基本思路解释:注意事项:总结:…...
C#调用Lua方法1+C#调用Lua方法2,3
xLua中Lua调用C#代码 原因:C#实现的系统,因为Lua可以调用,所以完全可以换成Lua实现,因为Lua可以即时更改,即时运行,所以游戏的代码逻辑就可以随时更改。 实现和C#相同效果的系统,如何实现&#…...
stable diffusion 量化加速点
文章目录 一、导出为dynamic shape1)函数讲解(函数导出、输出检查)2)代码展示二、导出为static shape1)函数讲解(略)2)代码展示三、序列化为FP32测速1)测速2)代码四、序列化为FP16测速1)测速2)代码同上五、发现并解决解决CLIP FP16溢出,并测速1)如何找到溢出的算子…...
NO.77十六届蓝桥杯备战|数据结构-单调队列|质量检测(C++)
什么是单调队列? 单调队列,顾名思义,就是存储的元素要么单调递增要么单调递减的队列。注意,这⾥的队列和普通的队列不⼀样,是⼀个双端队列。单调队列解决的问题 ⼀般⽤于解决滑动窗⼝内最⼤值最⼩值问题,以…...
通过发票四要素信息核验增值税发票真伪-iOS发票查验接口
发票是企业经济间往来的重要凭证,现如今,随着经济环境的日益复杂,发票造假现象屡禁不止,这使得增值税发票查验成为企业必须高度重视的工作。人工智能时代,发票查验接口犹如一道坚固的防线,助力企业财务守护…...
区块链是怎么存储块怎么找到前一个块
前言:学习区块链的过程中在想怎么管理区块链呢 📌 推荐项目回顾: 👉 Jeiwan 的 blockchain_go 项目 GitHub 地址:https://github.com/Jeiwan/blockchain_go ❓它是怎么存储区块 & 找前一个区块的? 项…...
超详解glusterfs部署
glusterfs部署 GlusterFS 是一个开源的分布式文件系统,旨在提供高性能、高可用性和可扩展性,适用于存储大量数据。它通过将多个存储节点组合成一个统一的文件系统,允许用户透明地访问分布在不同节点上的数据。 主要组件 存储砖块ÿ…...
总结一下常见的EasyExcel面试题
说一下你了解的POI和EasyExcel POI(Poor Obfuscation Implementation):它是 Apache 软件基金会的一个开源项目,为 Java 程序提供了读写 Microsoft Office 格式文件的功能,支持如 Excel、Word、PowerPoint 等多种文件格…...
【JAVA】十、基础知识“类和对象”干货分享~(三)
目录 1. 封装 1.1 封装的概念 1.2 访问限定符 public(公开访问) private(私有访问) 1.3 包 1.3.1 包的概念 1.3.2 导入包中的类 1.3.3 自定义包 2. static成员 2.1 static变量(类变量) 2.1.1 sta…...
DeepSeek+SpringAI家庭AI医生
文章目录 项目架构项目开发内容项目用户用例图项目地址开发环境大模型使用本地:Ollama部署DeepSeek离线与在线api大模型客户端使用 数据库脚本代码deepseek创建定制医生模型 内网互通原则云服务器类型 项目架构 项目开发内容 项目用户用例图 项目地址 FamilyAIDoct…...
PyTorch:解锁AI新时代的钥匙
(前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站)。 揭开PyTorch面纱 对于许多刚开始接触人工智能领域的朋友来说,PyTorch这个名字或许既熟悉又陌生。…...
C++第14届蓝桥杯b组学习笔记
1. 日期统计 小蓝现在有一个长度为 100100 的数组,数组中的每个元素的值都在 00 到 99 的范围之内。数组中的元素从左至右如下所示: 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4…...
解锁工业通信:Profibus DP到ModbusTCP网关指南!
解锁工业通信:Profibus DP到ModbusTCP网关指南! 在工业自动化领域,随着技术的不断进步和应用场景的日益复杂,不同设备和系统之间的通讯协议兼容性问题成为了工程师们面临的一大挑战。尤其是在Profibus DP和Modbus/TCP这两种广泛应…...
每日一题(小白)字符串娱乐篇16
分析题意可以了解到本题要求在一串字符串中找到所有组合起来排序递增的字符串。我们可以默认所有字符在字符串中的上升序列是1,从第一个字符开始找,如果后面的字符大于前面的字符就说明这是一个上序列那么后面字符所在的数组加一,如果连接不上…...
面试算法高频01
题目描述 验证回文串 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 示例 1: 输入: "A man, a plan, a canal: Panama" 输出: true示例 2: 输入: "race a car" 输出: falseimport…...
如何深刻理解Reactor和Proactor
前言: 网络框架的设计离不开 I/O 线程模型,线程模型的优劣直接决定了系统的吞吐量、可扩展性、安全性等。目前主流的网络框架,在网络 IO 处理层面几乎都采用了I/O 多路复用方案(又以epoll为主),这是服务端应对高并发的性能利器。 …...
java基础 数组Array的介绍
Array 数组定义一维数组多维数组动态数组常见方法Arrays排序1.sort() 排序 2.parallelSort() 排序 查找:binarySearch()填充:fill()比较:equals() 和 deepEquals()复制:copyOf() 和 copyOfRange()转换为列表:asList()转…...
Elixir语言的函数定义
Elixir语言的函数定义 Elixir是一种基于Erlang虚拟机(BEAM)的函数式编程语言,因其并发特性及可扩展性而受到广泛欢迎。在Elixir中,函数是程序的基本构建块,了解如何定义和使用函数对于掌握这门语言至关重要。本文将深…...
我的NISP二级之路-02
目录 一.数据库 二.TCP/IP协议 分层结构 三.STRIDE模型 四.检查评估与自评估 检查评估 自评估 五.信息安全应急响应过程 六.系统工程 七.SSE-CMM 八.CC标准 九.九项重点工作 记背: 一.数据库 关于数据库恢复技术,下列说法不正确的是:…...
k8s1.24升级1.28
0、简介 这里只用3台服务器来做一个简单的集群,当前版本是1.24.17目标升级到1.28.17 地址主机名192.168.160.40kuber-master-1192.168.160.41kuber-master-2192.168.160.42kuber-node-1 因为1.24已经更换过了容器运行时,所以之后的升级相对就会简单&am…...
常见的微信个人号二次开发功能
一、常见开发功能 1. 好友管理 好友列表维护 添加/删除好友 修改好友信息(备注、标签等) 分组管理 创建/编辑/删除标签 好友分类与筛选 2. 消息管理 信息发送 支持多类型内容:文本、图片、视频、文件、小程序、名片、URL链接等 附加功…...
unity的dots中instantiate克隆对象后,对象会在原位置闪现的原因和解决
原因 在Entity中有两个位置信息,一个是local transform。一个是local to world 其中local transform负责具体位置,local to world 负责渲染位置,即图像的渲染的位置是根据local to world的。 local to world 的更新是引擎自己控制的&#x…...
去中心化固定利率协议
核心机制与分类 协议类型: 借贷协议(如Yield、Notional):通过零息债券模型(如fyDai、fCash)锁定固定利率。 收益聚合器(如Saffron、BarnBridge):通过风险分级或博弈论…...
Java面试黄金宝典31
1. 什么是封锁协议 定义:封锁协议是在运用封锁机制时,为了保证事务的一致性和隔离性,对何时申请封锁、持锁时间以及何时释放封锁等问题制定的规则。它可防止并发操作引发的数据不一致问题,如丢失修改、不可重复读和读 “脏” 数据…...
R语言——绘制生命曲线图(细胞因子IL5)
绘制生命曲线图(根据细胞因子) 说明流程代码加载包读取Excel文件清理数据重命名列名处理IL-5中的"<"符号 - 替换为检测下限的一半首先找出所有包含"<"的值检查缺失移除缺失值根据IL-5中位数将患者分为高低两组 创建生存对象拟…...
在内网环境中为 Gogs 配置 HTTPS 访问
在内网环境中为 Gogs 配置 HTTPS 访问,虽然不需要公网域名,但仍需通过自签名证书或私有证书实现加密。以下是详细步骤和方案: 一、核心方案选择 方案适用场景优点缺点自签名证书快速测试、临时使用无需域名,快速生成浏览器提示“…...
神马系统8.5搭建过程,附源码数据库
项目介绍 神马系统是多年来流行的一款电视端应用,历经多年的发展,在稳定性和易用性方面都比较友好。 十多年前当家里的第一台智能电视买回家,就泡在某论坛,找了很多APP安装在电视上,其中这个神马系统就是用得很久的一…...
大模型论文:Improving Language Understanding by Generative Pre-Training
大模型论文:Improving Language Understanding by Generative Pre-Training OpenAI2018 文章地址:https://www.mikecaptain.com/resources/pdf/GPT-1.pdf 摘要 自然语言理解包括各种各样的任务,如文本蕴涵、问题回答、语义相似性评估和文…...
SDL视频显示函数
文章目录 1. **`SDL_Init()`**2. **`SDL_CreateWindow()`**3. **`SDL_CreateRenderer()`**4. **`SDL_CreateTexture()`**5. **`SDL_UpdateTexture()`**6. **`SDL_RenderCopy()`**7. **`SDL_RenderPresent()`**8. **`SDL_Delay()`**9. **`SDL_Quit()`**总结示例代码:代码说明:…...
