MyBatis 注解开发详解

目录

一、MyBatis 注解开发概述

二、使用注解完成 CRUD 操作

1. 配置 MyBatis 核心文件 SqlMapConfig.xml

2. UserDao 接口及注解

3. UserTest 测试方法

三、多对一查询(One-to-Many)

1. 多对一立即加载查询

        2.StudentDao 接口方法

四、多对一延迟加载查询(Lazy Loading)

1. StudentDao 接口方法

2. TeacherDao 接口方法

五、一对多查询(Many-to-One)

1. TeacherDao 接口方法(延迟加载)

2. StudentDao 接口方法


一、MyBatis 注解开发概述

        MyBatis 提供了基于 XML 配置基于注解的两种开发方式。注解方式相对简单,但实际开发中更推荐使用 XML 配置方式,以减少对源代码的修改,提高可维护性。

1. MyBatis 常用注解

  • @Insert:添加数据
  • @Update:修改数据
  • @Delete:删除数据
  • @Select:查询数据
  • @Result:实现结果集封装
  • @Results:配合 @Result 使用,封装多个结果集
  • @One:一对一、多对一映射
  • @Many:一对多映射

二、使用注解完成 CRUD 操作

1. 配置 MyBatis 核心文件 SqlMapConfig.xml

<mappers>
    <!-- 第一种方式:使用 class 引入具体的 Dao 接口 -->
    <mapper class="com.qcby.dao.UserAnnoDao"/>
    
    <!-- 第二种方式:针对整个包下的所有接口 -->
    <package name="com.qcby.dao"/>
</mappers>

2. UserDao 接口及注解

import com.qcby.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface UserDao {
    
    // 查询所有用户
    @Select("SELECT * FROM user")
    @Results(id="userMap", value = {
        @Result(property = "id", column = "id"),
        @Result(property = "username", column = "username"),
        @Result(property = "birthday", column = "birthday"),
        @Result(property = "sex", column = "sex"),
        @Result(property = "address", column = "address")
    })
    List<User> findAll();
    
    // 根据 ID 查询用户
    @Select("SELECT * FROM user WHERE id = #{id}")
    @ResultMap("userMap")
    User findById(int id);
    
    // 插入用户数据
    @Insert("INSERT INTO user(username, birthday, sex, address) VALUES(#{username}, #{birthday}, #{sex}, #{address})")
    @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyColumn = "id", keyProperty = "id", before = false, resultType = Integer.class)
    int insert(User user);

    // 更新用户信息
    @Update("UPDATE user SET username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address} WHERE id = #{id}")
    int update(User user);

    // 删除用户
    @Delete("DELETE FROM user WHERE id = #{id}")
    int delete(int id);

    // 查询用户总数
    @Select("SELECT COUNT(*) FROM user")
    int findCount();

    // 模糊查询用户
    @Select("SELECT * FROM user WHERE username LIKE #{username}")
    List<User> findByName(String username);
}

3. UserTest 测试方法

public class UserTest {
    private InputStream in;
    private SqlSession session;
    private UserDao mapper;

    @Before
    public void init() throws IOException {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        session = factory.openSession();
        mapper = session.getMapper(UserDao.class);
    }

    @After
    public void destroy() throws IOException {
        session.close();
        in.close();
    }

    @Test
    public void findAll() {
        List<User> users = mapper.findAll();
        users.forEach(System.out::println);
    }

    @Test
    public void findById() {
        System.out.println(mapper.findById(4));
    }

    @Test
    public void insert() {
        User user = new User("小美", new Date(), "女", "保定");
        int insert = mapper.insert(user);
        session.commit();
        System.out.println(insert);
    }

    @Test
    public void update() {
        User user = new User(22, "小美", new Date(), "女", "上海");
        int update = mapper.update(user);
        session.commit();
        System.out.println(update);
    }

    @Test
    public void delete() {
        int delete = mapper.delete(22);
        session.commit();
        System.out.println(delete);
    }

    @Test
    public void findCount() {
        System.out.println(mapper.findCount());
    }

    @Test
    public void findByName() {
        mapper.findByName("%a%").forEach(System.out::println);
    }
}

三、多对一查询(One-to-Many)

1. 多对一立即加载查询

StudentDao 接口方法
@Select("SELECT student.*, teacher.Tname FROM student LEFT JOIN teacher ON student.t_id = teacher.id")
@Results(value = {
    @Result(property = "id", column = "id"),
    @Result(property = "Sname", column = "Sname"),
    @Result(property = "sex", column = "sex"),
    @Result(property = "age", column = "age"),
    @Result(property = "t_id", column = "t_id"),
    @Result(property = "teacher.Tname", column = "Tname")
})
List<Student> getStudent();
测试代码
@Test
public void getStudent() {
    List<Student> students = mapper.getStudent();
    students.forEach(System.out::println);
}

