ORM、Mybatis和Hibernate、Mybatis使用教程、parameterType、resultType、级联查询案例、resultMap映射

news2025/4/14 13:51:37

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);
        // 获取sqlsession
        SqlSession sqlSession = build.openSession();
        // 调用Mybatis原生接口执行sql
        String statement = "com.shuwu.mapper.UserMapper.get";
        User user = sqlSession.selectOne(statement, 1);
        System.out.println(user);
    }
}

测试结果:

image-20250407105705462

要确保数据库里面有对应的表结构

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);
    // 获取sqlsession
    SqlSession 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());

image-20250407225235917

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

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

相关文章

C#调用Lua方法1+C#调用Lua方法2,3

xLua中Lua调用C#代码 原因&#xff1a;C#实现的系统&#xff0c;因为Lua可以调用&#xff0c;所以完全可以换成Lua实现&#xff0c;因为Lua可以即时更改&#xff0c;即时运行&#xff0c;所以游戏的代码逻辑就可以随时更改。 实现和C#相同效果的系统&#xff0c;如何实现&#…

NO.77十六届蓝桥杯备战|数据结构-单调队列|质量检测(C++)

什么是单调队列&#xff1f; 单调队列&#xff0c;顾名思义&#xff0c;就是存储的元素要么单调递增要么单调递减的队列。注意&#xff0c;这⾥的队列和普通的队列不⼀样&#xff0c;是⼀个双端队列。单调队列解决的问题 ⼀般⽤于解决滑动窗⼝内最⼤值最⼩值问题&#xff0c;以…

通过发票四要素信息核验增值税发票真伪-iOS发票查验接口

发票是企业经济间往来的重要凭证&#xff0c;现如今&#xff0c;随着经济环境的日益复杂&#xff0c;发票造假现象屡禁不止&#xff0c;这使得增值税发票查验成为企业必须高度重视的工作。人工智能时代&#xff0c;发票查验接口犹如一道坚固的防线&#xff0c;助力企业财务守护…

【JAVA】十、基础知识“类和对象”干货分享~(三)

目录 1. 封装 1.1 封装的概念 1.2 访问限定符 public&#xff08;公开访问&#xff09; private&#xff08;私有访问&#xff09; 1.3 包 1.3.1 包的概念 1.3.2 导入包中的类 1.3.3 自定义包 2. static成员 2.1 static变量&#xff08;类变量&#xff09; 2.1.1 sta…

DeepSeek+SpringAI家庭AI医生

文章目录 项目架构项目开发内容项目用户用例图项目地址开发环境大模型使用本地&#xff1a;Ollama部署DeepSeek离线与在线api大模型客户端使用 数据库脚本代码deepseek创建定制医生模型 内网互通原则云服务器类型 项目架构 项目开发内容 项目用户用例图 项目地址 FamilyAIDoct…

PyTorch:解锁AI新时代的钥匙

&#xff08;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff09;。 揭开PyTorch面纱 对于许多刚开始接触人工智能领域的朋友来说&#xff0c;PyTorch这个名字或许既熟悉又陌生。…

C++第14届蓝桥杯b组学习笔记

1. 日期统计 小蓝现在有一个长度为 100100 的数组&#xff0c;数组中的每个元素的值都在 00 到 99 的范围之内。数组中的元素从左至右如下所示&#xff1a; 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网关指南!

解锁工业通信&#xff1a;Profibus DP到ModbusTCP网关指南&#xff01; 在工业自动化领域&#xff0c;随着技术的不断进步和应用场景的日益复杂&#xff0c;不同设备和系统之间的通讯协议兼容性问题成为了工程师们面临的一大挑战。尤其是在Profibus DP和Modbus/TCP这两种广泛应…

每日一题(小白)字符串娱乐篇16

分析题意可以了解到本题要求在一串字符串中找到所有组合起来排序递增的字符串。我们可以默认所有字符在字符串中的上升序列是1&#xff0c;从第一个字符开始找&#xff0c;如果后面的字符大于前面的字符就说明这是一个上序列那么后面字符所在的数组加一&#xff0c;如果连接不上…

如何深刻理解Reactor和Proactor

