Java 实习生必看!XML 从语法到实战,搞定配置文件不再慌
作为秋招上岸的 Java 实习生,我刚入职时曾对着 MyBatis 的Mapper.xml和 Spring 的配置文件发呆 —— 明明看文档知道 XML 是 “标记语言”,但一到实际配置就报错:要么属性没加引号导致解析失败,要么大小写写错让 SQL 查不到数据,甚至因为没处理&符号让整个接口崩了…
后来才发现,咱们 Java 实习生学 XML 不用啃厚厚的教程,重点抓 “基础语法 + 工作常用场景 + 避坑点” 就行。今天就把这份 “实习生专属 XML 笔记” 分享出来,帮你快速搞定工作中 90% 的 XML 需求~
一、先搞懂:为什么 Java 实习生绕不开 XML?
很多同学会疑惑:“现在都用注解了,为啥还要学 XML?” 其实在日常开发中,XML 还在大量使用,尤其是这两个场景,咱们躲不开:
- MyBatis 配置:写 SQL 的
Mapper.xml(比如定义查询语句、结果映射); - Spring 配置:老项目的
applicationContext.xml(定义 Bean、配置数据源); - 其他场景:比如接口文档的
swagger.xml、日志配置log4j.xml,甚至有些公司的接口参数格式也是 XML。
简单说:XML 是 “配置文件的常用格式”,搞懂它才能看懂项目配置、改对 SQL 映射 —— 这是咱们实习生上手干活的基础。
二、XML 基础语法:5 个核心规则,记牢不踩语法坑
XML 的语法很严谨,哪怕一个空格、一个引号错了,都会导致 “配置失效” 或 “解析报错”。咱们先把最核心的规则吃透,用表格 + 例子讲明白,方便你直接对照用。
1. 必须有 XML 声明(可选但建议加)
XML 声明要放在文档第一行,告诉解析器 “这是 XML 文件,用什么版本和编码”。
- 语法:
<?xml version="1.0" encoding="utf-8"?> - 说明:
version="1.0":XML 的版本(目前主流是 1.0,不用改);encoding="utf-8":文件编码(和项目编码保持一致,避免中文乱码)。
- 错误示例:如果把声明放在根元素后面,会直接报错:
<!-- 错误:声明不在第一行 --> <mapper namespace="com.test.mapper.UserMapper"> <?xml version="1.0" encoding="utf-8"?> </mapper>
2. 必须有且只有一个根元素
XML 文档就像 “一棵大树”,根元素是 “树干”,所有其他元素都是 “树枝”,不能没有根,也不能有多个根。
- 正确示例(MyBatis 的 Mapper.xml,根元素是
<mapper>):<?xml version="1.0" encoding="utf-8"?> <!-- 根元素:mapper --> <mapper namespace="com.test.mapper.UserMapper"> <!-- 子元素:select --> <select id="getUserById" parameterType="int" resultType="User"> SELECT * FROM user WHERE id = #{id} </select> </mapper> - 错误示例:多个根元素(
<mapper>和<user>并列),解析器会报错:<?xml version="1.0" encoding="utf-8"?> <mapper namespace="com.test.mapper.UserMapper">...</mapper> <user>...</user> <!-- 错误:多个根元素 -->
3. 元素规则:大小写敏感 + 正确嵌套
这是实习生最容易踩的坑!XML 对大小写 “零容忍”,嵌套也必须严格对应。
-
核心规则:
- 大小写敏感:
<User>和<user>是两个不同元素(比如 Spring 配置里<bean>不能写成<Bean>); - 必须闭合:要么成对闭合(
<select>...</select>),要么自闭合(<property name="url" value="jdbc:mysql://localhost:3306/test"/>); - 不能交叉嵌套:比如
<a><b></a></b>是错误的,必须是<a><b></b></a>。
- 大小写敏感:
-
正确示例(Spring 的 Bean 配置):
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!-- 自闭合元素:property --> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> </bean> <!-- 正确闭合bean元素 --> -
错误示例:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"> <!-- 错误:没闭合property --> </Bean> <!-- 错误:bean写成Bean,大小写错了 -->
4. 属性值:必须加引号(单引双引都可,别漏!)
和 HTML 不同,XML 的属性值必须用引号包裹(单引号'或双引号"都行),没加引号会直接解析失败。
- 正确示例(MyBatis 的 resultMap 配置):
<resultMap id="userResultMap" type="User"> <!-- 属性column和property都加了双引号 --> <id column="user_id" property="userId"/> <result column="user_name" property="userName"/> </resultMap> - 错误示例:属性值没加引号,启动项目会报 “XML 解析异常”:
<result column=user_id property=userName/> <!-- 错误:column和property值没加引号 -->
5. 特殊字符:用 “实体引用” 代替
XML 里有些字符有特殊意义(比如<会被当成元素开始),直接写会报错,必须用 “实体引用” 代替。
咱们实习生常用的 5 个实体引用,记牢这张表就行:
| 实体引用 | 对应字符 | 用途场景 | 示例(正确写法) |
|---|---|---|---|
< |
< |
比较符号(比如 SQL 里的<) |
salary < 5000(对应 SQL:salary < 5000) |
> |
> |
比较符号 | age > 18(对应 SQL:age > 18) |
& |
& |
URL 参数、SQL 里的& |
url="jdbc:mysql://localhost:3306/test?useSSL&serverTimezone=UTC" |
' |
' |
单引号 | name='Tom 'Jerry''(对应值:Tom 'Jerry') |
" |
" |
双引号 | title="Java XML"(对应值:Java XML) |
- 错误示例:SQL 里直接写
<,导致 Mapper.xml 解析失败:<!-- 错误:直接写<,会被当成元素开始 --> <select id="getLowSalaryUser" resultType="User"> SELECT * FROM user WHERE salary < 5000 </select> - 正确示例:用
<代替<:<select id="getLowSalaryUser" resultType="User"> SELECT * FROM user WHERE salary < 5000 </select>
6. 空格保留:XML 不 “吃” 空格
HTML 会把多个连续空格合并成一个,但 XML 会完整保留空格—— 这个特性在配置 “值” 的时候要注意,别多写或少写空格。
-
示例:如果配置数据库密码时多写了空格:
<!-- 错误:value值末尾多了个空格 --> <property name="password" value="123456 "/>启动项目会报 “数据库连接失败”,因为实际传递的密码是
123456(带空格),和真实密码不匹配。 -
正确做法:配置值前后别加多余空格,除非业务明确需要:
<property name="password" value="123456"/>
7. XML 注释:别放错位置
注释格式是<!-- 注释内容 -->,但有个禁忌:不能放在 XML 声明之前,也不能嵌套注释。
- 正确示例:
<?xml version="1.0" encoding="utf-8"?> <!-- 这是MyBatis的用户Mapper配置 --> <mapper namespace="com.test.mapper.UserMapper"> <!-- 查询用户详情 --> <select id="getUserById" resultType="User"> SELECT * FROM user WHERE id = #{id} </select> </mapper> - 错误示例:注释放在 XML 声明前,会导致解析报错:
<!-- 错误:注释在XML声明前面 --> <?xml version="1.0" encoding="utf-8"?> <mapper namespace="com.test.mapper.UserMapper">...</mapper>
三、Java 实习生必练:XML 实战场景(附代码示例)
学完语法,咱们直接对接工作 —— 这 3 个场景是实习生最常接触的,结合代码例子讲,你可以直接抄模板改。
场景 1:MyBatis 的 Mapper.xml(写 SQL 必备)
咱们写接口时,SQL 基本都放在 Mapper.xml 里,核心是<select>/<insert>标签和resultMap配置。
-
完整示例(用户查询 + 新增):
<?xml version="1.0" encoding="utf-8"?> <!-- 根元素mapper:namespace要和Mapper接口全路径一致 --> <mapper namespace="com.test.mapper.UserMapper"> <!-- resultMap:解决数据库字段(下划线)和Java实体(驼峰)映射问题 --> <resultMap id="userResultMap" type="com.test.entity.User"> <id column="user_id" property="userId"/> <!-- 主键映射 --> <result column="user_name" property="userName"/> <result column="user_age" property="userAge"/> <result column="create_time" property="createTime"/> </resultMap> <!-- 1. 查询用户:用resultMap映射结果 --> <select id="getUserById" parameterType="java.lang.Long" resultMap="userResultMap"> SELECT user_id, user_name, user_age, create_time FROM user WHERE user_id = #{userId} AND user_age > 18 <!-- 用实体引用代替> --> </select> <!-- 2. 新增用户:useGeneratedKeys获取自增主键 --> <insert id="addUser" parameterType="com.test.entity.User" useGeneratedKeys="true" keyProperty="userId"> INSERT INTO user (user_name, user_age, create_time) VALUES (#{userName}, #{userAge}, #{createTime}) </insert> </mapper> -
关键注意点:
namespace必须和 Mapper 接口的全路径一致(比如接口是com.test.mapper.UserMapper,这里就写这个);resultMap用来解决 “下划线转驼峰” 问题(比如数据库user_id对应 Java 的userId),不用每次查都写别名;- 新增时用
useGeneratedKeys="true"+keyProperty="userId",能把数据库自增的userId回写到 Java 实体里。
场景 2:Spring 配置文件(老项目常用)
虽然现在 Spring Boot 多用注解,但有些老项目还在用applicationContext.xml配置 Bean,咱们要能看懂。
-
示例(配置数据源 Bean):
<?xml version="1.0" encoding="utf-8"?> <!-- 引入Spring约束:固定格式,复制就行 --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置Druid数据源Bean:id是Bean的名称,class是全类名 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!-- 用property注入属性:name对应Bean的set方法名(比如setDriverClassName) --> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL&serverTimezone=UTC"/> <!-- &用&代替 --> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!-- 配置Service Bean:依赖注入dataSource --> <bean id="userService" class="com.test.service.impl.UserServiceImpl"> <property name="dataSource" ref="dataSource"/> <!-- ref引用上面的dataSource Bean --> </bean> </beans> -
关键注意点:
- 开头的
xmlns约束是固定的,直接复制项目里的模板就行,不用自己写; property的name要和 Bean 类里的set方法对应(比如setDriverClassName对应name="driverClassName");- 引用其他 Bean 用
ref(比如ref="dataSource"),直接赋值用value。
- 开头的
场景 3:XML 文件的读取(了解基础逻辑)
偶尔需要自己写代码读 XML 配置(比如读自定义的配置文件),用 Java 自带的DOM解析就行,不用学复杂的框架。
-
示例(读
user-config.xml里的用户名):import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; public class XmlReader { public static void main(String[] args) throws Exception { // 1. 创建解析工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 2. 创建解析器 DocumentBuilder builder = factory.newDocumentBuilder(); // 3. 解析XML文件,得到Document对象 Document doc = builder.parse(new File("src/main/resources/user-config.xml")); // 4. 获取根元素 Element root = doc.getDocumentElement(); // 5. 查找<username>元素 NodeList nodeList = root.getElementsByTagName("username"); if (nodeList.getLength() > 0) { // 6. 获取元素内容 String username = nodeList.item(0).getTextContent(); System.out.println("配置的用户名:" + username); // 输出:配置的用户名:admin } } } -
对应的
user-config.xml:<?xml version="1.0" encoding="utf-8"?> <user-config> <username>admin</username> <password>123456</password> </user-config>
四、实习生 XML 避坑指南:6 个血泪教训
这些坑都是我和同事踩过的,每个坑都附 “错误示例 + 解决方法”,帮你少走弯路。
坑 1:大小写写错,配置 “找不到”
错误场景:把 Spring 的<bean>写成<Bean>,启动项目报 “NoSuchBeanDefinitionException”(找不到 Bean)。原因:XML 对大小写敏感,<Bean>和<bean>是两个不同元素。解决:严格对照项目里的模板,比如<bean>、<mapper>、<resultMap>这些标签,大小写别乱改。
坑 2:属性没加引号,解析报错
错误场景:Mapper.xml 里写<result column=user_id property=userName/>,启动报 “SAXParseException: 元素类型 "result" 的属性 "column" 必须具有值”。原因:XML 属性值必须加引号,不管是单引还是双引。解决:所有属性值都用引号包裹,比如<result column="user_id" property="userName"/>。
坑 3:特殊字符没转义,SQL 执行失败
错误场景:SQL 里写WHERE salary < 5000,Mapper.xml 解析时把<当成元素开始,报 “XML 文档结构不正确”。原因:<是 XML 的特殊字符,必须转义。解决:用<代替<,比如WHERE salary < 5000;其他特殊字符按 “实体引用表” 转义。
坑 4:注释放在 XML 声明前,文件无法解析
错误场景:在 XML 声明前面加注释<!-- 配置文件 -->,启动项目报 “XML 声明允许出现在文档类型声明之前的唯一内容”。原因:XML 声明必须是文档的第一行内容,前面不能有任何东西(包括注释)。解决:把注释移到 XML 声明后面,比如:
<?xml version="1.0" encoding="utf-8"?>
<!-- 配置文件 -->
<mapper namespace="com.test.mapper.UserMapper">...</mapper>
坑 5:根元素不唯一,解析失败
错误场景:在 Mapper.xml 里写两个根元素<mapper>和<user>,报 “文档中根元素后面的标记必须格式正确”。原因:XML 必须有且只有一个根元素。解决:所有子元素都放在同一个根元素里,比如 Mapper.xml 的所有内容都放在<mapper>里。
坑 6:空格多余,配置值错误
错误场景:数据库密码配置成<property name="password" value="123456 "/>(末尾多了空格),连接数据库报 “Access denied for user 'root'@'localhost' (using password: YES)”。原因:XML 保留空格,实际密码是123456 (带空格),和真实密码不匹配。解决:配置值前后别加多余空格,写的时候多检查一遍。
五、XML 学习路径:2 周搞定,不用焦虑
咱们实习生学 XML 不用贪多,按这个路径来,1-2 周就能上手干活:
-
Day1-Day2:吃透基础语法记牢 “声明、根元素、属性引号、实体引用、空格保留” 这 5 个核心规则,用记事本写个简单的 XML 文件练手(比如
user.xml),检查是否能正常解析。 -
Day3-Day5:结合 MyBatis 实战找项目里的 Mapper.xml 当模板,试着改 SQL(比如加个查询条件、改个 resultMap),跑通接口 —— 重点练 “resultMap 映射” 和 “特殊字符转义”。
-
Day6-Day7:看懂 Spring 配置看老项目的
applicationContext.xml,理解<bean>和<property>的作用,知道 “怎么通过 ref 引用其他 Bean”。 -
Day8-Day10:总结避坑点把自己踩过的坑记在笔记里(比如大小写错误、属性没加引号),下次遇到类似报错能快速定位。
结尾:XML 不用学太深,实用就好!
最后想跟大家说:咱们 Java 实习生学 XML,重点不是 “精通所有语法”,而是 “能改对配置、能查错”。遇到 XML 报错不用慌,先检查这 3 点:
- 看日志:报错信息里一般会写 “第几行有问题”(比如 “Line 10: 属性值必须加引号”);
- 查语法:对照本文的 “基础规则”,看是不是大小写、引号、实体引用错了;
- 抄模板:项目里肯定有正确的 XML 文件,复制过来改内容,比自己从头写不容易错。
如果这篇笔记帮到你了,欢迎在评论区分享你的 XML 踩坑经历~ 咱们一起在 “实习生加油站” 里慢慢进步!
更多推荐
所有评论(0)