四、多对一延迟加载查询(Lazy Loading)

1. StudentDao 接口方法

@Select("SELECT * FROM student")
@Results(value = {
    @Result(property = "id", column = "id"),
    @Result(property = "Sname", column = "Sname"),
    @Result(property = "sex", column = "sex"),
    @Result(property = "age", column = "age"),
    @Result(property = "teacher", column = "t_id",
            one = @One(select = "com.qcby.dao.TeacherDao.getTeacher", fetchType = FetchType.LAZY))
})
List<Student> getStudent();

2. TeacherDao 接口方法

@Select("SELECT * FROM teacher WHERE id = #{t_id}")
Teacher getTeacher(Integer id);

3. 测试代码

@Test
public void getStudent() {
    List<Student> students = mapper.getStudent();
    students.forEach(System.out::println);
}

五、一对多查询(Many-to-One)

1. TeacherDao 接口方法(延迟加载)

@Select("SELECT * FROM Teacher")
@Results(value = {
    @Result(property = "id", column = "id"),
    @Result(property = "Tname", column = "Tname"),
    @Result(property = "students", column = "id",
            many = @Many(select = "com.qcby.dao.StudentDao.findByUid", fetchType = FetchType.LAZY))
})
List<Teacher> findAllLazy();

2. StudentDao 接口方法

@Select("SELECT * FROM student WHERE t_id = #{t_id}")
Student findByUid(int uid);

3. 测试代码

@Test
public void findAllLazy() {
    List<Teacher> list = mapper.findAllLazy();
    list.forEach(System.out::println);
}

总结

  • 注解方式可以快速开发,但 XML 配置更具灵活性和可维护性。
  • @One@Many 结合 fetchType.LAZY 可以实现延迟加载,优化查询性能。
  • CRUD 操作通过 @Insert@Select@Update@Delete 进行实现。
  • 一对多、多对一映射可以用 @One@Many 进行关联查询。

注解开发适用于小型项目或快速原型搭建,而企业级应用更推荐使用 XML 配置方式以降低代码耦合度。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek r1本地安装全指南

环境基本要求 硬件配置 需要本地跑模型&#xff0c;兼顾质量、性能、速度以及满足日常开发需要&#xff0c;我们需要准备以下硬件&#xff1a; CPU&#xff1a;I9内存&#xff1a;128GB硬盘&#xff1a;3-4TB 最新SSD&#xff0c;C盘确保有400GB&#xff0c;其它都可划成D盘…

最新版仿天涯论坛系统源码带后台

亲测正常使用版&#xff0c;代码精简&#xff0c;压缩包也小&#xff0c;程序运行速度更快&#xff0c;效率更高&#xff0c;服务器抗攻击能力更强 功能方面&#xff1a; 仿天涯论坛模板的免费论坛系统在功能方面也很强大!程序本身包含一个PC版网站和一个手机版网站 支持打包…

PostgreSQL 数据备份与恢复:掌握 pg_dump 和 pg_restore 的最佳实践

title: PostgreSQL 数据备份与恢复:掌握 pg_dump 和 pg_restore 的最佳实践 date: 2025/1/28 updated: 2025/1/28 author: cmdragon excerpt: 在数据库管理中,备份与恢复是确保数据安全和业务连续性的关键措施。PostgreSQL 提供了一系列工具,以便于数据库管理员对数据进行…

C++ 写一个简单的加减法计算器

************* C topic&#xff1a;结构 ************* Structure is a very intersting issue. I really dont like concepts as it is boring. I would like to cases instead. If I want to learn something, donot hesitate to make shits. Like building a house. Wh…

我的2024年博客总结(在工作、博客和生活中找到自己的生活节奏)

文章目录 ⭐前言⭐工作和博客的关联⭐找到自己的生活节奏⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文主要写2024年博客总结&#xff0c;关于在工作、博客和生活中找到自己的生活节奏。 node系列往期文章 node_windows环境变量配置 node_npm发布包 linux_配置…

【视频+图文详解】HTML基础1-html和css介绍、上网原理

图文详解 html介绍 概念&#xff1a;html是超文本标记语言的缩写&#xff0c;其英文全称为HyperText Markup Language&#xff0c;是用来搭建网站结构的语言&#xff0c;比如网页上的文字&#xff0c;按钮&#xff0c;图片&#xff0c;视频等。html的版本分为1.0、2.0、3.0、…

VT:优化LLM推理过程的记忆与探索

