初次学习应该冒出来的几个问题点:
1. 是什么?
- 一款ORM框架(对象关系映射,用来作为连接数据库的桥梁);
- Mybatis通过定义配置(mybatis-config),映射(mapper)关系,实现Java POJO与数据库进行交互,完成数据持久化(将程序的数据保存到可永久保存的存储设备中(数据库或IO文件形式存储))操作;
- 封装了JDBC(Java数据库连接,提供API来供java程序对数据库进行访问)的操作;
- 支持自定义sql(CRUD, 动态SQL),存储过程,高级映射(一对多(联合collection),多对一(关联association)),缓存(一级缓存,二级缓存,自定义缓存)以及简化事务管理(SQLSession #commit,#close)。
2. 为什么?
- 免除了JDBC繁琐的代码编写,简化与数据库数据的操作,与Spring完美契合。
3. 怎么用?
通过以下两种方式的实现:JDBC VS Mybatis,可以看出:
- Mybatis的思想:本质上是对JDBC的"上层建筑"。
- 原本JDBC的代码上的实现:
- sql语句与代码的耦合度高,违背了java的高内聚,低耦合的设计原则;
- 需要管理多个资源:Connection,Statement,ResultSet
- 从狂神说JAVA的教学视频中得到一句架构真言:
- 没有什么是加一层解决不了的!!!
4. MyBatis Demo基本实现:
1. 加入依赖
<!--必选项:Mybatis核心依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.16</version>
</dependency>
<!--必选项:连接Mysql数据库 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.4.0</version>
</dependency>
<!-- 可选项:简化JavaBean的方法定义 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
2. 配置Mybatis-config.xml
一般放在resources下,以便创建SqlSessionFactory时读取
src/main/resources/mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引入外部properties文件,设置全部属性 ${}-->
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 将POJO映射关系引入Mybatis配置中-->
<mapper class="org.example.daos.UserMapper"/>
</mappers>
</configuration>
3. 数据相关配置
src/main/resources/db.properties
username=root
password=root
url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=true
driver=com.mysql.cj.jdbc.Driver
4. 编写POJO,Mapper映射关系:
POJO User定义:
package org.example.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String password;
}
UserMapper接口定义:
package org.example.daos;
import org.example.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> getUserList();
}
UserMapper.xml映射关系定义:一般将该映射xml放在UserMapper.java的同一个包下,以便能在config中注册mapper时被识别[Q1]
<?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="org.example.daos.UserMapper">
<select id="getUserList" resultMap="User">
SELECT * FROM mybatis.user
</select>
</mapper>
5. 在Mapper中定义数据库操作逻辑(CRUD)
6. 可以通过Junit进行验证测试
###################################################
5. 回顾Mybatis之前,采用JDBC编写代码
1. 读写Driver类,完成类加载:
Class.forName("com.mysql.cj.jdbc.Driver")
2. 创建Connection连接:
DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=true", username, password)
3. 创建预编译stament:PreparedStatement,对sql语句进行预编译
connection.prepareStatement(sql);
preparedStatement.setObject(parameterIndex, param);
4. 通过PreparedStatement执行CURD操作
// 经过预编译后,execute执行器无需再传参sql语句
// 查询
preparedStatement.executeQuery();
// 更新
preparedStatement.executeUpdate();
5. 管理事务
// 这里connection是自动管理,系统默认autocommit为true,当需要自定义管理时,需要将autocommit只为false方可: connection.setAutoCommit(false);
connection.commit();
connection.rollback();
6. 关闭资源
// 完成与数据库数据交互后,记得释放关闭资源,也可以通过try-resource语句针对实现AutoCloseable接口的资源进行自动托管
// 一定要按资源顺序倒序关闭(先进后出),否则会报异常
resultSet.close();
preparedStatement.close();
connection.close();
// 自动托管代码片段
try(Connection connection = BaseDao.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql)){
resultSet = BaseDao.execute(preparedStatement, resultSet, params);
while (resultSet.next()) {
user.setId(resultSet.getInt("id"));
user.setName(resultSet.getString("name"));
user.setPwd(resultSet.getString("pwd"));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
[Q1]: 将mapper xml放在java目录下要注意:
在打包生成jar后,默认java目录下的资源xml,properties不会被加载:
解决:需要在pom.xml让项目识别到:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
加了之后就会被发现: