MyBatis 入门

embedded/2025/2/1 14:32:04/

目录

一. MyBatis 概述

二. MyBatis 入门

1. 创建工程, 导入依赖

2. 数据准备

3. 配置数据库相关信息 

4. 编写持久层代码 

5. 编写测试代码

三. MyBatis基础操作.

1. 打印日志

2. 参数传递

3. 增 (Insert)

4. 删 (Delete)

5. 改 (Update)

6. 查 (Select)

(1) 起别名

(2) 结果映射

(3) 开启驼峰命名与蛇形命名转换

四. MyBatis XML配置文件

(1) 配置连接字符串和MyBatis

(2) 编写持久层代码

① 添加Mapper接口

② 添加UserInfoXMLMapper.xml

③ 单元测试

(3) 增删改查操作

① 增 (Insert)

② 删 (Delete)

③ 改 (Update)

④ 查 (Select)


一. MyBatis 概述

前面我们学习过使用JDBC编程对数据库进行操作. 不过JDBC对于数据库的操作过于麻烦, 所以我们在Spring中引入MyBatis框架, 来帮助我们对数据库进行操作.

MyBatis 是一款优秀的持久层框架, 用于简化JDBC的开发.

持久层(Mapper/Dao), 就是用来操作数据库的.

简单来说, MyBatis 是一个能够更简单地完成程序和数据库交互的框架. 接下来,我们就通过一个入门程序,让大家感受一下通过Mybatis如何操作数据 

二. MyBatis 入门

1. 创建工程, 导入依赖

MyBatis 是一个持久层框架, 具体的数据存储和数据操作还是在MySQL中进行的. 所以我们还需要添加MySQL驱动.

项目工程创建完成后, 我们就会发现: 在pom.xml文件中, 自动导入了Mybatis依赖和MySQL驱动依赖.

2. 数据准备

创建用户表:

-- 创建数据库 
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据 
USE mybatis_test;
-- 创建表[用户表] 
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now(),PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 
-- 添加用户信息 
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

创建对应的实体类 UserInfo: (其中实体类的属性名和表中的字段名 一一对应)

java">package com.jrj.mybatis;import lombok.Data;
import java.util.Date;@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;
}

3. 配置数据库相关信息 

MyBatis中 要连接数据库 需要配置数据库的相关参数, 包括数据库URL, 用户名, 密码, MySQL驱动类. 这些配置信息均在配置文件中完成

java"># 数据库连接配置 
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

如上代码, mybatis_test 就是数据库的名称.

[注意]: 如果password是纯数字的话, 需要在数字的的外围用单引号括起来.

4. 编写持久层代码 

java">package com.jrj.mybatis.mapper;import com.jrj.mybatis.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface UserInfoMapper {@Select("select * from userinfo")public List<UserInfo> selectAllUser();
}

@Mapper 注解:  表示MyBatis中的Mapper接口.

@Select 注解:  表示Select查询 (代表注解中方法的具体实现)

[注意]: 像上述代码这样返回多条数据的接口, 一定要用List来接收数据; MyBatis的持久层接口一般都叫 "xxxMapper".

5. 编写测试代码

自动生成:

在想要测试的接口中点击右键, 点击生成, 选择想要测试的方法, 即可生成测试代码.

三. MyBatis基础操作.

1. 打印日志

在Mybatis当中, 我们可以借助日志, 查看到sql语句的执行, 执行传递的参数以及执行结果. 在配置文件中进行配置即可.

java">mybatis:configuration: # 配置打印 MyBatis⽇志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置好之后, 重新运行程序, 即可看到SQL的执行内容.

2. 参数传递

如果我们现在需要查找 id=4 的用户, 对应的 sql语句 就是 select * from userinfo where id=4.

java">@Select("select * form userinfo where id = 4")
public UserInfo selectUser();

但是这样的话, 就只能查询到 id为4 用户的数据. 所以我们不建议把sql语句写死. 我们需要把 id 变为动态的数值.
解决办法就是在selectUser方法中添加一个参数(id), 将方法中的参数传递给sql语句.使用 #{} 的方式在sql语句中获取方法中传递的参数.

java">@Select("select * from userinfo where id = #{id}")
public UserInfo selectUser(Integer id);
java">void selectUser() {System.out.println(userInfoMapper.selectUser(4));
}

[注意]:

  • 如果参数只有一个, #{ } 内的属性名称可以随便写.
  • 如果参数有多个, 属性名和参数名必须保持一致; 或按照顺序对应(param1, param2…).

① 按名称对应

java">@Select("select * from userinfo where username = #{name} and id = #{id}")
public UserInfo selectUser2(String name,Integer id);
java">@Test
void selectUser2() {System.out.println(userInfoMapper.selectUser2("admin",1));
}

