# mybatis-app
**Repository Path**: hrbu2024/mybatis-app
## Basic Information
- **Project Name**: mybatis-app
- **Description**: 学习Mybatis框架
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-10-21
- **Last Updated**: 2026-10-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
MyBatis
2.x之前 都 IBaits
3.x: MyBatis
# 创建聚合项目(环境搭建)
- mybatis-app(父项目)
- 在父项目不真实的添加依赖,只是管理依赖版本
- 00-mybatis-common
- 通用的代码(重复的代码)
- User实体类
- 工具
- 01-app-helloword
- 依赖 00-mybatis-common
- mysql-connector-j : version 8.4.0
- 02-app-知识点xxxx
- 依赖 00-mybatis-common
- mysql-connector-j : version 8.4.0
## 父项目
创建项目删掉src

## 创建通用的项目 00-mybatis-common
Java代码就可以 quiuckstart

```xml
4.0.0
com.neuedu.mybatis
mybatis-app
1.0
00-mybatis-common
jar
00-mybatis-common
UTF-8
```
### 删除测试类

## 01-app-helloword
第一个mybatis的入门项目
- quickstart:

### 添加Java类的签名(注释)
```
/***
*
* 项目名称: ${PROJECT_NAME}
* 类名称:${PACKAGE_NAME}
* 类描述: ${desc}
* 创建人:金山老师
* 创建时间:${YEAR}/${MONTH}/${DAY} ${HOUR}:${MINUTE}
* 版本:1.0
*
*/
```



### 调整 idea 中注释的缩进
java


