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

mybatis执行流程、关联映射、注解开发

一、mybatis执行流程

对象作用线程安全
SqlSessionFactory会话工厂,创建SqlSession线程安全(全局单例)
SqlSession数据库会话,执行 SQL、事务控制非线程安全(每次操作新建)
Mapper代理对象执行 SQL 的接口代理非线程安全(依赖SqlSession

1.1核心执行流程

  1. 读取配置文件MyBatis 首先会加载核心配置文件(sqlMapConfig.xml/mybatis-config.xml)和所有 Mapper 映射文件。

    • 核心配置文件:包含数据库连接信息、环境配置、事务管理器、类型别名等全局设置。
    • Mapper 映射文件:包含具体的 SQL 语句、参数映射、结果映射规则。
  2. 构建SqlSessionFactory对象这一步是 MyBatis 的初始化阶段,会解析配置文件并构建SqlSessionFactory

    • SqlSessionFactory是 MyBatis 的核心工厂对象,全局单例,负责创建SqlSession
    • 它内部维护了数据库连接池、配置元信息,是线程安全的。
  3. 创建SqlSession对象通过SqlSessionFactory打开会话,创建SqlSession

    • SqlSession是 MyBatis 与数据库交互的会话对象,非线程安全,每次数据库操作都应创建新实例。
    • 它封装了数据库连接、事务控制、SQL 执行的核心方法。
  4. 获取 Mapper 代理对象图中多个mapper指向SqlSession,代表通过SqlSession.getMapper(xxxMapper.class)获取 Mapper 接口的代理对象。

    • 这个代理对象由 MyBatis 动态生成,实现了 Mapper 接口的所有方法,会自动关联对应的 SQL 语句。
    • 这是 MyBatis 推荐的操作方式,替代了传统的selectOne/insert等方法。
  5. 执行数据库操作通过 Mapper 代理对象调用方法,MyBatis 会执行以下操作:

    • 封装 SQL 参数
    • 执行预编译 SQL
    • 处理结果集映射(将数据库记录转为 Java 对象)
    • 管理事务(提交 / 回滚)最终与数据库完成交互,实现增删改查操作。

sqlsession可以实现JDBC的connection以及mysql执行(本质操作数据库)
mybatis实现目前是mapper接口+xml映射

二、mybatis关联映射

把数据库表之间的关系 → 映射成 Java 对象之间的关系

关系标签作用
多对一 / 一对一<association>关联单个对象
一对多<collection>关联集合对象
  • 查单个对象(多对一 / 一对一)→ 用<association>
  • 查集合对象(一对多)→ 用<collection>

三、注解开发

把原来写在 Mapper.xml 里的 SQL,直接写在 DAO 接口的方法上面不用 XML 文件

步骤 1:DAO 接口上直接写 SQL(重点)

直接在DAO 接口的方法上加注解,写 SQL 就行。

1. 查询(@Select)
public interface UserDao { // 查询所有用户 @Select("select * from user") List<User> findAll(); }
2. 新增(@Insert)
// 新增用户 @Insert("insert into user(name,age) values(#{name},#{age})") int addUser(User user);
3. 修改(@Update)
// 修改用户 @Update("update user set name=#{name} where id=#{id}") int updateUser(User user);
4. 删除(@Delete)
// 删除用户 @Delete("delete from user where id=#{id}") int deleteUser(int id);

步骤 2:MyBatis 核心配置文件中注册 DAO 接口

sqlMapConfig.xml中,直接注册 DAO 接口

<mappers> <!-- 注解开发:直接写接口全类名 --> <mapper class="com.qcby.dao.UserDao"/> </mappers>

步骤 3:测试调用(和之前一样)

UserDao userDao = session.getMapper(UserDao.class); List<User> list = userDao.findAll(); // 直接调用

关联映射(多对一)

@Results + @Result代替 XML:

@Select("select u.*, d.id dept_id, d.name dept_name from user u left join dept d on u.dept_id=d.id") @Results({ @Result(property = "id", column = "id"), @Result(property = "name", column = "name"), // 关联对象:property=实体类属性, javaType=类型, column=外键列 @Result(property = "dept", javaType = Dept.class, column = "dept_id", one = @One(select = "com.qcby.dao.DeptDao.findById")) }) List<User> findUserWithDept();

== 对比的是对象

User

dao

package com.qcby.dao; import com.qcby.entity.User; import org.apache.ibatis.annotations.*; import javax.jws.soap.SOAPBinding; 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") }) public List<User> findAll(); //通过ID查询 @Select("select * from user where id = #{id}") @ResultMap(value = "userMap") public 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) public int insert(User user); //更新 @Update("update user set username = #{username},birthday = #{birthday},sex = #{sex},address = #{address} where id = #{id}") public int update(User user); //删除 @Delete("delete from user where id = #{id}") public int delete(int id); //查询数量 @Select("select count(*) from user") public int findCount(); //模糊查询 @Select("select * from user where username like concat('%',#{username},'%')") public List<User> findByName(String username); }

test

import com.qcby.dao.UserDao; import com.qcby.entity.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.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.sql.Date; import java.util.List; public class UserTest { private InputStream in = null; private SqlSession session = null; private UserDao mapper = null; @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 destory() throws IOException { session.close(); in.close(); } @Test public void findAll() throws IOException { List<User> users = mapper.findAll(); for (User user:users) { System.out.println(user); } } @Test public void findById(){ User user = mapper.findById(4); System.out.println(user); } // ====================== 这里修复了日期!====================== @Test public void insert(){ User user = new User(); user.setSex("女"); user.setUsername("小美"); // 正确写法 user.setBirthday(new Date(System.currentTimeMillis())); user.setAddress("保定"); int insert = mapper.insert(user); session.commit(); System.out.println("插入成功:" + insert); } // ====================== 这里修复了日期!====================== @Test public void update(){ User user = new User(); user.setId(22); user.setSex("女"); user.setUsername("小美"); // 正确写法 user.setBirthday(new Date(System.currentTimeMillis())); user.setAddress("上海"); int insert = mapper.update(user); session.commit(); System.out.println("修改成功:" + insert); } @Test public void delete(){ int delete = mapper.delete(22); session.commit(); System.out.println("删除成功:" + delete); } @Test public void findCount(){ int count = mapper.findCount(); System.out.println("总记录数:" + count); } @Test public void findByName(){ List<User> list = mapper.findByName("小"); for (User user : list) { System.out.println(user); } } }

http://www.jsqmd.com/news/884956/

相关文章:

  • 收藏!2026年大模型行业爆发,小白程序员黄金入局期,薪资暴涨必看
  • Claude PEST分析实战手册(2024最新版):从政策红线到技术适配,7步构建合规AI决策框架
  • Lovable电商网站搭建全流程拆解(含GitHub可运行源码+AWS部署Checklist)
  • 2026 收藏版|生产级 AI Agent 落地现状剖析,程序员入门大模型必看行业报告
  • 收藏|2026零基础逆袭大模型工程师,三个月实战转型路线干货
  • 如何突破网盘限速瓶颈?LinkSwift直链解析工具让企业文件传输效率提升300%
  • 为内部知识库问答系统集成 Taotoken 提供多模型备选与故障切换
  • AAAI 2025 | VHM:面向遥感图像分析的通用可信视觉语言模型
  • 2026年资质齐全的炸鸡小吃加盟品牌排名 - 资讯焦点
  • 基于M5Stack与SCD40的室内空气质量监测站:从原理到实践
  • SingleFile完整使用指南:掌握网页离线保存的终极解决方案
  • 基于Arduino与DCF77的LED数码管无线电钟设计与实现
  • 基于ESP8266监听模式的低成本空中搜救信号探测系统设计与实现
  • 腾讯元宝GEO排名优化:2026年AI搜索流量抢占的系统性方法论 - 博客湾
  • taotoken多模型聚合api在ubuntu服务器上的稳定部署实践
  • OpenHRMS:如何用开源方案解决中小企业人力资源管理难题?
  • Kali Linux 2024.2 国内镜像源一键配置脚本(附清华、阿里云、中科大源地址)
  • 终极指南:如何用wechat-need-web插件突破微信网页版访问限制
  • 5分钟掌握终极音乐解锁方案:让所有加密音乐重获自由
  • Zip压缩包密码恢复
  • 珍宝黄金回收(十年老店)|2026 年 5 月扬州江都黄金回收行情解读、避坑技巧与 FAQ 在扬州江都区,提到黄金回收,很多老居民第一反应就是珍宝。 - 润富黄金珠宝行
  • 收藏必备|2026 版 AI 大模型应用开发学习指南,程序员转行增收绝佳路径
  • 3步设置解放双手!AzurLaneAutoScript碧蓝航线自动化脚本终极使用指南
  • 2026 年 5 月大连黄金回收避坑指南:添价收黄金奢侈品回收为首选,六家正规机构优势全解析 - 薛定谔的梨花猫
  • 【MySQL全面教学】MySQL索引原理与优化Day8(2026年)
  • 长期使用 Taotoken Token Plan 套餐对项目成本控制的实际影响
  • 河北钢格栅踏步板技术选型指南及合规供应商盘点 - 奔跑123
  • 从分区看设计哲学:深度对比银河麒麟V10、Windows 11与Ubuntu的系统布局
  • UE4项目实战:给你的FPS游戏加个3D全息武器菜单(UMG+控件交互组件教程)
  • 收藏干货|2026 年大模型入门必懂 Token 详解,分词原理与 BPE 算法通俗拆解