② 按顺序对应

java">    @Select("select * from userinfo where username = #{param1} and id = #{param2}")public UserInfo selectUser3(String name,Integer id);
java">    @Testvoid selectUser3() {System.out.println(userInfoMapper.selectUser3("admin",1));}

[注]: 也可以通过@Param注解, 设置参数的别名. 如果使用@Param设置别名, 注解中的别名必须和sql中的属性名保持一致. 举例如下:

java">@Select("select * from userinfo where id = #{ID}")
public UserInfo selectUser4(@Param("ID") Integer id);
java">@Test
void selectUser4() {System.out.println(userInfoMapper.selectUser4(1));
}

3. 增 (Insert)

sql语句: 

insert into userinfo (username, `password`, age, gender, phone) values ("zhaoliu","zhaoliu",19,1,"15585133024")

把SQL中的常量换为动态的参数.

Mapper接口:

java">@Insert("insert into userinfo (id,username,password,age,gender,phone) values (" +"#{id},#{username},#{password},#{age},#{gender},#{phone})")
public Integer insertUser1(UserInfo userInfo);

这里我们可以直接使用UserInfo对象的属性来获取参数:

java">@Test
void insertUser1() {UserInfo userInfo = new UserInfo();userInfo.setId(5);userInfo.setUsername("zhaoliu");userInfo.setPassword("zhaoliu");userInfo.setAge(19);userInfo.setGender(1);userInfo.setPhone("15585133024");userInfoMapper.insertUser1(userInfo);
}

如果设置了 @Param 属性,  #{...} 需要使用 参数. 属性 来获取.

返回主键
Insert语句默认返回的是受影响的行数.

但是有些情况下, 数据插入之后, 还需要有后续的关联操作, 需要获取到新插入的数据的id. 如果想要拿到自增id, 需要在Mapper接口的方法上添加一个Options的注解.

java">@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into userinfo (id,username,password,age,gender,phone) values (" +"#{id},#{username},#{password},#{age},#{gender},#{phone})")
public Integer insertUser2(UserInfo userInfo);

4. 删 (Delete)

sql语句:

delete from userinfo where id=6

把sql语句中的常量替换为动态参数. 

Mapper接口:

java">@Delete("delete from userinfo where id = #{id}")
public Integer deleteUser1(Integer id);
java">@Test
void deleteUser1() {System.out.println(userInfoMapper.deleteUser1(6));
}

5. 改 (Update)

sql语句:

update userinfo set username="zhaoliu" where id=5

把SQL中的常量替换为动态的参数

Mapper接口:

java">@Update("update userinfo set username = #{username} where id = #{id}")
public Integer updateUser(UserInfo userInfo);
java">@Test
void updateUser() {UserInfo userInfo = new UserInfo();userInfo.setId(5);userInfo.setUsername("tianqi");System.out.println(userInfoMapper.updateUser(userInfo));}

 

6. 查 (Select)

只有Java对象属性和数据库字段⼀模⼀样时,才会进行赋值.

当自动映射查询结果的时候, MyBatis会获取结果中返回的列名并在Java类中查找相同名字的属性(忽略大小写). 这意味着如果发现了ID列和id属性, MyBatis会将 ID列的值 赋给 id属性. 但是我们的创建时间, 更新时间, 删除逻辑数字: 在数据库中是蛇形结构的名字, 而在Java类中是小驼峰的格式.

问题如上图, 那如何解决这个问题呢?

(1) 起别名

在sql语句中, 给列名起别名, 保持 别名 和 实体类属性名 一致.

java">@Select("select id, username, `password`, age, gender, phone, " +"delete_flag as deleteFlag," +"create_time as createTime, update_time as updateTime from userinfo")
public List<UserInfo> selectAllUser2();

[注]: 当sql语句太长的时候,我们可以使用 + 进行拼接. 

(2) 结果映射

