欢迎光临
我们一直在努力

Java EE 进阶:8.MyBatis 操作数据库(入门)(第三弹)

目录

4.MyBatis XML 配置文件

4.1 配置连接字符串和 MyBatis

4.2 写持久层代码

4.2.1 添加 mapper 接口

4.2.2 添加 UserInfoXMLMapper.xml

4.2.3 单元测试

4.3 增删改查操作

4.3.1 查(Select)

1.起别名

2.结果映射:ResultMap 标签

后续补充:

3.配置驼峰自动转换(推荐)

4.3.2 增(Insert)

返回自增 id

4.3.3 改(Update)

 4.3.4 删(Delete)


书接上文:Java EE 进阶:8.MyBatis 操作数据库(入门)(第二弹)~~

4.MyBatis XML 配置文件

Mybatis 的开发有两种方式: 1. 注解 2. XML 上面学习了注解的方式, 接下来我们学习 XML 的方式 使用 Mybatis 的注解方式,主要是来完成一些简单的增删改查功能. 如果需要实现复杂的 SQL 功能,建议使用XML来配置映射语句,也就是将 SQL 语句写在 XML 配置文件中. MyBatis XML 的方式需要以下两步: 1. 配置数据库连接字符串和MyBatis 2. 写持久层代码

闲聊:注解和 XML 是可以共存的,甚至可以共存在一个类里,只不过但是不建议这么写,就好像上身穿了西装,下身穿了牛仔裤,就不是很搭~~

对比 XML 和 注解 的步骤👇

XML步骤 注解步骤
1.添加依赖:mybatis-starter、mysql 1.添加依赖
2.配置数据库信息 2.配置数据库信息
3.定义接口 3.定义接口
4.使用 XML 实现接口 4.使用 注解 实现接口

前两步都是一样的,我们目前都配置完了,我们接下来新建一个类 UserInfoMapperXML 来学习这里的知识~~

4.1 配置连接字符串和 MyBatis

此步骤需要进行两项设置,数据库连接字符串设置和 MyBatis 的 XML 文件配置

我们工作中会有很多的代码和不同的文件,那么 MyBatis 怎么知道这个 xml 文件放在哪了?那么我就需要做两件事:

1.告诉 MyBatis 我放在哪了

2.告诉 MyBatis 我到底要实现哪个接口

这就需要新增一个配置信息👇

# 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件
mybatis:
mapper-locations: classpath:mapper/**Mapper.xml

其中 ** 表示通配符,表示 匹配多个字母~~

写成 **.xml 时:这个路径下的所有 xml 都会加载(写成 *.xml 也是一样的效果)

如果是 application.yml 文件, 配置内容如下:

# 数据库连接配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件
mybatis:
mapper-locations: classpath:mapper/**Mapper.xml

如果是application.properties文件, 配置内容如下:

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=root
# 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件
mybatis.mapper-locations=classpath:mapper/**Mapper.xml

4.2 写持久层代码

 持久层代码分两部分 1. 方法定义 Interface 2. 方法实现: XXX.xml 

4.2.1 添加 mapper 接口

 数据持久层的接口定义:

package com.bit.mybatis.mapper;

import com.bit.mybatis.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
* Created with IntelliJ IDEA.
* Description:
* User: CoderYanger
* Date: 2026-11-07
* Time: 17:33
*/
@Mapper
public interface UserInfoMapperXML {

List<UserInfo> selectAll();
}

4.2.2 添加 UserInfoXMLMapper.xml

 数据持久成的实现,MyBatis 的固定 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="com.example.demo.mapper.UserInfoMapper">

</mapper>

com.bit.mybatis.mapper.UserInfoMapperXML 表示你实现的是哪个接口,这一部分按住 Ctrl 可以直接跳转的~~

闲聊:感兴趣的同学可以安装一下下面的插件~~

创建 UserInfoXMLMapper.xml, 路径参考 yml 中的配置

查询所有用户的具体实现 :

<?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="com.bit.mybatis.mapper.UserInfoMapperXML">

<select id="selectAll" resultType="com.bit.mybatis.model.UserInfo">
select * from user_info
</select>
</mapper>

