MyBatis_Learn
环境:
- jdk1.8
- MySql 5.7
- Maven 3.6.1
- IDEA
回顾:
- JDBC
- MySql
- Java基础
- Maven
- Junit
框架:SSM学习通过查询官方文档
mybatis官方文档:mybatis – MyBatis 3 | 入门
1. 简介
1.1 什么是MyBatis
- MyBatis 是一款优秀的持久层框架
- 它支持自定义 SQL、存储过程以及高级映射。
- MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了[google code](https://baike.baidu.com/item/google code/2346604),并且改名为MyBatis。2013年11月迁移到Github。
如何获取MyBatis
-
maven仓库:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency>
-
GitHub
1.2 持久化
数据持久化
持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 内存:断电即失
- 数据库:(JDBC)io文件持久化
- 生活:冷藏
为什么需要持久化
- 有些对象,不能让他丢失
- 内存价格归
1.3 持久层
Dao层,Service层,Controller层
- 完成持久化工作的代码块
- 层界限十分明显
1.4 为什么需要MyBatis
- 帮助程序员将数据存入数据库中
- 方便
- 传统的JDBC代码复杂,简化,自动化
- 更容易上手
- 优点:
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射。
- 提供对象关系映射标签,支持对象关系组建维护。
- 提供xml标签,支持编写动态sql。
重点 使用人多
1.5 MyBatis详细执行过程
- Resources获取加载全局配置文件
- 实例化SqlSessionFactoryBuilder构造器
- 解析配置文件流xml ConfigBuilder
- Configuration所有的配置信息
- SQL SessionFactory实例化
- transactional事务管理
- 创建executor执行器
- 创建SQL Session
- 实现CRUD
- 查看CRUD是否执行成功,不成功返回transactional事务管理重来
- 提交事务
- 关闭
2. 第一个MyBatis程序
思路:搭建环境->导入Mybatis->编写代码->测试!
2.1 搭建环境
-
数据库创建
CREATE TABLE user( id INT(20) not NULL PRIMARY KEY, name VARCHAR(30) DEFAULT(NULL), PASSWORD VARCHAR(30) DEFAULT NULL )ENGINE=INNODB; INSERT INTO USER(id,NAME,PASSWORD)VALUES (1,'缘昔','123456'), (2,'小红','456789'), (3,'小粉','147258')
-
新建项目
-
新建Maven项目
-
删除src
-
导入依赖
<!--导入依赖--> <dependencies> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <!--mybatis驱动--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> <!--junit驱动--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies>
-
2.2 创建一个模块
-
编写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核心配置文件,进行连接数据库等操作--> <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="020113"/> </dataSource> </environment> </environments> <mappers> <!--对于实现类的xml文件进行注册--> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
-
编写MyBatis工具类
//获取SqlSessionFactory对象,构建SqlSession public class MyBatisUtils { //提升作用域,注意将sqlSessionFactory提升为全局变量以后下文对应变量的定义 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 的实例 //SqlSession 提供了在数据库执行 SQL 命令所需的所有方法 //可以通过 SqlSession 实例来直接执行已映射的 SQL 语句 public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); }
2.3 编写代码
-
实体类
//实体类 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 int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }
-
Dao接口
public interface UserDao { List<User> getUserList(); }
-
接口实现类(由原来JDBC中的UserDaoImpl转换成一个mapper配置文件)
<?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(Dao)接口--> <mapper namespace="com.Yurrize.dao.UserDao"> <!--查询语句--> <select id="getUserList" resultType="com.Yurrize.pojo.User"> select * from mybatis.user </select> </mapper>
2.4 测试
注意:
org.apache.ibatis.binding.BindingException:Type interface com.Yurrize.dao.UserDao is not known to the MapperRegistry.
MapperRegistry是什么?
核心配置文件中注册mappers
解决办法:
<!--每一个Mapper,XML都需要在MyBatis核心配置文件中进行注册-->
<mappers>
<mapper resource="com/Yurrize/dao/UserMapper.xml"/>
</mappers>
注意:
java.lang.ExceptionInInitializerError 资源过滤问题,无法找到xml文件,由于Maven约定大于配置,我们之后可能遇到我们写的配置文件,无法导出或者生效的问题!
解决办法:
<!--在build中配置resources,防止资源导出失败-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
-
junit测试
@Test public void test(){ //第一步:获取sqlSession对象 SqlSession sqlSession = MyBatisUtils.getSqlSession(); //执行SQL语句 //方式一:getMapper UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.getUserList(); for (User user : userList) { System.out.println(user); } //关闭sqlSession sqlSession.close(); } }
测试中可能遇到的问题:
- 配置文件没有注册
- 绑定接口错误 .xml文件中检测接口绑定路径
- 方法名打错 .xml文件中检测
- 返回类型不对 .xml文件中检测
- Maven导出资源问题,过滤问题