java">@Results({@Result(column = "delete_flag",property = "deleteFlag"),@Result(column = "create_time",property = "createTime"),@Result(column = "update_time",property = "updateTime")
})
@Select("select * from userinfo")
public List<UserInfo> selectAllUser3();
  • @Results 注解 中可以用大括号括起多个@Result映射. 
  • @Result前面的参数是表的字段名, 后面是Java类的属性. (字段与属性一一映射

如果其他sql也想复用这一组映射, 可以给这一组 @Results映射 自定义一个名称. 之后在想要复用这个sql映射的地方使用 @ResultMap(vlaue="映射名称") 来实现映射的复用.

java">@Results(id = "resultMap1",value = {@Result(column = "delete_flag",property = "deleteFlag"),@Result(column = "create_time",property = "createTime"),@Result(column = "update_time",property = "updateTime")})@Select("select * from userinfo")public List<UserInfo> selectAllUser3();@ResultMap(value = "resultMap1")@Select("select * from userinfo where id = #{id}")public UserInfo selectUser5(Integer id);

 @ResultMap注解 中的 value 的值和上面映射的 id 名字必须相同.

我们也可以在xml文件中使用 <resultMap> 和 <result> 标签来完成.

<resultMap id="BaseResultMap" type="com.jrj.forums.model.Article"><id column="id" jdbcType="BIGINT" property="id" /><result column="board_id" jdbcType="BIGINT" property="boardId" /><result column="user_id" jdbcType="BIGINT" property="userId" /><result column="title" jdbcType="VARCHAR" property="title" /><result column="visit_count" jdbcType="INTEGER" property="visitCount" /><result column="reply_count" jdbcType="INTEGER" property="replyCount" /><result column="like_count" jdbcType="INTEGER" property="likeCount" /><result column="state" jdbcType="TINYINT" property="state" /><result column="delete_state" jdbcType="TINYINT" property="deleteState" /><result column="create_time" jdbcType="TIMESTAMP" property="createTime" /><result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /></resultMap>

指定好结果映射之后, 就可以在对应的sql标签之后使用 resultMap 来指定结果映射.

<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
...
</select>

我们也可以使用 extends 来继承结果映射, 在继承过来的结果映射中添加还未存在的字段.

<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.jrj.forums.model.Article"><result column="content" jdbcType="LONGVARCHAR" property="content" />
</resultMap>

 

(3) 开启驼峰命名与蛇形命名转换

通常数据库列使用蛇形命名法进行命名(下划线分割各个单词), 而Java属性⼀般遵循驼峰命名法约定.
为了在这两种命名方式之间启用自动映射, 需要 将mapUnderscoreToCamelCase设置为true . 我们需要在配置文件中配置.

mybatis: configuration:map-underscore-to-camel-case: true #配置驼峰⾃动转换 

转换规则: abc_xyz --> abcXyz (蛇形转换为小驼峰).

而Java代码不用做任何处理:

java">@Select("select * from userinfo")
public List<UserInfo> selectAllUser();

 

四. MyBatis XML配置文件

MyBatis 的开发方式有两种:

1. 注解

2. XML

使用Mybatis的注解方式, 主要是来完成一些简单的增删改查功能. 如果需要实现复杂的SQL功能, 建议使用XML来配置映射语句 (也就是将SQL语句写在XML配置文件中). 

前面我们学习了注解方式, 下面我们来看XML方式:

这种开发方式大致分为两步:

(1) 配置 数据库连接字符串MyBatis.

(2) 编写持久层代码

(1) 配置连接字符串和MyBatis

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

mapper-locations 中的value值, classpath表示的是项目中的resource目录. mapper表示的是一个自定义目录. 一般我们使用xml操作数据库的代码都会单独放在一个mapper目录中, 之后**Mapper.xml表示的是以这个结尾的xml文件就是操作数据库的xml文件.

(2) 编写持久层代码

持久层代码分为两部分:

① 方法定义: Interface
② 方法实现: xxx.xml

 

① 添加Mapper接口

java">package com.jrj.mybatis.mapper;import com.jrj.mybatis.UserInfo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface UserInfoXMLMapper {public List<UserInfo> selectAllUser1();
}

② 添加UserInfoXMLMapper.xml

java"><?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.jrj.mybatis.mapper.UserInfoXMLMapper"></mapper>

mapper标签中加的是带有@Mapper注解接口的路径, 即想要通过MyBatis操作数据库的Mapper接口.

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

java"><?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.jrj.mybatis.mapper.UserInfoXMLMapper"><select id="selectAllUser1" resultType="com.jrj.mybatis.UserInfo">select * from userinfo</select>
</mapper>
  • 其中. select标签中 id="selectAllUser1" 代表的是Mapper中的方法名; resultType="com.jrj.mybatis.UserInfo" 代表的是sql查询之后返回的类型 (也就是我们开头定义的实体类)
  • 只有select类型的语句会有返回值的类型. [注意]: 是sql查询之后返回的类型, 不是接口返回值的类型. (sql查询之后返回的是UserInfo类型, 而接口返回的是List类型.)
  • 标签中间写的是sql语句.

我们还可以安装一个插件, 叫做MyBatisX, 这个插件可以自动帮助我们生成xml标签. 我们只需要写sql语句就行了.

③ 单元测试

进行单元测试时, 我们可以在Mapper上点击右键 --> 生成 --> 测试 --> 勾选想要测试的方法, 就会在test目录下自动生成测试类和测试方法, 其中测试方法的返回值必须为void.