以下是对以上标签的说明: • <mapper> 标签:需要指定 namespace 属性,表示命名空间,值为 mapper 接口的全限定 名,包括全包名.类名。 • <select> 查询标签:是用来执行数据库的查询操作的: ◦ id :是和 Interface (接口)中定义的方法名称一样的,表示对接口的具体实现方法。 ◦ resultType :是返回的数据类型,也就是开头我们定义的实体类.

4.2.3 单元测试

package com.bit.mybatis.mapper;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

/**
* Created with IntelliJ IDEA.
* Description:
* User: CoderYanger
* Date: 2026-11-07
* Time: 18:22
*/
@SpringBootTest
class UserInfoMapperXMLTest {

@Autowired
private UserInfoMapperXML userInfoMapperXML;
@Test
void selectAll() {
userInfoMapperXML.selectAll().stream().forEach(x-> System.out.println(x));
}
}

运行结果如下:

注意,这其中的对应关系👇

如果没有按照这个顺序规则来写的话就会出现问题

第一个出错:没有映射上,把 mapper 改为 mapper1(改掉 **Mapper.xml 也是一样的)👇

# 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件
mapper-locations: classpath:mapper1/**Mapper.xml

报错结果显示:绑定异常,没找到👇

第二个出错:把 selectAll 改为 selectAll1,与原本的 selectAll 对应不上

<?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="com.bit.mybatis.mapper.UserInfoMapperXML">

<select id="selectAll1" resultType="com.bit.mybatis.model.UserInfo">
select * from user_info
</select>
</mapper>

@Mapper
public interface UserInfoMapperXML {

List<UserInfo> selectAll();
}

我们发现报的错误信息依旧是这个👇

如果说上面的 com.bit.mybatis.mapper.UserInfoMapperXML 对应不上了,把 XML 去掉,再加个 1

<?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="com.bit.mybatis.mapper.UserInfoMapper1">

<select id="selectAll" resultType="com.bit.mybatis.model.UserInfo">
select * from user_info
</select>
</mapper>

发现依旧是 绑定异常👇

所以当看到这个异常就按照上面图片的对应关系去查就可以了~~

4.3 增删改查操作

接下来,我们来实现一下用户的增加、删除和修改的操作.

方法的声明都跟注解是一样的~~

4.3.1 查(Select)

闲聊:传递一个参数、传递多个参数,跟我们的注解是一模一样的,此处就不再给大家赘述了~~

只是写法不一样,我们注解是把 SQL 语句放到了注解里面,XML 是放到标签里面了~~

同样的, 使用XML 的方式进行查询, 也存在数据封装的问题 我们把SQL语句进行简单修改, 查询更多的字段内容

<select id="selectAll" resultType="com.bit.mybatis.model.UserInfo">
select * from user_info
</select>

运行结果:

结果显示: deleteFlag, createTime, updateTime 也没有进行赋值,跟注解一样,数据库的字段名和我们的属性如果是一致的话,就直接给映射上了,但是不一致的话,他不知道怎么去映射,解决办法和注解类似: 1. 起别名 2. 结果映射 3. 开启驼峰命名

1.起别名

UserInfoMapper.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="com.bit.mybatis.mapper.UserInfoMapperXML">

<select id="selectAll" resultType="com.bit.mybatis.model.UserInfo">
<!– select * from user_info–>
select id,username,`password`,age,gender,phone,
delete_flag as deleteFlag,
create_time as createTime,
update_time as updateTime
from user_info
</select>
</mapper>

运行结果👇可行的

2.结果映射:ResultMap 标签

注解方式是写注解,但是 XML 里面没办法写注解,接下来看下 xml 如果来写结果映射 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="com.bit.mybatis.mapper.UserInfoMapperXML">
<resultMap id="BaseMap" type="com.bit.mybatis.model.UserInfo">
<id property="id" column="id"></id>
<result property="deleteFlag" column="delete_flag"></result>
<result property="createTime" column="create_time"></result>
<result property="updateTime" column="update_time"></result>
</resultMap>
<select id="selectAll" resultType="com.bit.mybatis.model.UserInfo">
select * from user_info
<!– select id,username,`password`,age,gender,phone,–>
<!– delete_flag as deleteFlag,–>
<!– create_time as createTime,–>
<!– update_time as updateTime–>
<!– from user_info–>
</select>
<select id="selectAll2" resultMap="BaseMap">
select * from user_info
</select>
</mapper>

其实跟注解方式是基本一样的👇


后续补充:

使用的时候直接映射就可以了👇

虽然这里只写了三个就能达到我们的目的👇

<result property="deleteFlag" column="delete_flag"></result>
<result property="createTime" column="create_time"></result>
<result property="updateTime" column="update_time"></result>

但是还是建议写全👇把其他的都补上

@Data
public class UserInfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}

如果没写全的话,别人调用的时候,其他的值就可能映射不上~~

有人可能会觉得麻烦,还要写全,其实我们在最后会教大家一个其他的方式,可以不用写这些代码的~~


package com.bit.mybatis.mapper;

import com.bit.mybatis.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
* Created with IntelliJ IDEA.
* Description:
* User: CoderYanger
* Date: 2026-11-07
* Time: 17:33
*/
@Mapper
public interface UserInfoMapperXML {

List<UserInfo> selectAll();

List<UserInfo> selectAll2();
}

