JDBC,是一种 SUN 为统一数据库访问而制定的接口规范。数据库厂商只要实现该接口,Java 层就可以通过该接口访问、管理数据库。它们之间,通过 桥接模式 (事物对象和其具体行为、具体特征分离开来,使它们可以各自独立的变化) 实现数据访问。
MyBatis 是 ORM(Object/Relational Mapping,对象-关系映射) 框架。其插入在 JDBC 和应用程序之间完成了对数据库操作的封装,但是同时,由于其支持定制化 SQL。
JDBC
JDBC Driver 是 JDBC API 的具体实现。应用直接通过 API ,间接通过驱动完成和数据库之间的交互。
在 JDBC API 中,主要包括以下几个对象:
DataSource:代表着可以连接物理数据源的工厂(A factory for connections to the physical data source that this DataSource object represents. )。该接口,通常由数据库厂商实现。
1
2
3
4public interface DataSource extends CommonDataSource, Wrapper {
Connection getConnection() throws SQLException;
Connection getConnection(String username, String password) throws SQLException;
}Connection:控制和数据库之间的连接。 SQL statements are executed and results are returned within the context of a connection.
1
2
3
4
5
6
7
8
9public interface Connection extends Wrapper, AutoCloseable {
Statement createStatement() throws SQLException;
PreparedStatement prepareStatement(String sql) throws SQLException;
CallableStatement prepareCall(String sql) throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
......
}Statement:用于执行静态 SQL 语句,并返回结果。
1
2
3
4
5
6
7
8public interface Statement extends Wrapper, AutoCloseable {
ResultSet executeQuery(String sql) throws SQLException;
int executeUpdate(String sql) throws SQLException;
oid close() throws SQLException;
void addBatch( String sql ) throws SQLException;
int[] executeBatch() throws SQLException;
......
}PreparedStatement:继承了 Statement,代表了一个预编译的 SQL 语句。预编译的语句被存储在 PreparedStatement 中,可以被多次使用。
1
2
3
4
5
6
7public interface PreparedStatement extends Statement {
ResultSet executeQuery() throws SQLException;
void setShort(int parameterIndex, short x) throws SQLException;
void setObject(int parameterIndex, Object x) throws SQLException;
boolean execute() throws SQLException;
......
}使用示例:
1
2
3
4
5
6
7Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url,user,password);
String sql = "update user set username=? where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"Fant.J");
preparedStatement.setInt(2,27);CallableStatement:CallableStatement 支持调用存储过程,提供了对输入/输出参数的支持。
1
2
3
4
5
6
7
8
9public interface CallableStatement extends PreparedStatement {
void registerOutParameter(int parameterIndex, int sqlType) throws SQLException;
void setByte(String parameterName, byte x) throws SQLException;
void setString(String parameterName, String x) throws SQLException;
void setBlob (String parameterName, Blob x) throws SQLException;
void setBinaryStream(String parameterName, java.io.InputStream x,
long length) throws SQLException;
......
}ResultSet:Statement 执行完的结果集。
1
2
3
4
5
6public interface ResultSet extends Wrapper, AutoCloseable {
boolean next() throws SQLException;
String getString(int columnIndex) throws SQLException;
boolean getBoolean(int columnIndex) throws SQLException;
......
}
MyBatis
MyBaits 是一个基于 SqlSessionFactory 构建的支持定制化 SQL、存储过程以及高级映射的持久层框架。
对于 SqlSessionFactory 而言,它的作用是生成 SqlSession 接口对象,这个接口对象(单例保持在 MyBatis 框架中)是 MyBatis 操作的核心。
配置
SqlSessionFactory 是通过 Configuration 完成配置的。而 Configuration 的配置,实际上是通过配置文件(比如 application.properties)进行。
(图片来源《深入浅出SpringBoot 2.x》)
可配置项如上所示:
****properties(属性)****:属性文件一般采用 Spring 进行配置。
1
2
3
4
5spring.datasource.url=jdbc:mysql://localhost:3310/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
......****settings(设置)****:该配置将改变 MyBatis 底层行为,可以配置映射规则,如自动映射和驼峰映射、执行器类型、缓存等内容。更多设置
1
2
3
4
5
6
7
8
9
10#全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。
mybatis.configuration.lazy-loading-enabled=true
#使全局的映射器启用或禁用缓存。
mybatis.configuration.cache-enabled=true
#配置默认的执行器,可选类型包括 SIMPLE 、REUSE(prepared statements) 、BATCH
mybatis.configuration.default-executor-type=simple
#设置本地缓存范围 在默认配置情况下,mybatis会将同一session内的查询结果都放在local cache中,
#这样可以提高性能,避免每次都hit到数据库
mybatis.configuration.local-cache-scope=session
......****typeAliases(类型别名)****:由于全限定类名较长,因此,MyBatis会对常用的类提供默认的别名,此外,还允许我们通过 typeAliases 配置自定义的别名。
****typeHandlers(类型处理器)****:在 MyBaits 写入和读取数据库的过程中,对不同类型的数据进行自定义转换。
****Mappers(映射器)****:提供 SQL 和 POJO 映射关系。
核心概念
待补充。。。
在 SpringBoot 中使用 Mybatis(以 MySQL 为例)
添加依赖:
1 | <dependency> |
在 application.properties 添加基本配置:
1 | spring.datasource.url=jdbc:mysql://localhost:3310/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true |
设置扫描:
1 |
|
设置 Mapper:
1 | package com.yuegs.mybatis.mapper; |
测试:
1 |
|
MyBatis 和 JDBC 的关联
可以看到,MyBatis 和 JDBC 之间有很多相似概念。MyBatis 使得 JDBC 的操作更加方便、快捷、灵活,如下图示,以后有空看完 MyBatis 源码后再做补充。
(图片来源)
参考文档:
Database Access (MyBatis3)
秒懂设计模式之桥接模式(Bridge Pattern)
How Does JDBC Work?
JDBC数据源(DataSource)的简单实现
执行对象Statement、PreparedStatement和CallableStatement详解 JDBC简介(五)
JDBC(五)PreparedStatement 详解
聊聊MyBatis缓存机制
MyBatis 核心配置综述之 Configuration 详解
从mybatis到mybatis-spring-boot-starter
MyBatis SQL是如何执行的?