java">@Test
void selectAllUser1() {List<UserInfo> list = userInfoXMLMapper.selectAllUser1();for (UserInfo userInfo: list){System.out.println(userInfo);}}

(3) 增删改查操作

① 增 (Insert)

UserInfoMapper接口:

java">public Integer insertUser(UserInfo userInfo);

 XML:

java"><insert id="insertUser">insert into userinfo (id,username,password,age,gender,phone) values (#{id},#{username},#{password},#{age},#{gender},#{phone})
</insert>

测试代码:

java">@Test
void insertUser() {UserInfo userInfo = new UserInfo();userInfo.setId(8);userInfo.setUsername("zhubajie");userInfo.setAge(22);userInfo.setPassword("6666666");userInfo.setGender(0);userInfo.setPhone("487362849326");userInfoXMLMapper.insertUser(userInfo);
}

与注解实现类似,要是在形参的前面加上 @Param注解 的话,在sql语句中的 #{ } 就必须使用对象名.属性名来访问.
Mapper接口: 

java">public Integer insertUser(@Param("userinfo") UserInfo userInfo);

XML:

java"><insert id="insertUser">insert into userinfo (id,username,password,age,gender,phone) values (#{userinfo.id},#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})
</insert>

② 删 (Delete)

③ 改 (Update)

④ 查 (Select)

删, 改, 查和增是同样的道理, 我们不再赘述.


http://www.ppmy.cn/embedded/158648.html

相关文章

p4:使用pytorch实现猴痘病识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 我的环境 语言环境&#xff1a;python 3.7.12 编译器&#xff1a;pycharm 深度学习环境&#xff1a;tensorflow 2.7.0 数据&#xff1a;本地数据集 一、代码 …

Kafa分区策略实现

引言 Kafka 的分区策略决定了生产者发送的消息会被分配到哪个分区中&#xff0c;合理的分区策略有助于实现负载均衡、提高消息处理效率以及满足特定的业务需求。 轮询策略&#xff08;默认&#xff09; 轮询策略是 Kafka 默认的分区策略&#xff08;当消息没有指定键时&…

【设计模式-行为型】迭代器模式

一、什么是迭代器模式 迭代器模式&#xff0c;顾名思义&#xff0c;同样的为了让大家更加了解啥是迭代器。我们通过电影情结来说明&#xff0c;不知道大家有没有看过一个剧烧脑的科幻大片--《盗梦空间》。影片讲述了由造梦师&#xff08;莱昂纳多迪卡普里奥扮演的&#xff09;带…

基于Python的药物相互作用预测模型AI构建与优化(下.代码部分)

四、特征工程 4.1 分子描述符计算 分子描述符作为量化分子性质的关键数值,能够从多维度反映药物分子的结构和化学特征,在药物相互作用预测中起着举足轻重的作用。RDKit 库凭借其强大的功能,为我们提供了丰富的分子描述符计算方法,涵盖了多个重要方面的分子性质。 分子量…

音视频多媒体编解码器基础-codec

如果要从事编解码多媒体的工作&#xff0c;需要准备哪些更为基础的内容&#xff0c;这里帮你总结完。 因为数据类型不同所以编解码算法不同&#xff0c;分为图像、视频和音频三大类&#xff1b;因为流程不同&#xff0c;可以分为编码和解码两部分&#xff1b;因为编码器实现不…

【2024年华为OD机试】(C卷,100分)- 检查是否存在满足条件的数字组合 (Java JS PythonC/C++)

一、问题描述 题目描述 给定一个正整数数组&#xff0c;检查数组中是否存在满足规则的数字组合。 规则&#xff1a;A B 2C 输入描述 第一行输出数组的元素个数。 接下来一行输出所有数组元素&#xff0c;用空格隔开。 输出描述 如果存在满足要求的数&#xff0c;在同…

1905电影网中国地区电影数据分析(二) - 数据分析与可视化

文章目录 前言一、数据分析1. 数据分析代码实现2. 分析后的数据截图2.1 描述性分析结果数据2.2 类别分布分析结果数据2.3 模式识别分析结果数据2.4 时间序列分析结果数据2.4.1 每年的电影发布数量2.4.2 按年份的评分趋势 2.5 相关性分析结果数据 二、数据可视化1. 描述性分析数…

007 JSON Web Token

文章目录 https://doc.hutool.cn/pages/jwt/#jwt%E4%BB%8B%E7%BB%8D JWT是一种用于双方之间安全传输信息的简洁的、URL安全的令牌标准。这个标准由互联网工程任务组(IETF)发表&#xff0c;定义了一种紧凑且自包含的方式&#xff0c;用于在各方之间作为JSON对象安全地传输信息。…