@Test
void selectAll2() {
userInfoMapperXML.selectAll().stream().forEach(x-> System.out.println(x));
}

来看运行结果👇

3.配置驼峰自动转换(推荐)

跟注解方式一样,可参考👇

Java EE 进阶:8.MyBatis 操作数据库(入门)(第二弹)

闲聊:开发中使用注解还是XML的方式? 关于开发中使用哪种模式这个问题, 没有明确答案. 仁者见仁智者见智, 并没有统一的标准, 更多是取决于你的团队或者项目经理, 项目负责人.

4.3.2 增(Insert)

依旧 Alt+Enter 键自动生成👇

从这里我们也能看出区别👇insert 没有 resultType 或者 resultMap,其实是只有 select 有,其他的都不用添加,我们的 insert、update、delete 返回的都是数字类型,所以不用加上 resultType

闲聊:其实方法定义的时候也是有一定规范的,插件也会根据你方法的名称大致判断出是什么,比如当你只写 user 的时候,生成时就会问你是增删改查哪一种👇

注意,是前缀,并不是说必须叫这个方法~~

 UserInfoMapper接口:

Integer insertUser(UserInfo userInfo);

UserInfoMapper.xml实现:

直接从之前的地方复制粘贴过来了,从这一点也可以发现这个注解 和 我们 XML 的 SQL 是一样的👇

