MyBatis详解
文章目录
一、定义
mybatis的引入
概念: MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作,专注于 SQL 本身,让开发者更加灵活地操作数据库。
理解:mybatis是DAO层的一个解决方案 他的主要功能和 JDBC以及dbutils是一样的 主要完成的是数据库的增删改查
SSM:Struts,SpringMVC/Spring/Mybatis
SSH:Struts,SpringMVC/Spring/Hibernate
SSS:Struts,SpringMVC/Spring/SpringData JPA
拓展:
有了JDBC,dbutils了,为什么还要学习这个 mybatis呢?
原因:这个时候我们就会提到 一个框架 这个框架叫做 Hibernate
其实在 JDBC和 Hibernate,以及我们的 mybatis中我们的代码最简洁是Hibernate,代码运行速度最高的是JDBC,代码复杂度最高的也是JDBC,代码复杂度最低的是Hibernate
好像没有 mybatis啥事一样?
其实我们的mybatis的运行效率 是介于 JDBC和Hibernate之间的,同时 代码的复杂度 也是介于 Hibernate和 JDBC之间的 它相当于是 JDBC和Hibernate之间的一个中间产物 你可以这样去理解
但是到今天为止 纯原生态的这个mybatis也基本上不会用
二、特点
mybatis能干什么:
数据库的增删改查,而且还提供了缓存 插件等功能供我们使用
- 灵活性高: MyBatis 允许开发者直接编写 SQL 语句,而不需要像 Hibernate 这样的 ORM 框架那样依赖自动生成的 SQL。这使得 MyBatis 在处理复杂查询、联合查询或存储过程时非常灵活。
- 性能优化: MyBatis 支持一级缓存和二级缓存,这可以减少数据库的访问频率,提高应用的性能。
- 简单易用: 相较于其他 ORM 框架,MyBatis 更加轻量级,不需要额外的复杂配置。它直接操作 SQL,容易理解和使用,特别是对熟悉 SQL 的开发者来说。
- 动态 SQL 支持: MyBatis 提供了强大的动态 SQL 支持,通过
、
、``等标签,开发者可以根据条件动态生成 SQL 语句,减少冗余 SQL 代码。
三、mybatis的第一个helloworld程序
1、导包:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<!--第一步:导包-->
<!--下面就是iBatis的相关的包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--mysql的驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.10</version>
</dependency>
<!--日志门面-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
2、编写mybatis.xml配置文件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 这个约束的文件中主要配置的是数据库连接的四要素
default:表示的是默认使用哪一个环境
这个一般就和下面的id名字一样就好了
-->
<environments default="mysql">
<!-- id是可以随便写的 一般写环境的名字-->
<environment id="mysql">
<!-- 事务管理器 这个位置可以配置两个
Managed
还可以是JDBC
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源-->
<dataSource type="POOLED">
<!-- 这里面就要配置数据库连接的四要素了-->
<!--数据库的驱动-->
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<!--连接的地址-->
<property name="url" value="jdbc:mysql:///cd_2401?useUnicode=true&characterEncoding=utf-8"></property>
<!--数据库的用户名-->
<property name="username" value="root"></property>
<!--连接密码-->
<property name="password" value="root"></property>
</dataSource>
</environment>
<environment id="Oracle">
<transactionManager type=""></transactionManager>
<dataSource type=""></dataSource>
</environment>
<environment id="db2">
<transactionManager type=""></transactionManager>
<dataSource type=""></dataSource>
</environment>
</environments>
<!-- 将Mapper.xml申明到这个文件中来-->
<mappers>
<mapper resource="UserMapper.xml"></mapper>
</mappers>
</configuration>
3、编写实体
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xiaobobo
* @title: User
* @projectName cd-java-fy-2401-framwork-demo
* @description: TODO
* @date 2024/9/2 9:39
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer userId;
private String username;
private String password;
}
4、编写UserMapper.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">
<!--
namespace:写啥呢?可以随便写 只要唯一就可以了
但是一般都见名之意 一般写成 实体的名字Mapper
-->
<mapper namespace="UserMapper">
<!-- 这个文件是实体对应的映射文件
这个文件中主要写的是 数据库的增删改查的描述文件
-->
<!-- 接下来 我们就可以写增删改查了...-->
<select id="list" resultType="com.qfedu.edu.pojo.User">
select * from t_user
</select>
</mapper>
5、测试类
![mybatis1运行结果](D:\桌面\img\mybatis1运行结果.png)public static void main(String[] args) throws Exception {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
//第四步:操作数据库
List<Object> objects = sqlSession.selectList("UserMapper.list");
System.out.println("查询出来的数据:" + objects);
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}
运行结果:
四、mybatis下基本的增删改查的编写
1、UserMapper.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">
<!--
namespace:写啥呢?可以随便写 只要唯一就可以了
但是一般都见名之意 一般写成 实体的名字Mapper
-->
<mapper namespace="UserMapper">
<!-- 这个文件是实体对应的映射文件
这个文件中主要写的是 数据库的增删改查的描述文件
-->
<!-- 接下来 我们就可以写增删改查了...-->
<select id="list" resultType="com.qfedu.edu.pojo.User">
select * from t_user
</select>
<!-- 更新数据-->
<update id="update">
update t_user set username="xxxx"
</update>
<!-- 添加-->
<insert id="insert">
insert into t_user(username,password) values('小波波111','11110')
</insert>
<!-- 删除-->
<delete id="delete">
delete from t_user where userId=2
</delete>
</mapper>
2、测试文件的编写
package com.qfedu.edu.crud;
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.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @author xiaobobo
* @title: Test001
* @projectName cd-java-fy-2401-framwork-demo
* @description: TODO
* @date 2024/9/2 9:43
*/
public class Test001 {
@Test
public void testQuery1() throws IOException {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
//第四步:操作数据库
List<Object> objects = sqlSession.selectList("UserMapper.list");
System.out.println("查询出来的数据:" + objects);
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}
@Test
public void testUpdate() throws IOException {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
//第四步:操作数据库
sqlSession.update("UserMapper.update");
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}
@Test
public void testAdd() throws IOException {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
//第四步:操作数据库
sqlSession.update("UserMapper.insert");
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}
@Test
public void testDelete() throws IOException {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
//第四步:操作数据库
sqlSession.delete("UserMapper.delete");
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}
}
五、mybatis下标签和方法混合调用问题
增删改的方法是可以互换的
增删改的标签也是可以互换的
因为不管是什么标签 最终执行的是SQL语句
为什么查询不能互换呢?
因为查询是有结果的 增删改的结果只有 影响的行数 所以他是不能互换的
六、基本参数问题
6.1、传递单一参数
6.1.1、编写mapper.xml文件
<!-- 这个是研究参数的传递问题的-->
<!-- 传递单一的参数-->
<!-- 通过用户名找用户
parameterType:这个参数写啥呢?
1、写这个参数类型在Java中的全路径
2、写当前类型在mybatis中取的别名
如果传递的是单一的参数的话 #{随便写都是对的} 但是做开发的时候一般写 value
注意事项:parameterType:这个只能在一个描述中用一次
-->
<select id="listByUsername" parameterType="string" resultType="com.qfedu.edu.pojo.User">
select * from t_user where username=#{value}
</select>
6.1.2、编写测试
@Test
public void testQuery1() throws IOException {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
Object xxxx = sqlSession.selectOne("UserMapper.listByUsername", "xxxx");
System.out.println("查询到的数据是:"+xxxx);
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}
6.2、传递对象类型的参数
传递对象是可以写 这个类型的全路径还可以写 这个类型的别名
6.2.1、编写UserMapper.xml
<!-- 添加数据到数据库
下面引用这个值的时候 直接写 对象中 成员变量的变量名
-->
<insert id="insert" parameterType="user">
insert into t_user(username, password)
values (#{username},#{password})
</insert>
6.2.2、编写测试
@Test
public void testInsert() throws IOException {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsername("uuuuu");
user.setPassword("ooooo");
sqlSession.insert("UserMapper.insert", user);
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}
6.2.3、取别名
取别名的第一种方式: 这个类型的全路径
取别名的第二种方式
这种方式取别名别名是:类名的所有单词小写
<typeAliases>
<package name="com.qfedu.edu.pojo"/>
</typeAliases>
6.3、传递集合类型的参数(map)
需求:通过用户名和密码删除用户数据,第一种传递map直接写Java中类型的全路径,还可以写Map在mybatis中的别名,那么 #{}中写啥呢?map中对应的key
6.3.1、编写mapper.xml
<delete id="deleteByUsernameAndPassword" parameterType="map">
delete from t_user where username=#{username} and password=#{password}
</delete>
6.3.2、编写测试文件
@Test
public void testDeleteByUsernameAndPassword() throws IOException {
//首先第一步:要找到这个mybatis.xml的配置文件
Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
//第二步:找到sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
//第三步:通过工厂创建会话对象(操作数据库的对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
//这个就是咋们的map
Map<String,Object> maps=new HashMap<String, Object>();
maps.put("username","小波波111");
maps.put("password","11110");
sqlSession.delete("UserMapper.deleteByUsernameAndPassword",maps);
//最后我们就来关闭资源
sqlSession.commit();
sqlSession.close();
resourceAsReader.close();
}