&#x1f4d6;标题&#xff1a;LLMs Can Plan Only If We Tell Them &#x1f310;来源&#xff1a;arXiv, 2501.13545 &#x1f31f;摘要 &#x1f538;大型语言模型&#xff08;LLM&#xff09;在自然语言处理和推理方面表现出了显著的能力&#xff0c;但它们在自主规划方面…

C++并发编程指南07

文章目录 [TOC]5.1 内存模型5.1.1 对象和内存位置图5.1 分解一个 struct&#xff0c;展示不同对象的内存位置 5.1.2 对象、内存位置和并发5.1.3 修改顺序示例代码 5.2 原子操作和原子类型5.2.1 标准原子类型标准库中的原子类型特殊的原子类型备选名称内存顺序参数 5.2.2 std::a…

日志收集Day007

1.配置ES集群TLS认证: (1)elk101节点生成证书文件 cd /usr/share/elasticsearch ./bin/elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass "" --days 3650 (2)elk101节点为证书文件修改属主和属组 chown elasticsearch:elasticsearch con…

AJAX综合案例——图书管理

黑马程序员视频地址&#xff1a; AJAX-Day02-10.案例_图书管理AJAX-Day02-10.案例_图书管理_总结_V1.0是黑马程序员前端AJAX入门到实战全套教程&#xff0c;包含学前端框架必会的&#xff08;ajaxnode.jswebpackgit&#xff09;&#xff0c;一套全覆盖的第25集视频&#xff0c…

Linux_线程同步生产者消费者模型

同步的相关概念 同步&#xff1a;在保证数据安全的前提下&#xff0c;让线程能够按照某种特定的顺序访问临界资源&#xff0c;从而有效避免饥饿问题&#xff0c;叫做同步竞态条件&#xff1a;因为时序问题&#xff0c;而导致程序异常&#xff0c;我们称之为竞态条件。 同步的…

Qt u盘自动升级软件

Qt u盘自动升级软件 Chapter1 Qt u盘自动升级软件u盘自动升级软件思路&#xff1a;step1. 获取U盘 判断U盘名字是否正确&#xff0c; 升级文件是否存在。step2. 升级step3. 升级界面 Chapter2 Qt 嵌入式设备应用程序&#xff0c;通过U盘升级的一种思路Chapter3 在开发板上运行的…

拦截器快速入门及详解

拦截器Interceptor 快速入门 什么是拦截器&#xff1f; 是一种动态拦截方法调用的机制&#xff0c;类似于过滤器。 拦截器是Spring框架中提供的&#xff0c;用来动态拦截控制器方法的执行。 拦截器的作用&#xff1a;拦截请求&#xff0c;在指定方法调用前后&#xff0c;根…

信息安全专业优秀毕业设计选题汇总:热点选题

目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光&#xff0c;一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整理…

Linux中使用unzip

安装命令 yum install unzip unzip常用选项和参数 选项 说明 -q 隐藏解压过程中的消息输出 -d /path/to/directory 指定解压文件的目标目录 -P password 如果.zip文件被密码保护&#xff0c;使用此选项可以指定打开文件所需的密码 解压命令 unzip 要解压的压缩包unz…

ThreadLocal源码解析

文章目录 一、概述二、get()方法三、set()方法四、可能导致的内存泄漏问题五、remove六、思考&#xff1a;为什么要将ThreadLocalMap的value设置为强引用&#xff1f; 一、概述 ThreadLocal是线程私有的&#xff0c;独立初始化的变量副本。存放在和线程进行绑定的ThreadLocalMa…

批量解密,再也没有任何限制了

有的时候我们在网上下载了PDF文档。发现没有办法进行任何的操作&#xff0c;就连打印权限都没有。今天给大家介绍的这个软件可以一键帮你进行PDF解密&#xff0c;非常方便&#xff0c;完全免费。 PDF智能助手 批量解密PDF文件 这个软件不是很大&#xff0c;只有10MB&#xff…

《LLM大语言模型+RAG实战+Langchain+ChatGLM-4+Transformer》

文章目录 Langchain的定义Langchain的组成三个核心组件实现整个核心组成部分 为什么要使用LangchainLangchain的底层原理Langchain实战操作LangSmithLangChain调用LLM安装openAI库-国内镜像源代码运行结果小结 使用Langchain的提示模板部署Langchain程序安装langserve代码请求格…

车载软件 --- 大一新生入门汽车零部件嵌入式开发

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…

有效运作神经网络

内容来自https://www.bilibili.com/video/BV1FT4y1E74V&#xff0c;仅为本人学习所用。 文章目录 训练集、验证集、测试集偏差、方差正则化正则化参数为什么正则化可以减少过拟合Dropout正则化Inverted Dropout其他的正则化方法数据增广Early stopping 归一化梯度消失与梯度爆…