# MyBaits介绍
[01.MyBatis框架](https://www.yuque.com/donghua-nhdx0/abx4x1/ih688kicram26y3i)
软件框架(software framework),通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。
框架的功能类似于基础设施,与具体的软件应用无关,但是提供并实现最为基础的软件架构和体系。
1. 为什么需要框架技术:
1. 1. 帮我们更快更好地构建程序
2. 是一个应用程序的半成品
3. 提供可重用的公共结构
4. 按一定规则组织的一组组件
1. 优势:
1. 1. 不用再考虑公共问题
2. 专心在业务实现上
3. 结构统一,易于学习、维护
4. 新手也可写出好程序
不要重复造轮子(Stop Trying to Reinvent the Wheel),已经成为开发人员的基本原则。
Java世界中的主流框架技术: Spring、SpringMVC、MyBatis、Struts、Hibernate、SpringBoot等。
- Hibernate: 重量级的框架 ORM ,不需要写代码
- MyBatis: 半自动的ORM 可以自主的掌握SQL (比Hibernate轻量)
- MyBatisPlus
## ORM :Object Relation Mapping
数据库中数据是以表的形式存在的,而java中使用的数据都是对象型的。所以不得不要将表数据转换成对象数据。 这样就会产生大量的没有技术含量的纯 “体力” 型代码。

MyBatis就是一个ORM框架。当然,也是一个持久层框架。
MyBatis封装了JDBC, 将数据库中的表数据自动封装到对象中。这样就可以以面向对象的方式操作数据了。它的出现,使得开发工作量变小了,可以将精力集中在业务逻辑的处理上。代码精简易读。
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。 也就是说:iBatis3.0之后都要改名为MyBatis 。
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
实际上,MyBatis最核心的功能,就是实现了**输入映射和输出映射**。
# 编写第一个入门程序
(01-app-helloworld)
## 分析过程(写代码的过程)
- 添加依赖
- mysql-connection-j: 8.4.0
- mybatis : 3.5.6
- junit:5.14.3
- 编写总的配置文件
- 环境信息: 数据库的url、用户名、密码 、数据库的驱动(msyql)
- 编写实体类
- SysUser
- SysRole
- SysMenu
- SysDept
- 单表的配置文件 SysUser.xml (所有sys_user的 sql)
- select * from sys_user -- > SysUser
- sleect * from sys_role --> SysRole
- 调用MyBaits 查询
## 添加依赖
pom.xml
```xml
4.0.0
com.neuedu.mybatis
mybatis-app
1.0
01-app-helloword
jar
01-app-helloword
http://maven.apache.org
UTF-8
org.junit.jupiter
junit-jupiter-api
5.14.4
test
com.mysql
mysql-connector-j
8.4.0
org.mybatis
mybatis
3.5.6
```
## 编写总的配置文件


SQlMapConfig.xml
```xml
```
## 编写SysUser实体类

```java
package com.neuedu.mybatis.po;
import java.util.Date;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.po
* 类描述: 用户表的实体类
* 创建人:金山老师
* 创建时间:2026/10/21 11:27
* 版本:1.0
*
*/
public class SysUser {
private Long userId ;
private Long deptId ;
private String userName ;
private String nickName ;
private String userType ;
private String email ;
private String phonenumber ;
private String sex ;
private String avatar ;
private String password ;
private String status ;
private String delFlag ;
private String loginIp ;
private Date loginDate ;
private Date pwdUpdateDate ;
private String createBy ;
private Date createTime ;
private String updateBy ;
private Date updateTime ;
private String remark ;
public SysUser() {
}
public SysUser(Long userId, Long deptId, String userName, String nickName, String userType, String email, String phonenumber, String sex, String avatar, String password, String status, String delFlag, String loginIp, Date loginDate, Date pwdUpdateDate, String createBy, Date createTime, String updateBy, Date updateTime, String remark) {
this.userId = userId;
this.deptId = deptId;
this.userName = userName;
this.nickName = nickName;
this.userType = userType;
this.email = email;
this.phonenumber = phonenumber;
this.sex = sex;
this.avatar = avatar;
this.password = password;
this.status = status;
this.delFlag = delFlag;
this.loginIp = loginIp;
this.loginDate = loginDate;
this.pwdUpdateDate = pwdUpdateDate;
this.createBy = createBy;
this.createTime = createTime;
this.updateBy = updateBy;
this.updateTime = updateTime;
this.remark = remark;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getLoginIp() {
return loginIp;
}
public void setLoginIp(String loginIp) {
this.loginIp = loginIp;
}
public Date getLoginDate() {
return loginDate;
}
public void setLoginDate(Date loginDate) {
this.loginDate = loginDate;
}
public Date getPwdUpdateDate() {
return pwdUpdateDate;
}
public void setPwdUpdateDate(Date pwdUpdateDate) {
this.pwdUpdateDate = pwdUpdateDate;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "SysUser{" +
"userId=" + userId +
", deptId=" + deptId +
", userName='" + userName + '\'' +
", nickName='" + nickName + '\'' +
", userType='" + userType + '\'' +
", email='" + email + '\'' +
", phonenumber='" + phonenumber + '\'' +
", sex='" + sex + '\'' +
", avatar='" + avatar + '\'' +
", password='" + password + '\'' +
", status='" + status + '\'' +
", delFlag='" + delFlag + '\'' +
", loginIp='" + loginIp + '\'' +
", loginDate=" + loginDate +
", pwdUpdateDate=" + pwdUpdateDate +
", createBy='" + createBy + '\'' +
", createTime=" + createTime +
", updateBy='" + updateBy + '\'' +
", updateTime=" + updateTime +
", remark='" + remark + '\'' +
'}';
}
}
```
## 编写映射文件(单表的SQL)
SysUser.xml
```xml
```
## 编写测试代码,执行sql语句
SysUserTest
```java
package com.neuedu.mybatis;
import com.neuedu.mybatis.po.SysUser;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;
import java.io.InputStream;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/21 11:40
* 版本:1.0
*
*/
public class SysUserTest {
@Test
public void test(){
try {
//读取配置文件,获得配置文件信息
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过配置信息创建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(input);
//通过SqlSessionFactory打开数据库会话
SqlSession sqlSession = ssf.openSession();
//通过SqlSession的selectOne(返回一行记录时使用)方法执行sql语句
List userList = sqlSession.selectList("SysUser.queryList");
System.out.println(userList);
//关闭数据库会话
sqlSession.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
使用ResultMap
因为数据库中的字段有下划线,而Java中的属性区分大小写 需要绑定映射关系
```xml
```
# 其他类型SQL语句
- select * from sys_user
- select * from sys_user where userid = ?
- update
- insert
- delete
- select count(1) from sys_user ;
## 根据主键查询单条记录
- 在SysUser.xml中添加SQL语句
- 测试
```xml
```
```java
@Test
public void testOne(){
try {
//读取配置文件,获得配置文件信息
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过配置信息创建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(input);
//通过SqlSessionFactory打开数据库会话
SqlSession sqlSession = ssf.openSession();
//通过SqlSession的selectOne(返回一行记录时使用)方法执行sql语句
Long id = 2L;
SysUser user = sqlSession.selectOne("SysUser.queryById", id);
System.out.println(user);
//关闭数据库会话
sqlSession.close();
} catch (Exception e) {
e.printStackTrace();
}
}
```
## 更新SQL
```xml
!-- 根据主键更新 -->
UPDATE
`his`.`sys_user`
SET
`user_id` = #{userId},
`dept_id` = #{deptId},
`user_name` = #{userName},
`nick_name` = #{nickName},
`user_type` = #{userType},
`email` = #{email},
`phonenumber` = #{phonenumber} ,
`sex` = #{sex},
`avatar` = #{avatar},
`password` = #{password},
`status` = #{status},
`del_flag` = #{delFlag},
`login_ip` = #{loginIp},
`login_date` = #{loginDate},
`pwd_update_date` = #{pwdUpdateDate},
`create_by` = #{createBy},
`create_time` = #{createTime},
`update_by` = #{updateBy},
`update_time` = #{updateTime},
`remark` = #{remark}
WHERE `user_id` = #{userId} ;
```
````java
@Test
public void testUpdateById(){
SqlSession session = null;
try {
//读取配置文件,获得配置文件信息
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过配置信息创建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(input);
//通过SqlSessionFactory打开数据库会话
session = ssf.openSession();
//通过SqlSession的selectOne(返回一行记录时使用)方法执行sql语句
Long id = 2L;
SysUser user = session.selectOne("SysUser.queryById", id);
// System.out.println(user);
user.setEmail("jshan@neueedu.com");
user.setPhonenumber("13888888888");
user.setSex("2");
//更新操作
int count = session.update("SysUser.updateById",user);
System.out.println("count = " + count);
session.commit(); //提交
} catch (Exception e) {
session.rollback();// 回关
e.printStackTrace();
}finally {
if(session != null){
session.close(); //关闭资源
}
}
}
````
## 插入操作
```xml
INSERT INTO `his`.`sys_user` (
`dept_id`,
`user_name`,
`nick_name`,
`user_type`,
`email`,
`phonenumber`,
`sex`,
`avatar`,
`password`,
`status`,
`login_ip`,
`login_date`,
`pwd_update_date`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES
(
#{deptId},
#{userName},
#{nickName},
#{userType},
#{email},
#{phonenumber},
#{sex},
#{avatar},
#{password},
#{status},
#{loginIp},
#{loginDate},
#{pwdUpdateDate},
#{createBy},
#{createTime},
#{updateBy},
#{updateTime},
#{remark}
) ;
```
测试类
````java
@Test
public void testInsert(){
SqlSession session = null;
try {
//读取配置文件,获得配置文件信息
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过配置信息创建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(input);
//通过SqlSessionFactory打开数据库会话
session = ssf.openSession();
//插入操作
SysUser user = new SysUser();
user.setDeptId(101L);
user.setUserName("jshan");
user.setPassword("145648964136153213546513615");
user.setNickName("jshan");
user.setUserType("1");
user.setEmail("jshan@neueedu.com");
user.setPhonenumber("13888888888");
user.setSex("2");
user.setStatus("1");
user.setCreateBy("1");
user.setCreateTime(new java.util.Date());
user.setUpdateBy("1");
user.setUpdateTime(new java.util.Date());
int count = session.insert("SysUser.insert",user);
System.out.println("count = " + count);
session.commit(); //提交
} catch (Exception e) {
e.printStackTrace();
if(session != null){
session.rollback(); //回滚数据
}
}finally {
if(session != null){
session.close(); //关闭资源
}
}
}
````
## 删除操作
```xml
delete from sys_user where user_id = #{userId}
```
测试类
```java
@Test
public void testDeleteById (){
SqlSession session = null;
try {
//读取配置文件,获得配置文件信息
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过配置信息创建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(input);
//通过SqlSessionFactory打开数据库会话
session = ssf.openSession();
long id = 102L;
int count = session.insert("SysUser.deleteById",id);
System.out.println("删除 count = " + count);
session.commit(); //提交
} catch (Exception e) {
e.printStackTrace();
if(session != null){
session.rollback(); //回滚数据
}
}finally {
if(session != null){
session.close(); //关闭资源
}
}
}
```

# 封装Dao
## 封装MyBatisUtils
```java
package com.neuedu.mybatis.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.utils
* 类描述: MyBatis工具
* 创建人:金山老师
* 创建时间:2026/10/21 16:18
* 版本:1.0
*
*/
public class MyBatisUtil {
private static SqlSessionFactory sessionFactory ;
/**
* 单利模式 创建 SqlSessionFactory 重量级的对象,现成安全的
* @return
* @throws IOException
*/
public synchronized static SqlSessionFactory getSqlSessionFactory() throws IOException {
if(sessionFactory == null){
//读取配置文件,获得配置文件信息
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过配置信息创建SqlSessionFactory
sessionFactory = new SqlSessionFactoryBuilder().build(input);
}
return sessionFactory;
}
}
```
## SysUserDao
```java
package com.neuedu.mybatis.dao;
import com.neuedu.mybatis.po.SysUser;
import com.neuedu.mybatis.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.dao
* 类描述: Dao
* 创建人:金山老师
* 创建时间:2026/10/21 16:21
* 版本:1.0
*
*/
public class SysUserDao {
public List selectList(){
List list = null ;
SqlSession session = null;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession();
//通过SqlSession的selectOne(返回一行记录时使用)方法执行sql语句
list = session.selectList("SysUser.selectList");
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session == null){
// 关闭数据库会话
session.close();
}
}
return list;
}
public SysUser selectById( Long id ){
SysUser user = null;
SqlSession session = null;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession();
user = session.selectOne("SysUser.selectById", id);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session == null){
// 关闭数据库会话
session.close();
}
}
return user;
}
public int updateById(SysUser user){
SqlSession session = null;
int count = 0;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession(false);
//更新操作
count = session.update("SysUser.updateById",user);
session.commit(); //提交
} catch (Exception e) {
session.rollback();// 回关
e.printStackTrace();
}finally {
if(session != null){
session.close(); //关闭资源
}
}
return count;
}
public int insert(SysUser user){
SqlSession session = null;
int count = 0;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession(false);
count = session.insert("SysUser.insert",user);
session.commit(); //提交
} catch (Exception e) {
e.printStackTrace();
if(session != null){
session.rollback(); //回滚数据
}
}finally {
if(session != null){
session.close(); //关闭资源
}
}
return count;
}
public int deleteById (long id ){
SqlSession session = null;
int count = 0;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession(false);
count = session.delete("SysUser.deleteById",id);
session.commit(); //提交
} catch (Exception e) {
e.printStackTrace();
if(session != null){
session.rollback(); //回滚数据
}
}finally {
if(session != null){
session.close(); //关闭资源
}
}
return count;
}
}
```
## 常见错误
```shell
D:\app\Java\jdk-21\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\app\JetBrains\IntelliJ IDEA 2024.3.1.1\lib\idea_rt.jar=50609:D:\app\JetBrains\IntelliJ IDEA 2024.3.1.1\bin" -javaagent:C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2024.3\captureAgent\debugger-agent.jar -Dkotlinx.coroutines.debug.enable.creation.stack.trace=false -Ddebugger.agent.enable.coroutines=true -Dkotlinx.coroutines.debug.enable.flows.stack.trace=true -Dkotlinx.coroutines.debug.enable.mutable.state.flows.stack.trace=true -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath "C:\Users\Administrator\.m2\repository\org\junit\platform\junit-platform-launcher\1.14.4\junit-platform-launcher-1.14.4.jar;C:\Users\Administrator\.m2\repository\org\junit\platform\junit-platform-engine\1.14.4\junit-platform-engine-1.14.4.jar;C:\Users\Administrator\.m2\repository\org\opentest4j\opentest4j\1.3.0\opentest4j-1.3.0.jar;C:\Users\Administrator\.m2\repository\org\junit\platform\junit-platform-commons\1.14.4\junit-platform-commons-1.14.4.jar;C:\Users\Administrator\.m2\repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;C:\Users\Administrator\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.14.4\junit-jupiter-engine-5.14.4.jar;C:\Users\Administrator\.m2\repository\org\junit\jupiter\junit-jupiter-api\5.14.4\junit-jupiter-api-5.14.4.jar;D:\app\JetBrains\IntelliJ IDEA 2024.3.1.1\lib\idea_rt.jar;D:\app\JetBrains\IntelliJ IDEA 2024.3.1.1\plugins\junit\lib\junit5-rt.jar;D:\app\JetBrains\IntelliJ IDEA 2024.3.1.1\plugins\junit\lib\junit-rt.jar;D:\workspace\mybatis-app\01-app-helloword\target\test-classes;D:\workspace\mybatis-app\01-app-helloword\target\classes;D:\workspace\mybatis-app\00-mybatis-common\target\classes;D:\app\apache-maven-3.9.9\jarrepository\org\junit\jupiter\junit-jupiter-api\5.14.4\junit-jupiter-api-5.14.4.jar;D:\app\apache-maven-3.9.9\jarrepository\org\opentest4j\opentest4j\1.3.0\opentest4j-1.3.0.jar;D:\app\apache-maven-3.9.9\jarrepository\org\junit\platform\junit-platform-commons\1.14.4\junit-platform-commons-1.14.4.jar;D:\app\apache-maven-3.9.9\jarrepository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;D:\app\apache-maven-3.9.9\jarrepository\com\mysql\mysql-connector-j\8.4.0\mysql-connector-j-8.4.0.jar;D:\app\apache-maven-3.9.9\jarrepository\com\google\protobuf\protobuf-java\3.25.1\protobuf-java-3.25.1.jar;D:\app\apache-maven-3.9.9\jarrepository\org\mybatis\mybatis\3.5.6\mybatis-3.5.6.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 com.neuedu.mybatis.dao.SysUserDaoTest,selectById
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for SysUser.selectById1111
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for SysUser.selectById1111
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
at com.neuedu.mybatis.dao.SysUserDao.selectById(SysUserDao.java:66)
at com.neuedu.mybatis.dao.SysUserDaoTest.selectById(SysUserDaoTest.java:36)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:786)
at org.junit.platform.commons.support.ReflectionSupport.invokeMethod(ReflectionSupport.java:514)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:161)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:152)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:91)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:112)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:94)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:93)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:87)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$4(TestMethodTestDescriptor.java:221)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:217)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:159)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:70)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:157)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:147)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:145)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:144)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:101)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:161)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:147)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:145)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:144)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:101)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:161)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:147)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:145)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:144)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:101)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.executeEngine(EngineExecutionOrchestrator.java:230)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.failOrExecuteEngine(EngineExecutionOrchestrator.java:204)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:172)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:101)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:64)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:150)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:63)
user = null
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:109)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:91)
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
at org.junit.platform.launcher.core.InterceptingLauncher.lambda$execute$1(InterceptingLauncher.java:39)
at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
at org.junit.platform.launcher.core.InterceptingLauncher.execute(InterceptingLauncher.java:38)
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:66)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for SysUser.selectById1111
at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:1031)
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:821)
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:814)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:146)
... 78 more
Process finished with exit code 0
```
# 练习Dao的封装
以 sys_role表为例演示
## 实体类(SysRole)
```java
package com.neuedu.mybatis.po;
import java.util.Date;
// import java.lang.String;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.po
* 类描述: 练习的sys_role实体
* 创建人:金山老师
* 创建时间:2026/10/26 08:52
* 版本:1.0
*
*/
public class SysRole {
//属性
private Long roleId ; // '角色ID',
private String roleName ; // '角色名称',
private String roleKey ; // ` '角色权限字符串',
private String roleSort ; // '显示顺序',
private String dataScope ; // '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)',
private Integer menuCheckStrictly ; // '菜单树选择项是否关联显示',
private Integer deptCheckStrictly ; // '部门树选择项是否关联显示',
private String status ; // ` '角色状态(0正常 1停用)',
private String delFlag ; // ` '删除标志(0代表存在 2代表删除)',
private String creatBy ; // '创建者',
private Date createTime ; // ` '创建时间',
private String updateBy ; // ` '更新者',
private Date updateTime ; // ` '更新时间',
private String remark ; // '备注',
//构造器
public SysRole() {
}
public SysRole(Long roleId, String roleName, String roleKey, String roleSort, String dataScope, Integer menuCheckStrictly, Integer deptCheckStrictly, String status, String delFlag, String creatBy, Date createTime, String updateBy, Date updateTime, String remark) {
this.roleId = roleId;
this.roleName = roleName;
this.roleKey = roleKey;
this.roleSort = roleSort;
this.dataScope = dataScope;
this.menuCheckStrictly = menuCheckStrictly;
this.deptCheckStrictly = deptCheckStrictly;
this.status = status;
this.delFlag = delFlag;
this.creatBy = creatBy;
this.createTime = createTime;
this.updateBy = updateBy;
this.updateTime = updateTime;
this.remark = remark;
}
//生成setter 、getter
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleKey() {
return roleKey;
}
public void setRoleKey(String roleKey) {
this.roleKey = roleKey;
}
public String getRoleSort() {
return roleSort;
}
public void setRoleSort(String roleSort) {
this.roleSort = roleSort;
}
public String getDataScope() {
return dataScope;
}
public void setDataScope(String dataScope) {
this.dataScope = dataScope;
}
public Integer getMenuCheckStrictly() {
return menuCheckStrictly;
}
public void setMenuCheckStrictly(Integer menuCheckStrictly) {
this.menuCheckStrictly = menuCheckStrictly;
}
public Integer getDeptCheckStrictly() {
return deptCheckStrictly;
}
public void setDeptCheckStrictly(Integer deptCheckStrictly) {
this.deptCheckStrictly = deptCheckStrictly;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getCreatBy() {
return creatBy;
}
public void setCreatBy(String creatBy) {
this.creatBy = creatBy;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
//toString
@Override
public String toString() {
return "SysRole{" +
"roleId=" + roleId +
", roleName='" + roleName + '\'' +
", roleKey='" + roleKey + '\'' +
", roleSort='" + roleSort + '\'' +
", dataScope='" + dataScope + '\'' +
", menuCheckStrictly=" + menuCheckStrictly +
", deptCheckStrictly=" + deptCheckStrictly +
", status='" + status + '\'' +
", delFlag='" + delFlag + '\'' +
", creatBy='" + creatBy + '\'' +
", createTime=" + createTime +
", updateBy='" + updateBy + '\'' +
", updateTime='" + updateTime + '\'' +
", remark=" + remark +
'}';
}
}
```
## 编写映射文件(SQL)
参考SysUser.xml编写SysRole.xml
- selectList
- selectById
- insert
- updateById
- deleteById
```xml
UPDATE
`sys_role`
SET
`role_name` = #{roleName},
`role_key` = #{roleKey},
`role_sort` = #{roleSort},
`data_scope` = #{dataScope},
`menu_check_strictly` = #{menuCheckStrictly},
`dept_check_strictly` = #{deptCheckStrictly},
`status` = #{status},
`del_flag` = #{delFlag},
`create_by` = #{createBy},
`create_time` = #{createTime},
`update_by` = #{updateBy},
`update_time` = #{updateTime},
`remark` = #{remark}
WHERE `role_id` = #{roleId} ;
INSERT INTO `his`.`sys_role` (
`role_name`,
`role_key`,
`role_sort`,
`data_scope`,
`menu_check_strictly`,
`dept_check_strictly`,
`status`,
`del_flag`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES
(
#{roleName},
#{roleKey},
#{roleSort},
#{dataScope},
#{menuCheckStrictly},
#{deptCheckStrictly} ,
#{status},
#{delFlag},
#{createBy},
#{createTime},
#{updateBy},
#{updateTime},
#{remark}
) ;
delete from sys_role where role_id = #{roleId}
```
## 在SqlMapConfig.xml中添加

## SysRoleDao
```java
package com.neuedu.mybatis.dao;
import com.neuedu.mybatis.po.SysRole;
import com.neuedu.mybatis.po.SysUser;
import com.neuedu.mybatis.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.dao
* 类描述: Dao
* 创建人:金山老师
* 创建时间:2026/10/21 16:21
* 版本:1.0
*
*/
public class SysRoleDao {
public List selectList(){
List list = null ;
SqlSession session = null;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession();
//通过SqlSession的selectOne(返回一行记录时使用)方法执行sql语句
list = session.selectList("SysRole.selectList");
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session == null){
// 关闭数据库会话
session.close();
}
}
return list;
}
public SysRole selectById( Long id ){
SysRole role = null;
SqlSession session = null;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession();
role = session.selectOne("SysRole.selectById", id);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session == null){
// 关闭数据库会话
session.close();
}
}
return role;
}
public int updateById(SysRole role){
SqlSession session = null;
int count = 0;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession(false);
//更新操作
count = session.update("SysRole.updateById",role);
session.commit(); //提交
} catch (Exception e) {
session.rollback();// 回关
e.printStackTrace();
}finally {
if(session != null){
session.close(); //关闭资源
}
}
return count;
}
public int insert(SysRole role){
SqlSession session = null;
int count = 0;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession(false);
count = session.insert("SysRole.insert",role);
session.commit(); //提交
} catch (Exception e) {
e.printStackTrace();
if(session != null){
session.rollback(); //回滚数据
}
}finally {
if(session != null){
session.close(); //关闭资源
}
}
return count;
}
public int deleteById (long id ){
SqlSession session = null;
int count = 0;
try {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
session = factory.openSession(false);
count = session.delete("SysRole.deleteById",id);
session.commit(); //提交
} catch (Exception e) {
e.printStackTrace();
if(session != null){
session.rollback(); //回滚数据
}
}finally {
if(session != null){
session.close(); //关闭资源
}
}
return count;
}
}
```
单元测试
```
package com.neuedu.mybatis.dao;
import com.neuedu.mybatis.po.SysRole;
import com.neuedu.mybatis.po.SysUser;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.dao
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/26 09:10
* 版本:1.0
*
*/
class SysRoleDaoTest {
SysRoleDao sysRoleDao = new SysRoleDao();
@Test
void selectList() {
List sysRoles = sysRoleDao.selectList();
sysRoles.forEach(System.out::println);
}
@Test
void selectById() {
}
@Test
void updateById() {
}
@Test
void insert() {
}
@Test
void deleteById() {
}
}
```
# 使用Mapper(接口)替换Dao
SysUserDao 他的实现类(MyBatis帮我们实现过程)
需要满足几个规则
- 接口中的方法要求跟xml中sql语句的id一致
- 方法的参数类型需要跟SQL语句中的parameterType 一致
- 映射文件中(XML)中的namespace 需要跟 接口名称一致(全限定名 :包名+类名 com.neuedu.myabtis.mapper.SysUserMapper)
- 更新类型的sql 对应的接口方法的返回值是数字类型(int、long) (update、insert、delete)
- 返回类型是集合自动调用selectList
- 结果是一条 可以使用selectList
- 返回类型是单条的自动调用selectOne
- 如果结果是多条的不能用selectOne 会报错
- selectOne的底层实际还是调用selectList ,自动从集合中取出第一条 ,如果集合大于1 会报错
-

```java
package com.neuedu.mybatis.dao;
import com.neuedu.mybatis.po.SysUser;
import com.neuedu.mybatis.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.dao
* 类描述: Dao
* 创建人:金山老师
* 创建时间:2026/10/21 16:21
* 版本:1.0
*
*/
public interface SysUserMapper {
public List selectList();
public SysUser selectById( Long id );
public int updateById(SysUser user);
public int insert(SysUser user);
public int deleteById (long id );
}
```
## 创建项目
02-app-mapper

## 添加依赖
- junit
- mysql
- mybaits
- 01-common
编写pom.xml ALT+SHIFT+L
```xml
4.0.0
com.neuedu.mybatis
mybatis-app
1.0
02-app-mapper
jar
02-app-mapper
UTF-8
com.neuedu.mybatis
00-mybatis-common
1.0
org.junit.jupiter
junit-jupiter-api
5.14.4
test
com.mysql
mysql-connector-j
8.4.0
compile
org.mybatis
mybatis
3.5.6
```
## 编写实体类
在00-mybatis-common项目中已经编写完的实体类、工具

## 编写配置文件
- 总的SqlMapConfig.xml
- 映射文件
- SysUserMapper.xml
- SysRoleMapper.xml
### SqlMapConfig.xml
```xml
```
### 在src/main/resources/mapper编写两个映射文件
SysRoleMapper.xml
```xml
UPDATE
`sys_role`
SET
`role_name` = #{roleName},
`role_key` = #{roleKey},
`role_sort` = #{roleSort},
`data_scope` = #{dataScope},
`menu_check_strictly` = #{menuCheckStrictly},
`dept_check_strictly` = #{deptCheckStrictly},
`status` = #{status},
`del_flag` = #{delFlag},
`create_by` = #{createBy},
`create_time` = #{createTime},
`update_by` = #{updateBy},
`update_time` = #{updateTime},
`remark` = #{remark}
WHERE `role_id` = #{roleId} ;
INSERT INTO `his`.`sys_role` (
`role_name`,
`role_key`,
`role_sort`,
`data_scope`,
`menu_check_strictly`,
`dept_check_strictly`,
`status`,
`del_flag`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES
(
#{roleName},
#{roleKey},
#{roleSort},
#{dataScope},
#{menuCheckStrictly},
#{deptCheckStrictly} ,
#{status},
#{delFlag},
#{createBy},
#{createTime},
#{updateBy},
#{updateTime},
#{remark}
) ;
delete from sys_role where role_id = #{roleId}
```
SysUserMapper.xml
```xml
UPDATE
`his`.`sys_user`
SET
`user_id` = #{userId},
`dept_id` = #{deptId},
`user_name` = #{userName},
`nick_name` = #{nickName},
`user_type` = #{userType},
`email` = #{email},
`phonenumber` = #{phonenumber} ,
`sex` = #{sex},
`avatar` = #{avatar},
`password` = #{password},
`status` = #{status},
`del_flag` = #{delFlag},
`login_ip` = #{loginIp},
`login_date` = #{loginDate},
`pwd_update_date` = #{pwdUpdateDate},
`create_by` = #{createBy},
`create_time` = #{createTime},
`update_by` = #{updateBy},
`update_time` = #{updateTime},
`remark` = #{remark}
WHERE `user_id` = #{userId} ;
INSERT INTO `his`.`sys_user` (
`dept_id`,
`user_name`,
`nick_name`,
`user_type`,
`email`,
`phonenumber`,
`sex`,
`avatar`,
`password`,
`status`,
`login_ip`,
`login_date`,
`pwd_update_date`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES
(
#{deptId},
#{userName},
#{nickName},
#{userType},
#{email},
#{phonenumber},
#{sex},
#{avatar},
#{password},
#{status},
#{loginIp},
#{loginDate},
#{pwdUpdateDate},
#{createBy},
#{createTime},
#{updateBy},
#{updateTime},
#{remark}
) ;
delete from sys_user where user_id = #{userId}
```
## 编写Mapper接口
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.po.SysRole;
import com.neuedu.mybatis.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.mapper
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/26 10:40
* 版本:1.0
*
*/
public interface SysRoleMapper {
public List selectList();
public SysRole selectById( Long id );
public int updateById(SysRole role);
public int insert(SysRole role);
public int deleteById (long id );
}
```
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.po.SysUser;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.mapper
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/26 10:40
* 版本:1.0
*
*/
public interface SysUserMapper {
public List selectList();
public SysUser selectById( Long id );
public int updateById(SysUser user);
public int insert(SysUser user);
public int deleteById (long id );
}
```
## 使用SysRoleMapper接口的代理对象(MyBatis创建的实现过程)
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.po.SysUser;
import com.neuedu.mybatis.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.mapper
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/26 10:43
* 版本:1.0
*
*/
class SysUserMapperTest {
@Test
void selectList() throws IOException {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//通过SqlSessionFactory打开数据库会话
SqlSession session = factory.openSession();
//获取 SysUserMapper接口的实现类(代理模式)
/**
*
* session.getMapper(SysUserMapper.class);
*
* 让MyBatis 帮我生成一个 SysUserMapper的实现过程
*
*/
SysUserMapper mapper = session.getMapper(SysUserMapper.class);
List sysUsers = mapper.selectList();
sysUsers.forEach(System.out::println);
}
@Test
void selectById() {
}
@Test
void updateById() {
}
@Test
void insert() {
}
@Test
void deleteById() {
}
}
```
## 配置,输出sql 语句
修改全局的配置文件 SqlMapConfig.xml
[MyBatis 3 | 配置 – mybatis](https://mybatis.org/mybatis-3/zh_CN/configuration.html#settings)
## MyBatis核心接口和类
1. SqlSessionFactoryBuilder负责构建SqlSessionFactory,并且提供了多个build()方法的重载。也就是说:此对象可以从xml配置文件,或从Configuration对象来构建SqlSessionFactory。
2. SqlSessionFactory就是创建SqlSession实例的工厂。通过openSession方法来获取SqlSession对象。而且,SqlSessionFactory一旦被创建,那么在整个应用程序期间都存在。重量级对象
3. SqlSession是一个面向程序员的接口,它提供了面向数据库执行sql命令所需的所有方法。SqlSession对应一次数据库会话,它是线程不安全的。
## 使用基于Mapper的方式新增功能
新增SQL SysUserMapper.xml
```xml
```
在接口中添加 SysUserMapper.java
```java
public Long total( );
```
# MyBaits的扩展
- 属性配置
- 类型别名
- mapper统一映射
新建一个项目

## 03-app-mybatis-extension
搭建Mybatis工程
- 添加依赖
- myatbis
- junit
- mysql
- 00-mybatis-common
- 编写SqlMapConfig.xml
- 编写实体类(**00-mybatis-common** 已经写过了)
- 编写映射文件(SysUserMapper、SysRoleMapper **Java、xml**)
编写测试类测试Mapper的功能
## 扩展的知识点
类型别名

# {}: 表示sql参数,一个占位符。
当parameterType属性为对象类型时:#{} 中的参数名为对象的属性名。 当parameterType属性为单个值时,参数名可以任意。
从映射文件中可以看到:MyBatis会根据字段名与实体对象中的属性名进行映射,从而实现自动将查询数据注入到实体对象的每一个属性中。这就是输出映射。
#{} : 使用 预编译的SQL,会有绑定变量,SQL中是 带 ?
${} 使用字符串拼接的能力 会有SQL注入的问题
# 通过包扫描的形式注册Mapper
com.neuedu.mybaits.mapper.SysUserMapper.java
com.neuedu.mybaits.mapper.SysUserMapper.xml
注意在resource 中创建多级目录中间使用 "/"


# 常用数据库操作
- parameterType="com.neuedu.mybatis.po.SysUser"
- #{nickName} nickName 是 SysUser中的属性
- #{sex} sex是 SysUser中的属性
- parameterType="long、int、String、double、char"
- #{写啥都行}
## 6.1.多条件查询
```xml
```
```java
public List selectListWithCondition(SysUser sysUser);
```
## 6.2.转义字符查询

## 6.3.返回单值查询
## 6.4.插入(不获取主键)
insert
## 6.5.插入(获取主键)
## 6.6.插入(获取主键)
## 6.7.修改
## 6.8.删除
# 多表关联查询
搭建工程

## 添加依赖
- junit
- mysql
- mybaits
- lombok:简化实体类的编写 (属性、setter getter、constructer、toString )
pom.xml
```xml
4.0.0
com.neuedu.mybatis
mybatis-app
1.0
06-app-association
jar
06-app-association
http://maven.apache.org
UTF-8
org.junit.jupiter
junit-jupiter-api
test
com.mysql
mysql-connector-j
org.mybatis
mybatis
org.projectlombok
lombok
```
## 编写核心配置文件
SqlMapConfig.xlm
```xml
```
## 编写实体类
使用lombok 的注解代替 setter、getter、等
```java
package com.neuedu.mybatis.po;
import lombok.*;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.po
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/28 10:53
* 版本:1.0
*
* Date java.util.Date 旧的
*
*/
// @NoArgsConstructor //帮我们生成无参构造器
// @AllArgsConstructor //帮我们生成全参构造器
// @Setter
// @Getter
// @ToString
// @EqualsAndHashCode
@Data //Equivalent to @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode.
public class Emp {
private Integer empno ;
private String ename ;
private String job ;
private Integer mgr ;
private Date hiredate ;
private Double sal ;
private String comm ;
private Double deptno ;
public static void main(String[] args) {
Emp emp = new Emp();
emp.setEmpno(111);
}
}
```
打开idea 的开关

## 编写CRUD的SQL语句
EmpMapper.xml
```xml
`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`
UPDATE
`emp`
`ename` = #{ename},
`job` = #{job},
`mgr` = #{mgr},
`hiredate` = #{hiredate},
`sal` = #{sal},
`comm` = #{comm},
`deptno` = #{deptno},
WHERE `empno` = #{empno} ;
INSERT INTO `emp`
`empno` ,
`ename` ,
`job` ,
`mgr` ,
`hiredate` ,
`sal` ,
`comm` ,
`deptno` ,
VALUES
#{empno},
#{ename},
#{job},
#{mgr},
#{hiredate},
#{sal},
#{comm},
#{deptno},
delete from emp where empno = #{empno}
```
## 编写EmpMapper
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.po.Emp;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.mapper
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/26 10:40
* 版本:1.0
*
*/
public interface EmpMapper {
public List selectList();
public Emp selectById( int id );
public long total( );
public int updateById(Emp emp);
public int insert(Emp emp);
public int deleteById (int id );
}
```
## 编写工具类
```java
package com.neuedu.mybatis.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.utils
* 类描述: MyBatis工具
* 创建人:金山老师
* 创建时间:2026/10/21 16:18
* 版本:1.0
*
*/
public class MyBatisUtil {
private static SqlSessionFactory sessionFactory ;
/**
* 单利模式 创建 SqlSessionFactory 重量级的对象,现成安全的
* @return
* @throws IOException
*/
public synchronized static SqlSessionFactory getSqlSessionFactory() throws IOException {
if(sessionFactory == null){
//读取配置文件,获得配置文件信息
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过配置信息创建SqlSessionFactory
sessionFactory = new SqlSessionFactoryBuilder().build(input);
}
return sessionFactory;
}
}
```
## 编写单元测试
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.po.Emp;
import com.neuedu.mybatis.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.mapper
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/28 11:30
* 版本:1.0
*
*/
class EmpMapperTest {
SqlSession session = null;
EmpMapper empMapper = null;
//每一个单元测试(@Test)方法之前都要做的事儿,
@BeforeEach
public void setup() throws IOException {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
// 通过SqlSessionFactory打开数据库会话
session = factory.openSession();
empMapper = session.getMapper(EmpMapper.class);
}
@Test
void selectList() {
List emps = empMapper.selectList();
emps.forEach(System.out::println);
}
@Test
void selectById() {
}
@Test
void total() {
}
@Test
void updateById() {
}
@Test
void insert() {
}
@Test
void deleteById() {
}
}
```

## 完成Dept表的CRUD
CRUD 指的是 Create(创建)、Read(读取)、Update(更新)和 Delete(删除),即软件系统中对数据的增删改查操作,是数据库与 API 设计的基础功能
```java
package com.neuedu.mybatis.po;
import lombok.Data;
import java.util.Date;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.po
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/28 10:53
* 版本:1.0
*
* Date java.util.Date 旧的
*
*/
// @NoArgsConstructor //帮我们生成无参构造器
// @AllArgsConstructor //帮我们生成全参构造器
// @Setter
// @Getter
// @ToString
// @EqualsAndHashCode
@Data //Equivalent to @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode.
public class Dept {
private Integer deptno;
private String dname;
private String loc;
}
```
```xml
UPDATE
`emp`
set `dname` = #{dname},
`loc` = #{loc}
WHERE `deptno` = #{deptno};
INSERT INTO `test`.`dept` (`deptno`, `dname`, `loc`)
VALUES
(#{deptno}, #{dname}, #{loc}) ;
delete from dept where deptno = #{deptno}
```
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.po.Dept;
import com.neuedu.mybatis.po.Emp;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.mapper
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/26 10:40
* 版本:1.0
*
*/
public interface DeptMapper {
public List selectList();
public Dept selectById( int id );
public long total( );
public int updateById(Dept emp);
public int insert(Dept emp);
public int deleteById (int id );
}
```
## 完成一对一的查询
使用 association :实现从表字段的映射
在主表的类型(Emp)上添加从表的类型(dept)


## 配置延迟加载
在SQLMapConfig.xml中配置延迟加载
```xm
3.4.1 之后默认false (3.5.6)
```
```xml
```
## 一对多的关系
- 维护实体之前的关系
- 在Dept中添加 emp的集合属性
- `List empList`

- 编写sql语句(DeptMapper.xml)
- resultMap
- connection
# 使用注解替代xml编写SQL
- 创建项目 07-app-annotation
- 添加依赖
- 编写实体类
- 编写工具类
- 编写核心配置文件(SqlMapConfig.xml)
- **不需要编写Mapper.xml**
- 编写Mapper.java
- 在Mapper.java中编写SQL语句 使用
- @Select
- @Update
- @Insert
- @Delete
- 编写测试代码
```java
package com.neuedu.mybatis.mapper;
import com.neuedu.mybatis.po.Dept;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/***
*
* 项目名称: mybatis-app
* 类名称:com.neuedu.mybatis.mapper
* 类描述:
* 创建人:金山老师
* 创建时间:2026/10/26 10:40
* 版本:1.0
*
*/
public interface DeptMapper {
@Select("select * from dept")
public List selectList();
@Select("select * from dept where deptno = #{deptno}")
public Dept selectById( int id );
@Select("select count(1) from dept")
public long total( );
@Update("update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}")
public int updateById(Dept emp);
@Insert("insert into dept(deptno,dname,loc) values(#{deptno},#{dname},#{loc})")
public int insert(Dept emp);
@Delete("delete from dept where deptno=#{deptno}")
public int deleteById (int id );
}
```