前言&#xff1a; 网络框架的设计离不开 I/O 线程模型&#xff0c;线程模型的优劣直接决定了系统的吞吐量、可扩展性、安全性等。目前主流的网络框架&#xff0c;在网络 IO 处理层面几乎都采用了I/O 多路复用方案(又以epoll为主)&#xff0c;这是服务端应对高并发的性能利器。 …

java基础 数组Array的介绍

Array 数组定义一维数组多维数组动态数组常见方法Arrays排序1.sort() 排序 2.parallelSort() 排序 查找&#xff1a;binarySearch()填充&#xff1a;fill()比较&#xff1a;equals() 和 deepEquals()复制&#xff1a;copyOf() 和 copyOfRange()转换为列表&#xff1a;asList()转…

我的NISP二级之路-02

目录 一.数据库 二.TCP/IP协议 分层结构 三.STRIDE模型 四.检查评估与自评估 检查评估 自评估 五.信息安全应急响应过程 六.系统工程 七.SSE-CMM 八.CC标准 九.九项重点工作 记背: 一.数据库 关于数据库恢复技术&#xff0c;下列说法不正确的是&#xff1a…

常见的微信个人号二次开发功能

一、常见开发功能 1. 好友管理 好友列表维护 添加/删除好友 修改好友信息&#xff08;备注、标签等&#xff09; 分组管理 创建/编辑/删除标签 好友分类与筛选 2. 消息管理 信息发送 支持多类型内容&#xff1a;文本、图片、视频、文件、小程序、名片、URL链接等 附加功…

unity的dots中instantiate克隆对象后,对象会在原位置闪现的原因和解决

原因 在Entity中有两个位置信息&#xff0c;一个是local transform。一个是local to world 其中local transform负责具体位置&#xff0c;local to world 负责渲染位置&#xff0c;即图像的渲染的位置是根据local to world的。 local to world 的更新是引擎自己控制的&#x…

R语言——绘制生命曲线图(细胞因子IL5)

绘制生命曲线图&#xff08;根据细胞因子&#xff09; 说明流程代码加载包读取Excel文件清理数据重命名列名处理IL-5中的"<"符号 - 替换为检测下限的一半首先找出所有包含"<"的值检查缺失移除缺失值根据IL-5中位数将患者分为高低两组 创建生存对象拟…

神马系统8.5搭建过程,附源码数据库

项目介绍 神马系统是多年来流行的一款电视端应用&#xff0c;历经多年的发展&#xff0c;在稳定性和易用性方面都比较友好。 十多年前当家里的第一台智能电视买回家&#xff0c;就泡在某论坛&#xff0c;找了很多APP安装在电视上&#xff0c;其中这个神马系统就是用得很久的一…

大模型论文:Improving Language Understanding by Generative Pre-Training

大模型论文&#xff1a;Improving Language Understanding by Generative Pre-Training OpenAI2018 文章地址&#xff1a;https://www.mikecaptain.com/resources/pdf/GPT-1.pdf 摘要 自然语言理解包括各种各样的任务&#xff0c;如文本蕴涵、问题回答、语义相似性评估和文…

[ctfshow web入门] web18

前置知识 js(javascript)语言用于前台控制&#xff0c;不需要知道他的语法是什么&#xff0c;以高级语言的阅读方式也能看懂个大概。 在JavaScript中&#xff0c;confirm()是一个用于显示确认对话框的内置函数&#xff0c;不用知道怎么使用。 信息收集 提示&#xff1a;不要…

`uia.WindowControl` 是什么:获取窗口文字是基于系统的 UI 自动化接口,而非 OCR 方式

uia.WindowControl 是什么:获取窗口文字是基于系统的 UI 自动化接口,而非 OCR 方式 uia.WindowControl 通常是基于 Windows 系统的 UI 自动化框架(如 pywinauto 中的 uia 模块)里用于表示窗口控件的类。在 Windows 操作系统中,每个应用程序的窗口都可以看作是一个控件,ui…

vue3 处理文字 根据文字单独添加class

下面写的是根据后端返回的html 提取我需要的标签和字 将他们单独添加样式 后端返回的数据 大概类似于<h1>2024年“双11”购物节网络零售监测报告</h1><p>表1 “双11” 期间网络零售热销品类TOP10</p> function checkfun(newList){if (newList) {let …