mybatis-3.9.9
mybatis
环境:
-
JDK 1.8
-
Mysql 5.7(依赖包用8.0代替)
-
maven 3.9.9
-
IDEA
回顾:
-
JDBC
-
mysql
-
java基础
-
junit
SSM框架:配置文件的。最好的方式:看官方文档;
如何获得mybatis?
-
maven仓库:https://mvnrepository.com/
-
Github:
-
中文文档:
1、持久层
DAo层,Service层,Controller层
-
完成持久化工作代码块
-
层界限十分明显
2、为什么需要Mbatis?
-
帮助程序员将数据存入数据库中
-
方便
-
传统的JDBC太复杂,简化
-
不用Mybatis也可以,更容易上手
3、第一个Mybatis程序
思路:导入环境---》导入Mybatis--》编写代码--》测试!
3.1、搭建环境
搭建数据库:创建数据库和表
新建项目:
-
新建一个普通maven项目
-
删除src目录
-
导入依赖(pom.xml)
<!-- 导入依赖 -->
<dependencies>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version> <!-- 最新稳定版 -->
</dependency>
<!-- mybatis -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
导入依赖出现过的错误:



删除.lastUpdated文件,重新刷新

maven仓库和阿里云mavenv仓库没有mysql5.7.19版本依赖包,用8.0版本代替

3.2、创建一个模块
创建一个普通 modul,这样,模块里面也会有pom.xml文件
-
编写mybatis配置文件
进入网站--》点击入门--》
-
使用xml配置mybatis
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>创建mybatis-config.xml文件。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- configuration核心配置文件 --> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration> -
IDEA与数据库连接失败
措施:排除用户密码不匹配;检查用户权限;查看mysql服务状态;检查IDEA中主机名、端口号、用户、密码、Mysql-connector驱动是否下载。最后通过编辑mysql配置文件my.ini文件后成功连接。
![]()
添加bind-address = 127.0.0.1 # 只允许本地连接
![]()
-
-
编写mybatis工具类
- 创建工具类

