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

XML语言

XML语言

在开始介绍Mybatis之前,先介绍一下XML语言,XML语言发明最初是用于数据的存储和传输,它是由一个一个的标签嵌套而成

<?xml version="1.0" encoding="UTF-8" ?>
<outer> <name>阿伟</name><desc>怎么又在玩电动啊</desc> <inner type="1"> <age>10</age> <sex></sex>  </inner>
</outer>

JDK为我们内置了一个叫做org.w3c的XML解析库,我们来看看如何使用它来进行XML文件内容解析:

// 创建DocumentBuilderFactory对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 创建DocumentBuilder对象
try {DocumentBuilder builder = factory.newDocumentBuilder();Document d = builder.parse("file:mappers/test.xml");// 每一个标签都作为一个节点NodeList nodeList = d.getElementsByTagName("test");  // 可能有很多个名字为test的标签Node rootNode = nodeList.item(0); // 获取首个NodeList childNodes = rootNode.getChildNodes(); // 一个节点下可能会有很多个节点,比如根节点下就囊括了所有的节点//节点可以是一个带有内容的标签(它内部就还有子节点),也可以是一段文本内容for (int i = 0; i < childNodes.getLength(); i++) {Node child = childNodes.item(i);if(child.getNodeType() == Node.ELEMENT_NODE)  //过滤换行符之类的内容,因为它们都被认为是一个文本节点System.out.println(child.getNodeName() + ":" +child.getFirstChild().getNodeValue());// 输出节点名称,也就是标签名称,以及标签内部的文本(内部的内容都是子节点,所以要获取内部的节点)}
} catch (Exception e) {e.printStackTrace();
}

依赖管理

如果使用Maven可以直接引入:

<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.16</version>
</dependency>

依赖变多之后,我们可以将其放到一个单独的文件夹,不然会很繁杂:

QQ_1723452238551

