1、什么是MyBatis?
· Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的过程。
· Mybatis是一款优秀的持久层框架。
* 持久层:可以理解为把数据保存在数据库或者硬盘啊可以保存很长时间的设备里面;像内存,它断点之后数据就会丢失了。
· Mybatis可以简单通过XML或者注解来配置和映射原生信息,将接口和Java的实体类映射成数据库中的记录。
· Mybatis原本是Apache的一个开源项目ibatis,2010年这个项目从Apache迁移到了Google Code,并且改名为Mybatis.
· 2013年11月迁移到Github。
Mybatis官方文档: https://mybatis.org/mybatis-3/zh/getting-started.html
Github地址:https://github.com/mybatis/mybatis-3
注:Github中点击releases可以下载jar和源码。
2、持久化
持久化是将程序数据在持久状态和瞬时状态键转换的机制。
· 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用试讲内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
· JDBC就是一种持久化机制。文件IO也是一种持久化机制。
· 举例:生活中:将鲜肉冷藏,吃的时候再解冻的方法;或者将水果做成罐头等...
为什么需要持久化服务呢?因为内存本身的缺陷引起的。
· 内存断电后数据会丢失。
· 内存价格贵,与硬盘,光盘等外存相比,内存的价格要高2~3个数量级,而且维持成本比较高,如一直需要供电。及时对象不需要永久保存,也会因为内存的容量限制不能一直呆在内存中,需要持久化来缓存到外存。
3、持久层
· 持久层是指:完成持久化工作的代码块 ---> dao层(Data Access Object);
· 大多数情况下,特别是企业级应用,数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程,则大多通过各种关系数据库来完成。
· 说白了,就是用来操作数据库而存在的!
4、Mybatis的好处
· 传统的jdbc操作,会有很多的重复代码块。比如:数据取出时的封装,数据库的建立连接等...通过Mybatis框架可以减少重复代码,提高开发效率。
· 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了。而且通过官方文档和源代码,可以比较完全的掌握它的设计思路和实现。
· 灵活:sql写在XML中,便于统一管理和优化。通过sql语句就可以满足操作数据库的所有需求。
· 接触sql与程序代码的耦合:通过提供dao层,将业务逻辑和数据访问逻辑分离,是系统的设计更清晰,更易维护,更易单元测试。
· 提供xml标签,支持动态sql编写。
5、搭建第一个程序
①、创建数据库表
我这边创建一张简单的用户表,id主键,姓名,密码。(测试数据请自行插入)
-- auto-generated definition
create table user
(
id int auto_increment
primary key,
username varchar(20) not null,
password varchar(20) not null
);
②、使用普通Maven工程创建一个普通的java项目,在pom.xml中导入mybatis以及mysql以及单元测试junit所需要的依赖
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
③、查看官方文档,编写Mybatis的核心配置文件
enviroments中默认环境为id为development的环境,事务管理使用JDBC事务管理,以及数据源POOLED,后面则是根据自己的数据库配置相应的驱动(mysql8.0以上需要在驱动中加上cj), url,用户名和密码。这里的mappers标签是重点,你所写的mapper.xml文件需要在mappers标签中注册,就是相应的目录,可以用/也可以用. (我这里的UserMapper.xml后面会用到)
<?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.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///ftj?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<!--每一个mapper.xml都需要在mybatis核心配置文件中注册!-->
<mappers>
<mapper resource="com/ftj/dao/UserMapper.xml"/>
</mappers>
</configuration>
④、编写一个mybatis的工具类(可以查看中文文档来创建:目的就是读取配置文件,用SqlSessionFactory(工厂模式)来创建SessionFactory,这里可以用静态代码块来加载配置文件 )
package com.ftj.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 ---> sqlSession 工厂设计模式
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//使用Mybatis第一步:获取SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
//有了SqlSessionFactory,我们就可以获取SqlSession的实例了
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
⑤、根据①中的数据库表,创建实体类(这一步比较简单)
package com.ftj.pojo;
public class User {
private int id;
private String username;
private String password;
public User(int id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
⑥、编写Mapper接口类(里面创建一个User类型的List集合,用来获取用户信息)
package com.ftj.dao;
import com.ftj.pojo.User;
import java.util.List;
public interface UserDao {
List<User> getUserList();
}
⑦、编写Mapper.xml配置文件(这里namespace十分重要,不能写错,就是他所存放的目录),<select>标签中的Id是接口方法名,resultType就是返回数据的类型:直接锁定实体类就好了) 这些xml的模板都可以在官方文档中找到,copy一份就行。
<?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=绑定一个对应的Dap/Mapper接口-->
<mapper namespace="com.ftj.dao.UserDao">
<!--查询语句-->
<select id="getUserList" resultType="com.ftj.pojo.User">
select * from user
</select>
</mapper>
⑧、编写测试类
这里的话官方文档也提到了,使用了两种方法来调用映射
1、
2、
两种方法的比较:他也做了解释:第二种方法有很多优势,首先它不依赖于字符串字面值,会更安全一点;其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择到映射好的 SQL 语句。
package com.ftj.dao;
import com.ftj.pojo.User;
import com.ftj.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* org.apache.ibatis.binding.BindingException: Type interface com.ftj.dao.UserDao is not known to the MapperRegistry.
* 解决:每一个mapper.xml都需要在mybatis核心配置文件中注册!
*
* 这里maven可能会造成资源导出失败 .xml
*
* 可能会遇到的问题:
* 1、配置文件没有注册
* 2、绑定接口错误
* 3、方法名不对
* 4、返回类型不对
* 5、maven导出问题
*/
public class UserDaoTest {
@Test
public void test(){
//获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//方式1:getMapper 执行SQL
//UserDao userDao = sqlSession.getMapper(UserDao.class);//反射
//List<User> userList = userDao.getUserList();
//方式2:
List<User> userList = sqlSession.selectList("com.ftj.dao.UserDao.getUserList");
for (User user : userList) {
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
}
⑨、测试成功
⑩、可能会遇到的问题就是:maven造成的 .xml文件导出问题(在target目录中没法找到这份文件,从而导致缺少映射的关系,报错,解决办法:就是在pom.xml中增加下面的代码:)
<!--在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>