Mybatis中的映射文件编写原则
先来回顾一下,在Java项目中如何使用Mybatis执行SQL语句:
- 添加依赖:在项目中添加 MyBatis 和数据库驱动的依赖。
- 配置 MyBatis:创建 MyBatis 的配置文件,配置数据源和 Mapper 映射。
- 创建 POJO 类:定义与数据库表对应的实体类。
- 创建 Mapper 接口:定义操作数据库的方法。
- 创建 SQL 映射文件:使用 XML 定义 SQL 语句和结果映射。
- 编写主程序:执行 SQL 查询并获取结果。
下面再来详细讲解一下如何编写Mapper文件。
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="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
接下来我们来讲解每个标签的作用
1.Mapper标签
<mapper>
标签是 MyBatis Mapper XML 文件的根标签,用于定义 SQL 映射。它包含一系列的子标签,如 <select>
、<insert>
、<update>
和 <delete>
,用于定义具体的数据库操作。
1.1 namespace参数
指定映射器接口的完全限定名(即包名+接口名),用于将 XML 中的 SQL 语句与 Java 接口中的方法关联起来。(说明白点就是指明我调用SQL语句时,给每个SQL起一个唯一的名字,这样每次调用只要输入SQL的名字,就可以进行调用了。注意:这里的是一个大的范围,因为一般是每一个POJO类都有一个Mapper文件,而在这个类的业务逻辑中,需要很多条SQL语句(如增删改查),每个SQL都有一个id,在使用是可以使用namespace.id的值,唯一指明一条SQL语句
)
1.2 resource参数
注意:一旦使用这个参数,就说明此条<mapper>是在Mybatis-config.xml这个核心配置文件中的。
我们需要记住:每次建立一个Mapper映射文件,就需要在mapper-config.xml核心配置文件中说明有这么个文件,就要添加一个<mapper>标签:
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
在Java项目中,特别是使用MyBatis这类框架时,项目的结构通常遵循Maven或Gradle等构建工具的约定。这些约定中,src/main/java
目录用于存放Java源代码(.java
文件),这些代码在编译时会被转换成.class
字节码文件。
然而,一个完整的Java应用不仅仅包含Java源代码,还可能包含其他类型的资源文件,如配置文件、属性文件、XML映射文件等。在MyBatis中,Mapper XML文件就是这类资源文件,它们包含了SQL语句和映射定义,是MyBatis框架在运行时解析和执行SQL所必需的。
虽然这些XML文件不是Java源代码,不需要被编译,但它们在运行时是必需的,因为MyBatis会读取这些文件来构建和执行相应的SQL操作。因此,需要在项目的配置中指明这些文件的位置,以便MyBatis能够正确地加载它们。
在MyBatis的核心配置文件中,<mappers>
标签就是用来完成这个任务的。通过<mapper resource="..."/>
子标签,可以告诉MyBatis去哪里找到这些XML映射文件。这样,Java代码通过Mapper接口调用SQL操作时,MyBatis就知道去哪里找到对应的SQL语句和映射定义。
所以,总结来说:
src/main/java
中的.java
文件是Java源代码,需要被编译成.class
文件。- Mapper XML文件是MyBatis的资源文件,不需要编译,但在运行时是必需的。
- 需要在MyBatis配置中指明Mapper XML文件的位置,以便框架能够加载和使用它们。
2. Mapper的子标签
其子标签有很多,这里重点以<select>标签为例子,主要讲解其参数。
基本结构如下:
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserById" parameterType="int" resultType="com.example.pojo.User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
2.1 id标签
唯一标识一个<select>标签。这个id
用于在Java接口中匹配方法名。就像上面说的,可以根据namespace.id来选择唯一一个SQL,如下:
public class UserTest {
@Test
public void findByIDTest(){
String resources = "mybatis-config.xml";
Reader reader = null;
try{
reader = Resources.getResourceAsReader(resources);
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sqlSessionFactory.openSession();
User user = session.selectOne("com.example.mapper.UserMapper.selectByID",1); //这里面的第一个参数就是一个例子
System.out.println(user);
session.close();
}
}
这里使用session.selectOne()来查询,第一个参数就是要使用的SQL语句的ID,第二个参数是这个SQL的需要的参数(parameterType)
2.2 parameterType标签
指定输入参数的类型。可以是Java基本数据类型(如int
、String
)或自定义的Java类。
2.3 resultType标签
指定查询结果的类型。可以是Java基本数据类型、自定义的Java类或集合类型。
2.4 resultMap标签
可以看到上面的User类中的属性名字和表users表中的字段名字都一一对应。
现在又有一种新的需求,如果二者的这些内容不对应呢?那又要如何操作呢?
请看已经有下面的内容:
POJO类有(id,name,age)这三个属性。
而我们的表t_student中有(sid,sname,sage)这三个属性。
现在的问题是,它们已经不匹配了,我们又要如何查询?这里我们就需要使用<resultMap>标签。
我们还是首先建立一个<select>标签用于查询,只不过需要修改一下参数:
<select id="selectAll" resultMap="studentMap">
select *
from t_student
</select>
这里我们把原来的"resultType"属性换成了"resultMap"属性(注意:这两个属性之间是互斥的,只能存在一个)。这个意思是说,我返回值的类型需要做一下映射,请你根据我的"resultMap"标签的值,找到<resultMap>标签,然后再查看返回值类型。
然后我们还需要在下面创建一个<resultMap>标签:
<resultMap id="studentMap" type="Student">
<id property="id" column="sid"></id>
<result property="name" column="sname"></result>
<result property="age" column="sage"></result>
</resultMap>
这里的参数id是来表示唯一<resultMap>的,"type"属性是用来指定映射后的返回值。(注意这里应该是com.example.pojo.Student,后面会讲如何简化。)
这里每个<resultMap>标签下面只能有一个<id>子标签,用来映射主键。其余的<result>标签是用来映射除主键之外的字段。
这里的property属性的值是POJO类中的属性名字(如这里Student类的id、name、age),而column属性的值是表中的字段名(这里是t_studnet表中的sid、sname、sage)。
这样就可以用select来查询了。
整体xml文件如下:
<mapper namespace="com.example.mapper.StudentMapper">
<select id="selectAll" resultMap="studentMap">
select *
from t_student
</select>
<resultMap id="studentMap" type="Student">
<id property="id" column="sid"></id>
<result property="name" column="sname"></result>
<result property="age" column="sage"></result>
</resultMap>
</mapper>
然后测试文件中:
@Test
public void findAllTest(){
SqlSession session = MybatisUtils.getSession();//这里是我自己建立的工具类
List<Student> list = session.selectList("com.example.mapper.StudentMapper.selectAll");
for(Student student:list){
System.out.println(student);
}
session.commit();
session.close();
}
如何简化
在上面的xml文件中,每次都需要写明返回值类型所在的地址(如com.example.pojo.Student),我们可以加一些内容使只用写Student即可。
只需要在mybatis-config核心配置文件中的<properties>标签下加上下面内容:
<configuration>
<!-- 其他配置项 -->
<typeAliases>
<package name="com.example.pojo"/>
</typeAliases>
<!-- 其他配置项 -->
</configuration>
这样就可以简化操作了。
至此,本文结束!!!