-
从xml构建SqlSessionFactory,从 SqlSessionFactory 中获取 SqlSession
![]()
![]()
package com.yang.utils;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 java.io.IOException;
import java.io.InputStream;//sqlSessionFactory
public class MybatisUtils {private static SqlSessionFactory sqlSessionFactory;
static {
try { //使用mybatis第一步:获取sqlSessionFactory对象 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); }}
//有了sqlSessionFactory,从中获取sqlSession实例。
public static SqlSession getSqlSession(){return sqlSessionFactory.openSession();}
}
3.3、编写代码
-
实体类
package com.yang.pojo; public class User { private int id; private String name; private String pwd; public User(){ } public User(int id, String name, String pwd){ this.id=id; this.name=name; this.pwd=pwd; } public void setId(int id) { this.id = id; } public int getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setPwd(String pwd) { this.pwd = pwd; } public String getPwd() { return pwd; } } -
Dao接口
package com.yang.dao; import com.yang.pojo.User; import java.util.List; public interface UserDao { List<User> getUserList(); } -
接口实现类(注意空间绑定接口,名字,返回类型不要写错)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace=绑定一个对应的Dao/Mapper接口 --> <mapper namespace="com.yang.dao.UserDao"> <!-- select 查询语句 --> <select id="getUserList" resultType="com.yang.pojo.User"> select * from mybatis.user </select> </mapper>
3.4、测试
注意:
- 错误org.apache.ibatis.binding.BindingException: Type interface com.yang.dao.UserDao is not known to the MapperRegistry.
措施:在mybatis核心配置文件里面注册Mapper.xml
<!--每一个Mapper.xml文件都需要在mybatis核心配置文件配置 -->
<mappers>
<mapper resource="com/yang/dao/UserMapper.xml"/>
</mappers>
-
错误二:Could not find resource com/yang/dao/UserMapper.xml
措施:
<!--在build中配置resources,防止我们资源导出失败的问题--> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> -
错误三:
- Maven 在构建过程中使用了平台默认编码(虽然实际是 UTF-8),这可能导致跨平台构建不一致。
措施:在pom.xml文件加上
- Maven 在构建过程中使用了平台默认编码(虽然实际是 UTF-8),这可能导致跨平台构建不一致。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
- 清理并重建项目:删掉target目录--》打开IDEA右侧Maven界面--》展开Lifecycle--》双击clean--》双击install

junit测试代码:
package com.yang.dao;
import com.yang.pojo.User;
import com.yang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//方式一:getMapper
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
for (User user : userList){
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
}
需要注意:
-
配置文件注册
-
绑定接口
-
方法名
-
返回类型
-
Maven导出资源
小结:
MybatisUtils->mybatis-cofig.xml
User
UserDao->UserMapper.xml
UserDaoTest
pom.xml
4、CPRUD
4.1、namespace
namespace中的包名要与Dao/Mapper接口包名一致
4.2、select,······
选择查询
-
id :namespace中的方法名
-
resultType :sql语句执行返回结果
-
parameterType:参数类型
-
编写接口
-
编写对应Mapper.xml的sql语句
-
测试
注意:增删改需要提交事务
4.3、代码
//UserMapper接口
package com.yang.dao;
import com.yang.pojo.User;
import java.util.List;
public interface UserMapper {
//查询全部用户
List<User> getUserList();
//根据id查询用户信息
User getUserById(int id);
//插入一条用户信息
int insertUser(User user);
//更新一条记录
int updateUser(User user);
//删除一条记录
void deleteUser(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace=绑定一个对应的Dao/Mapper接口 -->
<mapper namespace="com.yang.dao.UserMapper">
<!-- select 查询语句 -->
<select id="getUserList" resultType="com.yang.pojo.User">
select * from mybatis.user
</select>
<!--根据id查询用户信息-->
<select id="getUserById" resultType="com.yang.pojo.User">
select * from mybatis.user where id = #{id}
</select>
<!--插入一条用户信息(属性可以从User表里面获取)-->
<insert id="insertUser" parameterType="com.yang.pojo.User">
insert into mybatis.user (id,name,pwd) value(#{id},#{name},#{pwd})
</insert>
<!--更新一条记录-->
<update id="updateUser" parameterType="com.yang.pojo.User" >
update mybatis.user set name = #{name},pwd = #{pwd} where id = #{id}
</update>
<!--删除一条记录-->
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id = #{id}
</delete>
</mapper>
//UserMapperTest测试
package com.yang.dao;
import com.yang.pojo.User;
import com.yang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserMapperTest {
@Test
public void test(){
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//方式一:getMapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
for (User user : userList){
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
@Test
public void UserByIdTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
//获得接口
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserById(6);
System.out.println(user);
sqlSession.close();
}
@Test
public void insertUserTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.insertUser(new User(6,"shishi","123456"));
//提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUserTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(new User(6,"liushishi","123456"));
sqlSession.commit();
sqlSession.close();
}
@Test
public void deleteUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(6);
sqlSession.commit();
sqlSession.close();
}
}
4.4、万能Map
Map传递参数,直接在sql中取出key即可;
对象传递参数,直接在sql中传递对象的属性即可;
只有一个基本类型参数的情况下,可以直接在sql中取到;
多个参数用Map或者注解!
5、配置解析
xml文件里面的标签都是有顺序的!!!!!
5.1、核心配置文件
-
mybatis-config.xml
-
Mybatis的配置文件包含了
![]()
5.2、 环境配置(environments)
Mybatis 可以配置成适应多种环境;
Mybatis默认的事务管理器就是JDBC,连接池:POOLED
5.3、属性(properties)
可以通过properties属性实现引用配置文件(db.properties)
- 在resources目录下编写db.properties文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
-
在核心配置文件中映入(Mybatis-cofig.xml)
<!--引入核心配置文件--> <properties resource="db.properties"> <property name="username" values="root"/> <property name="pwd" value="111"/> </properties>-
可以直接引入外部文件
-
可以在其中增加一些属性配置
-
如果两个文件有同一个字段,优先使用外部配置文件的!!!
-
5.4、类型别名(typeAliases)
-
类型别名是为Java类型设置一个短的名字
<!--可以给实体类起别名--> <typeAliases> <typeAlias type="com.yang.pojo.User" alias="User"/> </typeAliases> -
扫描实体类的包,默认别名就是这个类的类名,首字母小写!
<typeAliases> <package name="com.yang.pojo"/> <typeAliases/> -
注意:
实体类较少的时候,使用第一种方式;
如果实体类十分多,建议使用第二种方式;
第一种可以DIY别名,第二种不行,除非在实体类上增加注解:
@alias("user") public class User {}
5.5、设置
5.6、其他配置
-
plugins插件
-
mybatis-genertor-core(可以根据你自己的代码自动生成mybatis代码)
-
mybatis-plus(可以让你的mybatis代码更简化)
-
通用mapper
-
5.7、映射器(mappers)
MapperRegistry:注册绑定我们的Mapper文件;
方式一:(推荐)
<!--每一个Mapper.xml都需要在Mybatis核心配置文件注册-->
<mappers>
<mapper resource="com/yang/dao/UserMapper.xml"/>
<mappers/>
方法二:使用class文件绑定注册
<mappers>
<mapper class="com.yang.dao.UserMapper"/>
<mappers/>
注意点:
-
接口和他的Mapper配置文件必须同名
-
接口和它的Mapper配置文件必须在同一个包下!!!
方法三:使用扫描包进行注册绑定
<mappers>
<package name="com.yang.dao"/>
<mappers/>
注意点:
-
接口和他的Mapper配置文件必须同名
-
接口和它的Mapper配置文件必须在同一个包下!!!
5.8、生命周期和作用域

SqlSessionFactoryBuilder:
-
局部变量
-
一旦创建了,就不再需要了
SqlSessionFactory:
-
可以当成一个 数据库连接池
-
一旦创建运行期间一直存在,没有理由丢弃
-
最佳作用域是应用作用域
-
最简单的就是使用单例模式或者静态单例模式
SqlSession
-
连接到数据库连接池的一个请求
-
线程不安全,不被共享,最佳作用域是请求或者方法作用域
-
用完之后需要赶紧关闭,否则资源被占用
![]()
这里的每一个Mapper,就代表一个具体的业务!
6、解决属性名和字段名不一致的问题
数据库表格里的属性命名和代码实体类里面的名字不一致
解决办法:
起别名:as password
<select id="getUserById" resultType="com.yang.pojo.User">
select id,name,pwd as password from mybatis.user where id=#{id}
<select/>
resultMap(结果集映射)
-
resultMap 元素是Mybatis中最强大的元素
-
设计思想:简单语句不需要配置显式的结果映射,对于复杂的语句只需要描述他们的关系就行了
UserMapper.xml文件
<!--结果集映射-->
<resultMap id="UserMap" type="User">
<!--column数据库字段,property实体类属性-->
<result column="pwd" property="password"/>
<resultMap/>
<select id="getUserById" resultMap="UserMap">
select * from mybatis.user where id=#{id}
<select/>
7、日志
7.1、日志工厂
如果一个数据库操作,出现了异常,日志就是最好助手。
曾经:sout,debug
现在:日志工厂(logImpl)
-
SLF4J
-
LOG4J(掌握)
-
LOG4J2
-
JDK_LOGGING
-
COMMONS_LOGGING
-
STDOUT_LOGGING(掌握)
-
NO_LOGGING
在mybatis具体使用哪一个日志实现,在设置中设定!
STDOUT_LOGGING标准日志输出(默认的)
在mybatis核心配置文件中,配置我们的日志:
<!--默认标准日志输出-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
注意:name注意大小写,一定不要写错;value注意不要出现多余空格之类的;
7.2、Log4j
什么是Log4j?
-
Log4j是一个开源项目,可以通过Log4j控制日志信息输送目的地是控制台、文件、GuI组件
-
可以控制每一条日志的输出格式
-
通过定义每一条日志信息的级别,更加细致的控制日志的生成过程
-
通过一个配置文件来灵活地进行配置,不需要修改应用代码
- 导包(在pom.xml文件添加)
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 创建log4j.properties文件(在resources目录下)
面向百度查询,粘贴
# 设置根日志级别和输出源
log4j.rootLogger=DEBUG, console, file
# 控制台输出配置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# 文件输出配置
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/yang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
# SQL日志配置
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
- 配置log4j为日志的实现(在mybatis核心配置文件)
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
- Log4j的使用
简单使用(UserMapperTest)
-
在要使用log4j的类中,导入包 import org.apache.log4j.Logger;
-
日志对象,参数为当前的class
```java
static Logger logger = Logger.getLogger(UserMapperTest.class);
```
- 日志级别
```java
@Test
public void Log4jExample() {
logger.info("info:进入了testLog4j");
logger.debug("debug:进入了testLog4j");
logger.error("error:进入了testLog4j");
}
```
8、分页
为什么分页?
- 减少数据处理量
使用Limit分页
语法:select * from user limit startIndex,pageSize;
select * from user limit 3; #[0,3]
使用mybatis实现分页,核心是SQL:
- 接口
//分页
List<User> getUserByLimit(Map<String,Integer> map);
- Mapper.xml
<!--分页-->
<select id = "getUerByLimit" parameterType = "map" resultMap ="UserMap">
select * from mybatis.user limit #{startIndex},#{pageSize}
<select/>
- 测试
@Test
public void getUserByLimit(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String,Integer> map = ner HashMap<String,Integer>();
map.put("startIndex",1);
map.put("pageSize",2);
List<User> userList = mapper.getUserByLimit(map);
for(User user:userList){
System.out.println(user);
}
sqlSession.close();
}
9、使用注解开发
mybatis大部分会使用配置文件,除了mybatis之外的东西都会使用注解开发。
9.1、面向接口编程
解耦
9.2、使用注解开发
- 注解在接口上实现
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
}
- 需要在核心配置中绑定接口(mybatis核心配置文件)
<!--绑定接口-->
<mappers>
<mapper class="com.yang.dao.UserMapper"/>
</mappers>
- 测试
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.getUsers();
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
本质:反射机制实现
底层逻辑:动态代理!(面试常考)
Mybatis详细执行流程:
9.3、注解-增删查改(只需要注册接口以及编写接口方法(用注解))
MybatisUtils工具类里面:设置自动提交事务
//有了sqlSessionFactory,从中获取sqlSession实例。////////加上true,自动提交事务commit().
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}
注意:我们必须要将接口注册绑定到我们的核心配置文件!!!
关于@Param()注解:
-
基本类型的参数或者String类型,需要加上
-
引用类型不需要
-
sql中引用的就是我们这里的@Param(”id“)中的属性名!!!
- 在Mybatis核心配置文件绑定注册接口
<!--绑定接口-->
<mappers>
<mapper class="com.yang.dao.UserMapper"/>
</mappers>
- 编写接口
package com.yang.dao;
import com.yang.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
//方法存在多个参数,所有参数前面必须加上:@Param(“id”)注解
@Select("select * from user where id = #{id}")
User getUserById(int id);
@Select("select * from user where id = #{id} and name = #{name}")
User getUserById_Name(@Param("id") int id,@Param("name") String name);
@Insert("insert into user(id,name,pwd) value (#{id},#{name},#{pwd})")
int InsertUser(User user);
@Delete("delete from user where id = #{id}")
int DeleteUser(@Param("id") int id);
@Update("update user set name = #{name} ,pwd = #{pwd} where id = #{id}")
int UpdateUser(User user);
}
- 测试
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询所有用户
// List<User> users = mapper.getUsers();
// for (User user : users) {
// System.out.println(user);
// }
//根据id查询用户信息
// User userById = mapper.getUserById(1);
// System.out.println(userById);
// User userById_Name = mapper.getUserById_Name(4,"shshi");
// System.out.println(userById_Name);
//增加用户
// mapper.InsertUser(new User(6,"dili","123456"));
//删除用户
// mapper.DeleteUser(6);
//更改用户信息
mapper.UpdateUser(new User(5,"yangshi","123456"));
sqlSession.close();
}
10、Lombok
是什么?
简化java代码的一个插件,看情况吧,不建议使用
使用步骤:
-
在IEDA中安装Lombok插件
-
在项目中,pom.xml导入lombok的jar包
<dependencies>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<scope>provided</scope>
</dependency>
</dependencies>
- 直接在实体类加上注解即可
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
@Data: 无参构造,get,set,tostring,hashcode,equals
@AllArgsConstructor:有参构造
@NoArgsConstructor:无参构造
@EqualsAndHashCode
@ToString
@Getter
11、多对一处理
多个学生,对应一个老师
-
对于学生而言,关联,多个学生关联一个老师
-
对于老师而言,集合,一个老师有很多学生
创建数据库环境:
CREATE TABLE `teacher`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY(`id`))
ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO teacher(`id`,`name`) VALUES (1,"秦老师");
CREATE TABLE `student`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY(`id`),
KEY `fktid`(`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`))
ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('1','小明','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('2','小红','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('3','小张','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('4','小李','1');
INSERT INTO `student` (`id`, `name`,`tid`) VALUES ('5','小王','1');
测试环境搭建:
(Mybatis-study2目录下的mybatis-04项目)
-
新建实体类
-
建立Mapper接口
-
建立Mapper.xml文件
-
在核心配置文件中绑定我们的Mapper接口或者文件!!(方式有很多)
-
测试查询是否成功
按照查询嵌套处理:
-
先写StudentMapper接口
public interface StudentMapper { //查询所有学生信息,以及对应老师的信息 public List<Student> getStudent(); } -
编写StudentMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.yang.dao.StudentMapper"> <!--1.查询学生信息 2.根据查询出来的tid,查询相应老师信息--> <select id="getStudent" resultMap="StudentTeacher"> select * from student </select> <resultMap id="StudentTeacher" type="Student"> <result property="id" column="id"/> <!--复杂的属性,需要单独处理,对象用association ;集合用collection; --> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap> <select id="getTeacher" resultType="Teacher"> select * from teacher where id = #{id} </select> </mapper> -
测试
@Test public void testStudent(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); List<Student> studentList = studentMapper.getStudent(); for (Student student : studentList) { System.out.println(student); } }
按照结果嵌套处理
<!--按照结果嵌套查询-->
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid, s.name sname, t.name tname
from student s,teacher t
where s.tid = t.id;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
12、一对多处理
一个老师拥有多个学生
对于老师而言,就是一对多的关系!
也有两种方法,和多对一 一样,下面我只写了一种
环境搭建
-
实体类
@Data public class Teacher { private int id; private String name; //一个老师拥有很多学生 一个学生集合 private List<Student> students; }
@Data
public class Student {
private int id;
private String name;
private int tid;
}
-
接口
public interface TeacherMapper { //获取指定老师下所有学生以及老师的信息 Teacher getTeacher(@Param("tid") int id); } -
Mapper.xml(对象:association;集合:collection; javaType--指定属性类型;集合中泛型信息,我们用ofType获取)
<!--按照结果查询--> <select id="getTeacher" resultMap="TeacherStudent"> select t.id tid, t.name tname, s.id sid, s.name sname,s.tid stid from teacher t,student s where t.id = s.tid; </select> <resultMap id="TeacherStudent" type="Teacher"> <result property="id" column="tid"/> <result property="name" column="tname"/> <collection property="students" ofType="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="stid"/> </collection> </resultMap> -
测试
@Test public void test(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = teacherMapper.getTeacher(1); System.out.println(teacher); sqlSession.close(); }
注意点:
-
保证sql的可读性
-
注意一对多和多对一中,属性名和字段的问题
-
如果问题不好排查,可以使用Log4j
13、动态sql
什么是动态sql?
动态sql就是根据不同的条件生成不同的Sql语句

总结:拼接SQL语句,确保SQL语句正确性,按照SQL格式去排列组合即可。建议先写出完整SQL语句再去对应修改动态sql实现通用!
动态sql本质还是sql语句,if/ where/ set/ choose/ when/
搭建环境
(mybatis-study2目录下mybatis-06目录)
数据库环境
CREATE TABLE `blog` (
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创作时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `blog` (`id`, `title`, `author`, `create_time`, `views`) VALUES
('1', 'mysql', '小明', '2025-01-01 00:00:00', 1000),
('2', 'maven', '小李', '2025-01-02 00:00:00', 1500),
('3', 'mybatis', '小丽', '2025-01-03 00:00:00', 2000),
('4', 'ieda中使用maven', '小云', '2025-01-04 00:00:00', 800),
('5', 'mysql动态', '小红', '2025-01-05 00:00:00', 1200);
创建一个基础工程:
-
导包
-
编写配置文件
核心配置文件添加:
<mappers>
<mapper resource="com/yang/dao/BlogMapper.xml"/>
</mappers>
<!--是否开启自动命名规则映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>

- 编写实体类
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
-
编写实体类对应Mapper接口和Mapper.xml文件
-
工具类,IDUtils(随机生成id)
public class IDUtils {
public static String getId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
@Test
public void test(){
System.out.println(IDUtils.getId());
System.out.println(IDUtils.getId());
System.out.println(IDUtils.getId());
}
}
IF
环境搭建好,只需要编写Mapper接口以及Mapper.xml文件和测试代码即可
- BlogMapper接口
//查询博客
List<Blog> queryBlogIF(Map map);
- BlogMapper.xml
<select id="queryBlogIF" resultType="Blog" parameterType="map">
select * from mybatis.blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
<!--1.输入title查询该title全部信息
2.输入author查询该author全部信息
3.什么都不输入则查询全部博客信息-->
<select id="queryBlogIF" resultType="Blog" parameterType="map">
select * from mybatis.blog where 1 = 1
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</select>
- MyTest
@Test
public void queryBlogIFTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap hashMap = new HashMap();
// hashMap.put("title","mysql");
// hashMap.put("author","小明");
List<Blog> blogs = blogMapper.queryBlogIF(hashMap);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
choose,when,otherwise
- 接口
//查询博客
List<Blog> queryBlogChoose(Map map);
- Mapper.xml
<select id="queryBlogChoose" resultType="Blog" parameterType="map">
select * from mybatis.blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
views = #{views}
</otherwise>
</choose>
</where>
</select>
- Test
@Test
public void queryBlogChooseTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap hashMap1 = new HashMap();
// hashMap1.put("title","mysql");
hashMap1.put("author","小明");
hashMap1.put("views",2000);
List<Blog> blogs = blogMapper.queryBlogChoose(hashMap1);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
Set
<select id="UpdateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id}
</select>
foreach
<!--通过foreach,传递一个万能的Map,这个Map可以存在一个集合-->
<!--foreach:集合名,集合里面的每一个项名,开始,结束,分隔符-->
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<foreach collection="ids" item="id" open="(" close=")" separator="or">
id = #{id}
</foreach>
</where>
</select>
@Test
public void queryBlogForeach(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap hashMap3 = new HashMap();
ArrayList<Integer> ids = new ArrayList<Integer>();
hashMap3.put("ids",ids);
ids.add(1);
ids.add(2);
List<Blog> blogs = blogMapper.queryBlogForeach(hashMap3);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
//查询第1-5号记录的博客
List<Blog> queryBlogForeach(Map map);
SQL片段
有时候,可能把一些功能的部分提取出来,方便复用!(提取SQL公共部分,在需要地方引用include标签
<sql id="if_title_author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<!--1.输入title查询该title全部信息
2.输入author查询该author全部信息
3.什么都不输入则查询全部博客信息-->
<select id="queryBlogIF" resultType="Blog" parameterType="map">
select * from mybatis.blog
<where>
<include refid="if_title_author"></include>
</where>
</select>
注意事项:
最好基于单表来定义SQL片段,不要存在where标签
14、缓存
14.1、简介
查询:连接数据库,耗资源
一次查询的结果,给他缓存在一个可以直接提取的地方,---》内存/ 缓存
我们再次查询相同数据的时候,直接走缓存,不用走数据库了。(解决高并发系统问题)






浙公网安备 33010602011771号