Mybatis入门教程
在此感谢哔哩哔哩的秦疆老师,up主:遇见狂神说,视频地址: https://www.bilibili.com/video/BV1NE411Q7Nx,于2020-04-05学习后用Typora0.9.98整理的观后感。开发环境:JDK1.8.231,MySQL5.7, maven-3.6.3, IDEA
1 mybatis入门简介
-
Mybatis是一个持久层ORM(Object Relation Map)框架。迭代历史:apache(iBatis) -> google(Mybatis) -> GitHub
-
Hibernate全自动框架,配置文件之后不需要书写SQL语句,但欠缺灵活,优化不便;
mybatis是半自动框架,需要手动写sql及定义映射,增加了一些操作但带来了设计上的灵活性。且简单易学,本身很小且简单没有三方依赖。
-
mybatis优缺点:(1)解耦:sql与代码分离;(2)逻辑标签控制动态sql拼接;(3)查询结果集与java对象自动映射;
2 第一个mybatis程序
- 创建数据库
DROP DATABASE IF EXISTS `demo`;
CREATE DATABASE `demo`
CHARACTER SET 'utf8'
COLLATE 'utf8_general_ci';
use 'demo';
drop table if exists mybatis_user;
create table mybatis_user(
id int(20) not null PRIMARY KEY,
name varchar(30) default null,
pwd varchar(30) default null
)ENGINE=INNODB DEFAULT CHARSET=utf8;
- 创建一个普通maven项目,引入依赖
1. 新建的工程中删除src目录,使其成空父工程,然后新建module,
2. 新建的module的pom.xml引入maven依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
- src/resource目录下编写mybatis核心配置文件:mybatis-config.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核心配置文件 注意:属性配置顺序The content of element type "configuration" must match -->
<configuration>
<!--引用外部配置文件,外部配置文件优先级高于本标签内属性,例如以下的错误密码会被外部属性覆盖-->
<properties resource="db.properties">
<property name="password" value="error"/>
</properties>
<settings>
<!-- 指定 MyBatis 所用日志的具体实现 -->
<!--<setting name="logImpl" value="STDOUT_LOGGING"/>-->
<!-- 是否开启驼峰命名自动映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 是否开启全局缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--<property name="driver" value="jdbc:mysql://127.0.0.1:3306/demo?serverTimezone=UTC&useSSL=false"/>-->
<!--&为转义符<=>& -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- mappser映射器 每个mapper.xml都需要在mybatis核心配置文件中注册 -->
<mappers>
<mapper resource="mybatis/kuangshen/dao/UserMapper.xml"/>
</mappers>
</configuration>
//db.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/demo?serverTimezone=UTC&useSSL=false
username=root
password=root
- 封装构建sqlSessionFactory及从其中获取sqlSession公共步骤封装
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
//1. 从XML中构建 SqlSessionFactory /或直接从Java代码构建 qlSessionFactory
static {
try{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}catch (IOException e){
e.printStackTrace();
}
}
//2. 从 SqlSessionFactory 中获取 SqlSession,SqlSession完全包含了面向数据库执行SQL命令的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
- 编写实体类
package mybatis.kuangshen.pojo;
public class User {
private int id;
private String name;
private String pwd;
..set/get/toString/有参构造/无参构造
}
- 同一目录下编写mapper接口和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接口,id对应namespace中的方法,resultType:SQL执行返回类型, parameterType:参数类型 -->
<mapper namespace="mybatis.kuangshen.dao.UserMapper">
<select id="getUserList" resultType="mybatis.kuangshen.pojo.User">
select * from mybatis_user
</select>
</mapper>
package mybatis.kuangshen.dao;
public interface UserMapper {
List<User> getUserList();
}
-
注册mapper
每一个mapp都需要在mybatis配置文件中注册,如上代码块3:
-
编写测试类
@Test
public static void test1() {
//1.获取sqlsession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.获取mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
System.out.println(userList);
//3.关闭sqlsession
sqlSession.close();
}
- 常见问题
- MapperRegistry问题:检查类型接口是否在核心配置文件中注册
- 绑定接口错误
- 方法名不对
- 返回类型不对
- initError,not find resource:maven项目中资源导出问题,< build>标签设置资源导出过滤
- 编码问题
- CRUD:增删改注意sqlSession.commit();
3 万能Map及模糊查询扩展
4 mybatis配置
properties(属性),settings(设置),typeAliases(类型别名),typeHandlers(类型处理器),objectFactory(对象工厂),plugins(插件),
environment(环境配置),databaseldProvider(数据库厂商标识),mappers(映射器)
1.3.1 配置之属性优化
5 mybatis缓存cache
-
缓存[cache]:存在在内存中的临时数据,将用户经常查询的数据放在缓存中,用户查询时不再从磁盘查询而是直接从缓存获取,提高性能。
-
使用目的:减少和数据库的交互次数,减少系统开销,提高性能。
-
缓存顺序:先看二级缓存中有没有 -> 再看一级缓存中有没有 -> 查询数据库
-
mybatis默认定义了两级缓存:一级缓存和二级缓存。
-
默认情况下,只开启了一级缓存(且无法关闭),(sqlsession级别缓存,也称本地缓存);
-
二级缓存需要手动开启和配置,是基于namespace级别的缓存;
-
为了提高扩展性,mybatis定义了缓存接口Cache,我们可以通过Cache接口来定义二级缓存。
-
5.1 mybatis一级缓存(本地缓存)
-
一级缓存也叫本地缓存(sqlsession级别),与数据库同一次会话期间查询到的数据会放在本地缓存中,若再获取相同数据会直接从缓存中拿;
-
一级缓存默认是开启的,在一次sqlsession中有效(也就是拿到连接到关闭这个区间段);
-
缓存失效情况:
- 查询不同东西;
- 增删改操作可能会改变原数据,所以必定会刷新缓存
- 查询不同Mapper.xml
- 手动清理缓存,如:sqlsession.clearCache();//手动清理缓存
-
编写mybatis一级缓存案例:
-
开启日志(mybatis配置文件中)
<settings> <!-- 指定 MyBatis 所用日志的具体实现 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
-
编写Test
@Test public static void test1() { //1.获取sqlsession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); //2.获取mapper UserMapper userMapper = sqlSession.getMapper(UserMapper.class); System.out.println("===========第一次查询==========="); List<User> userList1 = userMapper.getUserList(); System.out.println(userList1); System.out.println("===========第二次查询==========="); List<User> userList2 = userMapper.getUserList(); System.out.println(userList2); System.out.println("比较两个结果是否同一对象:"+ (userList1==userList2) ); //3.关闭sqlsession sqlSession.close(); } 控制台输出如下/** Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter. Class not found: org.jboss.vfs.VFS JBoss 6 VFS API is not available in this environment. Class not found: org.jboss.vfs.VirtualFile VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment. Using VFS adapter org.apache.ibatis.io.DefaultVFS PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. ===========第一次查询=========== Opening JDBC Connection Created connection 868737467. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@33c7e1bb] ==> Preparing: select * from mybatis_user ==> Parameters: <== Columns: id, name, pwd <== Row: 1, name1, pwd1 <== Row: 2, name2, pwd2 <== Row: 3, name3, pwd3 <== Row: 4, name4, pwd4 <== Total: 4 [User{id=1, name='name1', pwd='pwd1'}, User{id=2, name='name2', pwd='pwd2'}, User{id=3, name='name3', pwd='pwd3'}, User{id=4, name='name4', pwd='pwd4'}] ===========第二次查询=========== [User{id=1, name='name1', pwd='pwd1'}, User{id=2, name='name2', pwd='pwd2'}, User{id=3, name='name3', pwd='pwd3'}, User{id=4, name='name4', pwd='pwd4'}] 比较两个结果是否同一对象:true Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@33c7e1bb] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@33c7e1bb] Returned connection 868737467 to pool. */
-