MyBatis框架(1)
什么是“框架”?
我们可以把一个工程比作盖楼房,框架就是整个建筑的骨架,就像是我们要在这个骨架上去实现不同的类型、用途的房子。
框架的优势及劣势?
框架的优势
- 提高开发效率,降低开发难度
- 提高代码的规范性和可维护性
- 提高软件的性能
框架的劣势
- 使软件应用和系统的可维护性变差
- 代码重用性变低
Java程序员使用的主流框架
- Spring框架:为POJO(Plain Ordinary Java Object, 普通Java对象)提供企业级的服务
- Spring MVC框架:采用松耦合、可插拔的组件结构针对Web开发的框架
- MyBatis框架:半自动化的ORM(Object Relational Mapping, 对象关系映射),提供在实体类和SQL语句之间建立映射关系的框架,在互联网应用开发广泛使用
- Spring Boot框架:便于配置Spring,为了快速且便捷的构建项目的基于Spring框架的应用
- Spring Cloud框架:将Spring Boot框架再封装,为微服务架构提供的有序化集合框架
MyBatis框架
传统JDBC操作数据库存在着与数据库交互过多、读写数据量较大、代码冗余、复用性低等缺点,在企业级开发中一般使用MyBatis等ORM框架来操作数据库
MyBatis框架概述
MyBatis框架是一个支持普通SQL操作、存储及高级映射的持久层框架,通过使用简单的XML或注解进行配置和原始映射,将接口和Java的POJO映射为数据库中的记录,使开发人员可以使用面向对象的编程思想和方式来操作数据库
MyBatis对JDBC问题的解决方案
- JDBC频繁创建、释放数据库造成系统资源浪费,影响系统性能的解决方案是使用MyBatis框架在项目中的SqlMapConfig.xml文件中配置数据库连接池,使用数据库连接池管理数据库连接
- SQL硬编码造成不易于维护,SQL变化导致Java代码相应变化,违反开闭原则的解决方案是将SQL语句配置给MyBatis映射文件中,实现与Java代码分离
- 使用PreparedStatement向占位符传参存在硬编码,导致如果要修改SQL就要相应修改代码,导致难以维护的解决方案是使用使用Mabatis自动将Java对象映射至SQL语句中,通过Statement的parameterType定义输入参数类型即可
- JDBC解析结果集查询列名存在硬编码,导致系统难以维护的解决方案是使用MyBatis自动将SQL执行结果映射给Java对象,通过Statement中的resultType定义输出结果类型
MyBatis环境搭建
-
启动IDEA,选择工具栏的“File”→"New"→"Project",在弹出的窗口选择"Maven"→"Next"
-
"Name"处为项目命名,"Location"为项目选择存放路径
-
"Artifact Coordinates"下拉框可以设置"GroupID"可以设置公司倒置网络域名,"Artifact"一般直接设置为项目名,"Version"为IDEA默认版本
-
我们选择“JDK8(JDK1.8)”版本,“ProjectName”为“mybatistest”,“GroupId”输入”com.itheima“,路径自选,其他一般情况不需要修改
-
打开"pom.xml"引入Maven仓库的JAR包,Maven是一个项目管理工具,只需要将JAR包的依赖引入项目的"pom.xml"就可以调用JAR包中的类,添加"dependences"依赖例如下面代码(第一次使用引入依赖需要在联网状态进行,且首次引入依赖可能需要较长时间,可以搜索一下如何使用阿里云镜像配置依赖,如若依赖配置不成功可以点击右边栏的Maven,再点击刷新尝试):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>mybatistest</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--配置Mybatis核心包依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!--配置MySQL核心包依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!--配置JUnit测试包依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<!--将项目中的src/main/java目录下的XML等资源文件编译进classes文件夹-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
- 在MySQL中创建一个名称为"mybatis"的库,SQL语句如下:
# 创建数据库
DROP DATABASE IF EXSITS mybatis;
CREATE DATABASE mybatis;
- 在项目的src/main/resources目录创建一个"file"并命名为"db.properties",并修改其中url选项配置为你的数据库名,还有下面的用户名及密码
# Configure Database Connection Parameters.
# Driver, The JDBC driver class for MySQL.
mysql.driver=com.mysql.cj.jdbc.Driver
# URL, The JDBC URL for connecting to the MySQL database.
mysql.url=jdbc:mysql://localhost:3306/YOURSDATABASE?serverTimezone=UTC&\
characterEncoding=utf8&useUnicode=true&useSSL=false
# Username, The username for the database connection.
mysql.username=YOURSUSERNAME
# Password, The password for the database connection.
mysql.password=YOURSPASSWORD
- 在src/main/resources目录下创建"file"命名为"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>
<!-- 加载类路径下的属性文件 -->
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 使用db.properties文件中的配置 -->
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
至此,我们就成功搭建好一个MyBatis的开发环境了,总结一下步骤为:创建工程、引入相关依赖、创建数据库、创建数据库连接配置文件、创建MyBatis的核心配置文件
MyBatis入门程序
- 在mybatis数据库中创建users表,插入两条数据
# 操作mybatis库
USE mybatis;
# 创建user表
CREATE TABLE users(
uid INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(20) NOT NULL ,
uage INT NOT NULL
);
# 插入两条数据
INSERT INTO users(uid,uname,uage)
VALUES (null,'张三',20),
(null,'李四',18);
- 在src/main/java目录下创建com.itheima.pojo包,再在该包下创建一个User类,用于封装User对象的所有属性,我们在生成get、set、toString方法可以使用Alt+Insert的快捷键,未来还可以使用Lombok,这里先使用常规创建
package com.itheima.pojo;
/**
* @author Zhang
*/
// 该类用于对应的user表中的字段,封装User对象的属性
public class User {
// 用户ID,对应user表中的uid字段
private int uid;
// 用户名,对应user表中的uname字段
private String uname;
// 用户年龄,对应user表中的uage字段
private int uage;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getUage() {
return uage;
}
public void setUage(int uage) {
this.uage = uage;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", uname='" + uname + '\'' +
", uage=" + uage +
'}';
}
}
- 在src/main/resources目录下创建一个mapper包,用来存放映射文件,再创建一个UserMapper.xml。这个文件主要用于配置SQL语句和Java对象之间映射,使SQL查询出来的数据可以被封装成Java对象,一个项目中可以有多个映射文件,每个实体类都可以由他对应的映射文件,通常命名为POJO体类名+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">
<!-- mapper为映射的根节点 -->
<!-- namespace指定DAO接口的完整类名
mybatis会依据这个接口动态的创建一个实现类去实现这个接口
而这个实现类是一个Mapper对象 -->
<mapper namespace="com.itheima.pojo.User">
<!-- id = "接口中的方法名"
parameterType = "传入的参数类型"
resultType = "返回实体类的对象,使用包.类名"
-->
<select id="findById" parameterType="int"
resultType="com.itheima.pojo.User">
SELECT * FROM users WHERE uid = #{id}
</select>
</mapper>
- 增加mybatis-config.xml映射文件的</environments>和</configuration>之间填写UserMapper.xml的路径,以便将UserMapper.xml映射文件加载进程序中
<!-- mapping 文件路径配置 -->
<mappers>
<mapper resource="mapper/UserMapper.xml" />
</mappers>
- 在src/main/java下创建Test包,在该包下创建UserTest类,用于测试
package Test;
import com.itheima.pojo.User;
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 org.junit.Test;
import java.io.Reader;
public class UserTest {
@Test
public void userFindByIdTest() {
String resources = "mybatis-config.xml";
// 创建流
Reader reader = null;
try {
// 读取mybatis-config.xml文件内容到reader对象中
reader = Resources.getResourceAsReader(resources);
} catch (Exception e) {
e.printStackTrace();
}
// 初始化MyBatis数据库,创建SqlSessionFactory类的实例
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
// 创建SqlSession的实例
SqlSession session = sqlMapper.openSession();
// 传入参数查询,返回结果
User user = session.selectOne("findById", 1);
// 输出结果
System.out.println(user.getUname());
// 关闭Session
session.close();
}
}
注意我们要在"src/main/resources"包处右键选择"Mark Directory as",再选择"Resources Root",将该包设计为根资源包,之后运行测试类观察运行结果,尝试分析MyBatis的工作原理
MyBatis工作原理
- MyBatis读取核心配置文件mybatis-config.xml,其中配置了MyBatis的运行环境等信息
- 加载映射文件Mapper.xml,可以由mybatis-config.xml对其加载
- 构造会话工厂,SqlSeeionFactory,用于创建SqlSeesion
- 创建会话对象,SqlSessionFactory创建SqlSession对象,其中包含所有执行SQL语句的方法
- 创建执行器,对象本身不能操作数据库,实际上是MyBatis的底层定义Executor接口实现操作数据库,其会根据SqlSession传递参数来动态生成SQL语句,同时负责查询缓存地维护
- 封装SQL信息,执行器将SQL信息封装到MapperStatement对象,其中存储即将映射的SQL语句。Mapper.xml中每条SQL语句对应一个MapperStatement对象,SQL语句的id即MapperStatement的id,Executor接口会在执行SQL语句前通过MapperStatement对象输入的参数映射进SQL语句
- 操作数据库,根据动态生成的SQL进行数据库操作
包含所有执行SQL语句的方法 - 创建执行器,对象本身不能操作数据库,实际上是MyBatis的底层定义Executor接口实现操作数据库,其会根据SqlSession传递参数来动态生成SQL语句,同时负责查询缓存地维护
- 封装SQL信息,执行器将SQL信息封装到MapperStatement对象,其中存储即将映射的SQL语句。Mapper.xml中每条SQL语句对应一个MapperStatement对象,SQL语句的id即MapperStatement的id,Executor接口会在执行SQL语句前通过MapperStatement对象输入的参数映射进SQL语句
- 操作数据库,根据动态生成的SQL进行数据库操作
- 输出结果映射,SQL语句执行后,通过MapperStatement对象将输出结果映射到Java对象中