从JDBC到Mybatis
JDBC
概述
JDBC代表Java数据库连接(Java Database Connectivity),它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API,换句话说:JDBC是用于在Java语言编程中与数据库连接的API。
从根本上说,JDBC是一个规范,它提供了一整套接口,允许以一种可移植的访问底层数据库API。
所有这些不同的可执行文件都能够使用JDBC驱动程序来访问数据库,并用于存储数据到数据库中。
JDBC提供与ODBC相同的功能,允许Java程序包含与数据库无关的代码(同样的代码,只需要指定使用的数据库类型,不需要重修改数据库查询或操作代码)。
JDBC连接数据库
public static void main(String[] args) {
String driverName="com.microsoft.sqlserver.jdbc.SQLServerDriver";
String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=studentAdmin";
String userName="sa";
String userPwd="welcome123";
try{
Class.forName(driverName);
Connection dbConn=DriverManager.getConnection(dbURL, userName, userPwd);
System.out.println("数据库连接成功");
String sql="select * from student";
PreparedStatement pst= dbConn.prepareStatement(sql);//预编译SQL语句
ResultSet results=pst.executeQuery();//执行SQL语句,并返回结果集
while(results.next()){
int no=results.getInt("no");///no是数据库中字段名
String name=results.getString("name");
int age=results.getInt(3);//3是数据库中字段的位置
System.out.println(no+"\t"+name+"\t"+age);
}
}catch(Exception e){
System.out.println("失败");
}
}
缺点:
- 数据库频繁地连接开启和关闭,造成资源的浪费。(使用数据库连接池进行管理)
- SQL语句、preparedStatement设置参数硬编码在Java代码中,不利于系统维护。(使用xml进行配置)
- resultSet遍历结果集数据时,也存在硬编码。(将查询的结果集,自动映射成Java对象)
Mybatis
为什么选择MyBatis
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
MyBatis 避免了几乎所有的 JDBC 代码和手工设置参数以及抽取结果集。
MyBatis 使用简单的 XML 或注解来配置和映射基本体,将接口和 Java的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
(选自官网)
使用mybatis可以只关注SQL语句本身,而不需要关注注册驱动,获取连接,获取传输器,释放资源等操作。
mybatis可以将要执行的SQL语句使用xml文件的方式或者注解方式配置起来,在执行时,将Java对象中携带的参数值和SQL骨架进行映射,生成最终要执行的SQL,将执行的结果处理后再返回。
概述
MyBatis是一个Java持久化框架,它通过XML
描述符或注解把对象与存储过程
或SQL语句
关联起来,映射成数据库内对应的纪录。
MyBatis是在Apache许可证 2.0
下分发的自由软件,是iBATIS 3.0
的分支版本,其维护团队也包含iBATIS
的初创成员。
与其他对象关系映射框架不同,MyBatis没有将Java对象与数据库表关联起来,而是将Java方法与SQL语句关联。MyBatis允许用户充分利用数据库的各种功能,例如存储过程、视图、各种复杂的查询以及某数据库的专有特性。如果要对遗留数据库、不规范的数据库进行操作,或者要完全控制SQL的执行,MyBatis是一个不错的选择。
与JDBC相比,MyBatis简化了相关代码:SQL语句在一行代码中就能执行。MyBatis提供了一个映射引擎,声明式的把SQL语句执行结果与对象树映射起来。通过使用一种内建的类XML表达式语言,或者使用Apache Velocity
集成的插件,SQL语句可以被动态的生成。
MyBatis与Spring Framework
和Google Guice
集成,这使开发者免于依赖性问题。
MyBatis支持声明式数据缓存(declarative data caching)。当一条SQL语句被标记为“可缓存”后,首次执行它时从数据库获取的所有数据会被存储在一段高速缓存中,今后执行这条语句时就会从高速缓存中读取结果,而不是再次命中数据库。MyBatis提供了基于 Java HashMap 的默认缓存实现,以及用于与OSCache
、Ehcache
、Hazelcast
和Memcached
连接的默认连接器。MyBatis还提供API供其他缓存实现使用。
优势
- JDBC连接访问数据库有大量重复的代码,而mybatis可以极大的简化JDBC代码:注册驱动、获取连接、获取传输器、释放资源。
- JDBC没有自带连接池,而mybatis自带的有连接池。
- JDBC中是将SQL语句、连接参数写死在程序中,而mybatis是将SQL语句以及连接参数都写在配置文件中。
- JDBC执行查询后得到的ResultSet我们需要手动处理,而mybatis执行查询后得到的结果会处理完后,将处理后的结果返回。
MyBatis框架图
运行流程
- 在SQLMapConfig.xml(mybati的全局配置文件)中配置mybatis的运行环境等信息。并在其中加载mapper.xml(sql映射文件,配置了操作数据库的SQL语句)文件。
- 通过mybatis环境等配置信息构造SQLSessionFactory会话工厂。 由会话工厂创建SQLSession来操作数据库。
- mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有基本执行器和缓存执行器两个实现。
- Mapped Statement也是mybatis一个底层封装对象,包装了mybatis配置信息及SQL映射信息等。mapper.xml文件中一个SQL对应一个Mapped
Statement 对象,SQL的id即是Mapped Statement的id。 - Mapped Statement对SQL执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行SQL前将输入的Java对象映射至SQL中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
- Mapped Statement对SQL执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行SQL后将输出结果映射至Java对象中,输出结果映射过程相当于jdbc编程中结果的解析处理过程。
IDEA环境下Spring-Mybatis
创建spring-mybatis方法:SpringBoot整合Mybatis完整详细版
按照上面方法创建项目需要修改的地方:
- UserMapper接口的注解应该改为@Mapper
package com.example.mybatis.mapper;
import com.example.mybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
User Sel(int id);
}
- application-dev.xml中的
mapper-locations: classpath:mapping/*Mapper.xml
写错,应该为mapper-locations: classpath:mapping/*Mapping.xml
server:
port: 8080
spring:
datasource:
username: root
password: 20010304
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mapping/*Mapper.xml
type-aliases-package: com.example.mybatis.entity
#showSql
logging:
level:
com:
example:
mapper : debug
运行结果:
测试成功,基本框架搭建成功
JDBC到Mybatis的改进
-
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能
解决问题:
数据库连接的获取和关闭我们可以使用数据库连接池来解决资源浪费的问题。通过连接池就可以反复利用已经建立的连接去访问数据库了。减少连接的开启和关闭的时间。 -
Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决问题:
Mybatis将SQL语句写在配置文件中通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。这样当需要更改SQL时,只需要更改配置文件。(不影响接口的情况下) -
使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
解决问题:
同上,配置文件。 -
对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
解决问题:
Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。