文章目录
文章学习视频资源 来源于B站:狂神说Java, 欢迎大家关注老师呀!一起学习!
MyBatis
一、简介
1、什么是MyBatis
- 一款优秀的持久层框架
- 支持定制化SQL、存储过程以及高级映射
- MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- 原身是Apache的一个开源项目iBatis。
- 2010迁移到Google code 并改名为MyBatis,2013年11月迁移到GitHub
2、获取MyBatis
GitHub:https://github.com/mybatis/mybatis-3/releases
Maven:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
3、持久层
数据持久化
将程序的数据在持久状态和瞬时状态转化的过程。
为什么需要持久化?
内存的断电即失的特点,无法一直将数据放在内存中,需要将数据持久化到数据库
4、为什么使用MyBatis
- 方便数据存入数据库
- 简化传统JDBC代码,SQL与代码分离,提高可维护性。
- 目前流行的框架,利于自动化。
二、第一个MyBatis
1、环境搭建
- 创建数据库
- 导入maven依赖(MyBatis、MySQL连接驱动、Junit)
2、创建一个Module
-
编写MyBatis核心配置文件
用于连接数据库
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatisstudy?userSSL=true&CharacterEncoding=utf8&useUnicode=true&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="170312"/> </dataSource> </environment> </environments> </configuration>
-
编写MyBatis工具类
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
XML配置文件 -->SqlSessionFactoryBuilder --> SqlSessionFactory
既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
所以这个工具类只是用于获取SqlSession,SqlSession就是用于执行SQL语句的。
3、代码编写
-
编写实体类POJO
-
编写Dao接口
-
创建mapper绑定到Dao层的接口
<mapper namespace=""> <select id=""> </select> </mapper>
-
namespace(命名空间):
命名空间的作用有两个,一个是利用更长的全限定名来将不同的语句隔离开来,同时也实现了上面见到的接口绑定。
-
mapper里面可以定制SQL语句
以select标签为例子,id填入当前mapper绑定接口下的某个方法名,相当于接口实现类的方法实现,当然需要在标签内写上SQL语句,标签内可以加上resultType即结果集,还有一个resultMap可以返回多个结果集。ParameterType填写传入参数类型
举例
<mapper namespace="com.sakura.dao.UserDao"> <select id="getUsers" resultType="com.sakura.pojo.User"> select * from mybatisstudy.user </select> </mapper>
- 这个mapper 就是绑定com.sakura.dao.UserDao这个接口,(也可以使用短命名,前提是这个短命名是全局唯一,否则就要使用全限定名),后面会讲到类型别名。
- select标签则表示是对这个接口下的getUsers这个方法的实现。
- 返回结果集的类型resultType为实体类的User,一般返回结果集类型注明为返回集容器的泛型(即结果集中内容的类型)
完成这些步骤,就结束了对一条SQL语句的映射,就代替了传统的接口实现类
它们映射的语句不仅可以 XML 来配置,还可以使用 Java 注解来配置。
遗留问题:Mapper的底层原理?是否和动态代理有关系?
-
4、Junit测试
-
报错
org.apache.ibatis.binding.BindingException: Type interface com.sakura.dao.UserDao is not known to the MapperRegistry.
com.sakura.dao.UserDao在映射注册表中是未知的,即我们的Mapper没有注册
- 去MyBatis-config.xml中注册Mapper
<!--每个xxxMapper.xml都需要在MyBatis的配置文件中注册--> <mappers> <mapper resource="com/sakura/dao/UserMapper.xml"></mapper> </mappers>
-
再次报错
Could not find resource com/sakura/dao/UserMapper.xml
无法找找到xxxMapper.xml文件,这就是之前在Maven中提到过的资源导出问题
Maven项目在打包时,约定将资源配置文件放在resource文件夹下
(需要在pom.xml中增加配置项,使得其他包中的配置或资源文件能够导出)
<build> <resources> <!--默认只导出resource文件夹下的--> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <!--添加配置导出java文件夹下的--> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
测试代码:
@Test
public void Test(){
// 1.获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 2.执行SQL
//============方式A==============//
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> users = mapper.getUsers();
for (User user : users) {
System.out.println(user.toString());
}
//===========方式B============//
List<User> list = sqlSession.selectList("com.sakura.dao.UserDao.getUsers");
for (User user : list) {
System.out.println(user);
}
sqlSession.close();
}
三、CURD
增
<insert id="addUser" parameterType="com.sakura.pojo.User">
insert into mybatisstudy.user (id, name, password) VALUES (#{id},#{name},#{password})
</insert>
// 增删改需要提交事务
@Test
public void insertUser(){
try (SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.addUser(new User(4, "张三", "1234567"));
System.out.println(i);
// 提交事务
sqlSession.commit();
}
}
注意点:
- 在传入参数时,使用
#{}
直接获取传入对象的数据,填什么取决于你传递的参数- 所有的增删改操作都需要提交事务 SqlSession.commit();
改
<update id="updateUser" parameterType="com.sakura.pojo.User">
update mybatisstudy.user
set password = #{password}
where #{id} = 4;
</update>
@Test
public void updateUser(){
try (SqlSession sqlSession = MyBatisUtils.getSqlSession()) {
UserMapp