<insert id="insertUser">
insert into user_info (username,`password`,age) values (#{username},#{password},#{age})
</insert>

Insert 时也涉及一个传参问题,我们现在是放在对象 UserInfo 里面了,那么接下来我就要从这个对象获取到参数了,我们的传参方式,XML 和 注解是一模一样的,我们注解如何获得参数的,我们 XML 也如何获得参数~~

闲聊:因为注解是在 XML 之后才兴起的,是参考 XML 而进行设计的~~

需要注意的是我们依然要区分字段名称和属性名称~~

我们下面进行测试👇

@Test
void insertUser() {
UserInfo userInfo=new UserInfo();
userInfo.setUsername("username4");
userInfo.setPassword("password4");
userInfo.setAge(5);
userInfoMapperXML.insertUser(userInfo);
}

运行前数据库👇

运行后👇

我们发现插入成功了👇

如果使用@Param设置参数名称的话, 使用方法和注解类似 UserInfoMapper 接口:

Integer insertUser2(@Param("userInfo") UserInfo userInfo);

UserInfoMapper.xml 实现:

注意,进行参数绑定之后,跟我们之前学习注解的方式相同,不加 @Param 是可以直接使用属性名称的,但是加上 @Param 就需要在前面加上 userinfo. 了

<insert id="insertUser2">
insert into user_info (username,`password`,age)
values (#{userinfo.username},#{userinfo.password},#{userinfo.age})
</insert>

下面进行测试👇

@Test
void insertUser2() {
UserInfo userInfo=new UserInfo();
userInfo.setUsername("username5");
userInfo.setPassword("password5");
userInfo.setAge(6);
userInfoMapperXML.insertUser2(userInfo);
}

我们发现出错了👇

这次的参数绑定错误跟之前的不一样,不要光看参数绑定出错就觉得是一样的,后面的也要看!它说是 userinfo 没找到,我们对比观察发现下面代码中全是 小写的 i,应该改为大写的 I👇

<insert id="insertUser2">
insert into user_info (username,`password`,age)
values (#{userInfo.username},#{userInfo.password},#{userInfo.age})
</insert>

再来运行👇

发现此时就插入成功了👇

闲聊:如果不知道自己错哪里了,可以去用在线的 diff 工具👇

能够快速找到肉眼看不出的 Bug,比如半角逗号和全角逗号👇

或者找到空格或者 Tab 键👇

这些非常适合初学者,在网上随便找一找  在线 diff 工具  就能用~~

另外给大家说一个很多人就会犯错的点,就是空格不能省,比如说我把这个空格去掉了👇

那么拼接的时候就会直接拼接成:insert intouser_info ……,我们来看看对应的报错信息👇

我们发现它报的是一个 SQL 语法错误,mybatis_test.intouser_info 这个表不存在~~

出现这个错误的时候,如果我们肉眼就是看不出来,那就放在这里执行一下👇

如果这里能够运行成功,那么 SQL 语句绝对没问题,这时候再去排查别的错误~~

返回自增 id

和注解也是非常类似的

接口定义不变, Mapper.xml 实现 设置 useGeneratedKeys 和 keyProperty 属性

<insert id="insertUser2" useGeneratedKeys="true" keyProperty="id">
insert into user_info (username,`password`,age)
values (#{userInfo.username},#{userInfo.password},#{userInfo.age})
</insert>

对比注解的方式👇我们发现是非常相似的

@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into user_info (username,`password`,age) "+
"values (#{userInfo.username},#{userInfo.password},#{userInfo.age})")
Integer insertUser2(@Param("userInfo") UserInfo userInfo);

下面我们来运行尝试拿到它的值👇

@Test
void insertUser2() {
UserInfo userInfo=new UserInfo();
userInfo.setUsername("username6");
userInfo.setPassword("password6");
userInfo.setAge(7);
Integer result=userInfoMapperXML.insertUser2(userInfo);
System.out.println("影响行数:"+result+",自增id:"+userInfo.getId());
}

运行前数据库👇

运行后👇

此时已经自增成功了~~

4.3.3 改(Update)

 UserInfoMapper接口:

//我们换一种传参方式,之前是根据对象,这次使用这种方式,根据id更新
Integer updateUser(String password,Integer age,Integer id);

UserInfoMapper.xml实现:

<update id="updateUser">
update user_info set password = #{password},age = #{age}
where id =#{id}
</update>

下面来测试👇

@Test
void updateUser() {
//更新id为13的数据
userInfoMapperXML.updateUser("updatePassword5",8,13);
}

更新前:

更新后:

我们发现更新成功👇

 4.3.4 删(Delete)

 UserInfoMapper接口:

//根据id删除
Integer deleteUser(Integer id);

UserInfoMapper.xml实现:

<delete id="deleteUser">
delete from user_info where id = #{id}
</delete>

下面测试👇

@Test
void deleteUser() {
//把刚刚更新的id为13的数据删除
userInfoMapperXML.deleteUser(13);
}

删除前:

删除后:

我们发现删除成功👇

闲聊:我们会发现当我们学习完 MyBatis 的注解操作之后再来学习 MyBatis 的 XML 操作就会简单很多~~

答疑:这个部分的 id 有啥用??👇

这个不是必须要加的~~

爱加不加,放在这就是表示主键,其他的都是普通键,如果你的主键是一样的,那你删了也行~~

我们删了之后也是正常走的👇

<?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="com.bit.mybatis.mapper.UserInfoMapperXML">
<resultMap id="BaseMap" type="com.bit.mybatis.model.UserInfo">
<!– <id property="id" column="id"></id>–>
<result property="deleteFlag" column="delete_flag"></result>
<result property="createTime" column="create_time"></result>
<result property="updateTime" column="update_time"></result>
</resultMap>

<select id="selectAll" resultType="com.bit.mybatis.model.UserInfo">
select * from user_info
<!– select id,username,`password`,age,gender,phone,–>
<!– delete_flag as deleteFlag,–>
<!– create_time as createTime,–>
<!– update_time as updateTime–>
<!– from user_info–>
</select>

依旧是有的👇

赞(0)
未经允许不得转载:171主机测评 » Java EE 进阶:8.MyBatis 操作数据库(入门)(第三弹)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址