依赖导入完成后,我们就可以编写Mybatis的配置文件了(现在不是在Java代码中配置了,而是通过一个XML文件去配置

配置文件架构
创建mybatis-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><environments default="development">  <environment id="development">  <transactionManager type="JDBC"/>  <dataSource type="POOLED">  <property name="driver" value="${jdbc.driver}"/>  <property name="url" value="${jdbc.url}"/>  <property name="username" value="${jdbc.username}"/>  <property name="password" value="${jdbc.password}"/>  </dataSource>       </environment>  </environments>  <!-- 加载 Mapper 文件 -->  <mappers>  <!--映射文件方式1:一个一个的配置 -->  <mapper resource="mapper/UserMapper.xml"/>  <!--<mapper resource="com/demo14/mapper/UserMapper.xml"/>-->  <!--  <mapper class="mapper.UserMapper.xml"/> 根据实际路径调整 -->  <!--映射方式2,自动扫描包内的Mapper接口与配置文件-->  <!--<package name="com.demo14.mapper"/>-->   </mappers>  
</configuration>

实体类与映射文件

UserMapper.xml 是 MyBatis 实现 ​数据访问层 的核心文件,通过将接口方法与 SQL 绑定,简化数据库操作

<select id="唯一标识(必须与Mapper接口中的方法名一致用于绑定SQL与方法)" parameterType="传入参数类型(可省略),MyBatis通过方法参数自动推断" resultType="返回结果类型,MyBatis将查询结果自动映射到该实体类">
</select>  
  • 创建与数据库表对应的Java实体类,属性名需与字段名严格对应:
    @Data
package com.demo14.entity;  /**  * 用户实体类  */  
public class User {  private Integer userid;  private String userName;  private String userPwd;  private Integer userage;  ...}
/**  * 用户接口类  */  
@WebServlet  
public interface UserMapper {  public User queryUserByName(String userName);  }
  • 编写Mapper XML文件TestMapper.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 接口全限定名一致 -->  
<mapper namespace="com.demo14.mapper.UserMapper">  <!--  id: 对应 Mapper 接口方法名  parameterType: 参数类型(可省略)  resultType: 返回结果实体类全限定名  -->  <!--  MyBatis 代理 --><select id="queryUserByName" parameterType="string" resultType="com.demo14.entity.User">  <!--SQL 执行-->SELECT * FROM tb_user WHERE userName = #{userName}  </select>  
</mapper>
_`resultType`指定结果映射的实体类全路径_

属性外部化
- 创建jdbc.properties文件管理数据库参数

        jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/web_studyjdbc.username=testjdbc.password=123456
- 配置文件引用:
    <?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>  <!--  properties 标签中的配置可以供整个配置文件使用,在任何位置都可以引入其中配置的值  properties 标签可以通过标签property标签来配置一些子元素信息,也可以配置外部的动态文件  -->  <!-- 加载外部属性文件(如 jdbc.properties)(支持多环境配置)-->  <properties resource="jdbc.properties"/> <!-- 全局参数优化(生产环境必调参数) --><settings>        <!-- 启用下划线转驼峰 -->  <setting name="mapUnderscoreToCamelCase" value="true"/>  <!-- 启用日志输出 -->  <setting name="logImpl" value="STDOUT_LOGGING"/>  </settings>    <!-- 全局设置 -->  <!--<settings>  启用字段下划线转驼峰  <setting name="mapUnderscoreToCamelCase" value="true"/>   </settings> -->  <!-- 配置类型别名(可选) -->  <!--<typeAliases>     实体类包路径  <package name="com.example.entity"/>  </typeAliases>-->  <!-- 数据库环境配置(需与 jdbc.properties 中的参数匹配) -->  <environments default="development">  <environment id="development">  <transactionManager type="JDBC"/>  <dataSource type="POOLED">  <property name="driver" value="${jdbc.driver}"/>  <property name="url" value="${jdbc.url}"/>  <property name="username" value="${jdbc.username}"/>  <property name="password" value="${jdbc.password}"/>  </dataSource>       </environment>  </environments>  <!-- 加载 Mapper 文件 -->  <mappers>  <!--映射文件方式1:一个一个的配置 -->  <mapper resource="mapper/UserMapper.xml"/>  <!--<mapper resource="com/demo14/mapper/UserMapper.xml"/>-->  <!--  <mapper class="mapper.UserMapper.xml"/> 根据实际路径调整 -->  <!--映射方式2,自动扫描包内的Mapper接口与配置文件-->  <!--<package name="com.demo14.mapper"/>-->   </mappers>  </configuration>
为什么需要 MyBatis 的 <select> 标签配置?

1. 解耦 SQL 与 Java 代码

  • 传统 JDBC 问题
    SQL 与 Java 代码混杂,导致代码臃肿且难以维护。例如:
    // 传统 JDBC 代码(硬编码 SQL)
    String sql = "SELECT * FROM user WHERE name = ?";
    PreparedStatement stmt = connection.prepareStatement(sql);
    stmt.setString(1, "admin");
    ResultSet rs = stmt.executeQuery();
    
    • 缺点:SQL 修改需重新编译 Java 代码,且字符串拼接易引发 SQL 注入。
  • MyBatis 解决方案
    将 SQL 独立到 XML 文件中,实现 ​业务逻辑与数据访问逻辑分离
    <!-- UserMapper.xml -->
    <select id="getUserByName" resultType="User">SELECT * FROM user WHERE name = #{name}
    </select>
    

2. 自动结果集映射

  • 传统 JDBC 问题
    手动解析 ResultSet 到 Java 对象,代码重复且易错:
    User user = new User();
    while (rs.next()) {user.setId(rs.getInt("id"));user.setName(rs.getString("name"));// ...其他字段
    }
    
  • MyBatis 解决方案
    通过 resultTyperesultMap 自动映射查询结果到对象:
    <select id="getUserByName" resultType="com.example.User">SELECT id, name, email FROM user WHERE name = #{name}
    </select>
    

3. 动态 SQL 支持

  • 传统 JDBC 问题
    拼接动态 SQL 易出错且难以维护:

    String sql = "SELECT * FROM user WHERE 1=1 ";
    if (name != null) {sql += "AND name = '" + name + "' "; // 存在 SQL 注入风险
    }
    
  • MyBatis 解决方案
    使用 <if>, <where>, <foreach> 等标签实现动态 SQL:

    <select id="searchUsers" resultType="User">SELECT * FROM user<where><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></where>
    </select>
    
  • 核心机制
    MyBatis 通过 ​接口绑定 将 Mapper 接口与 XML SQL 关联:

public interface UserMapper {  public User queryUserByName(String userName);  
}
- ​**工作流程**:1. 调用 `userMapper.queryUserByName("admin")`。2. MyBatis 动态代理接口,根据方法名 `getUserByName` 找到对应的 XML SQL。3. 执行 SQL 并返回结果。

替代方案:简单项目可用注解,但 XML 仍是 MyBatis 的推荐实践

为何需要分别两个 mapper 目录?

这样做的原因是为了遵循Maven或Gradle的项目结构约定,构建工具会自动处理资源文件的打包和路径问题

职责分离

​构建与部署规范

  • Java 代码目录 (src/main/java)
    • 存放可编译的 Java 源文件(如 UserMapper.java)。
    • 构建工具(如 Maven/Gradle)会将其编译为 .class 文件。
  • 资源目录 (src/main/resources)
    • 存放非代码文件(如 XML、配置文件)。
    • 构建时,资源文件会被复制到 target/classes(类路径),供 MyBatis 运行时加载。

流程

  1. 开发者编写 UserMapper.java 接口。

  2. UserMapper.xml 中编写对应的 SQL。

  3. 构建工具将 Java 代码编译为 .class 文件,资源文件复制到类路径

  4. MyBatis 启动时,通过 ​接口名 + 方法名 动态绑定 XML 中的 SQL。

若合并目录

  • 将 XML 文件放在 Java 包目录中,可能导致构建工具忽略资源文件,引发 ​SQL 映射加载失败

MyBatis 的约定与配置

  • 默认映射规则
    MyBatis 要求 XML 文件的路径与接口包名一致。例如:

    • 接口路径:com.demo14.mapper.UserMapper
    • XML 路径:resources/mapper/UserMapper.xml
  • 配置验证
    mybatis-config.xml 或 Spring Boot 配置中需指定 XML 文件位置:

    <!-- MyBatis 配置 -->
    <mappers><mapper resource="mapper/UserMapper.xml"/>
    </mappers>
    
  • 在 Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致

相关文章:

  • 前端实战中的单例模式:以医疗药敏管理为例
  • 从一城一云到AI CITY,智慧城市进入新阶段
  • OpenCV 中用于背景分割的一个类cv::bgsegm::BackgroundSubtractorLSBP
  • 【数据融合实战手册·应用篇】“数字孪生+视频融合”让智慧城市拥有空间感知
  • 大语言模型主流架构解析:从 Transformer 到 GPT、BERT
  • 【JS逆向基础】前端基础-HTML与CSS
  • ‌CDGP|数据治理:探索企业数据有序与安全的解决之道
  • 开源照片管理系统PhotoPrism的容器化部署与远程管理配置
  • Python中的re库详细用法与代码解析
  • 跨浏览器自动化测试的智能生成方法
  • mission planner烧录ardupilot固件报错死机
  • 02_JVM
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月8日第72弹
  • SQLite3常用语句汇总
  • 文件包含 任意文件读取
  • 使用Jmeter进行核心API压力测试
  • 云计算的基础概论
  • 【工具推荐】Code2Prompt
  • 认识不同格式的点云数据 -PCD点云数据 文本点云数据
  • C++23 views::as_rvalue (P2446R2) 深入解析
  • 涨知识|没想到吧,体育老师强调的运动恢复方法是错的?
  • 万达电影:股东杭州臻希拟减持不超1.3927%公司股份
  • 印方称若巴方决定升级局势,印方已做好反击准备
  • 习近平离京赴莫斯科对俄罗斯进行国事访问并出席纪念苏联伟大卫国战争胜利80周年庆典
  • 公积金利率降至历史低位,百万房贷30年省5万
  • 汪海涛评《线索与痕迹》丨就虚而近实