MyBatis学习笔记
MyBatis
是SSM
框架之一,接下来我们进入其中MyBatis
的简要讲解吧。
1、MyBatis概念
MyBatis
本来是apache
的一个开源项目iBatis
,之后被apache software foundation
迁移到了 google code
,并且改名为 MyBatis
。2013年11月迁移到 Github
。
Mybatis
基于java
的持久层框架,它的内部封装了JDBC
,让开发人员只需要关注SQL
语句本身,不需要花费精力在驱动的加载、连接的创建、Statement
的创建等复杂的过程。并且采用了ORM
思想解决了实体类和数据库表映射的问题。对JDBC
进行了封装,屏蔽了JDBCAPI
底层的访问细节,避免我们与jdbc
的api
打交道,就能完成对数据的持久化操作。
1.1 ORM思想
O--Object java对象
R--Relation 关系,就是数据库中的一张表
M--mapping 映射
1.2 JDBC编程基础
前面我们使用的JDBC中,通过Druid
与MySQL-connector
相结合调用数据库的方式成功的能够使用数据库。但是这对于代码的维护度较高,因为其耦合度也会增大。
比如看如下代码举例:
public class TestJDBC {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT";
//获取连接
conn= DriverManager.getConnection(url,"root","root");
//SQL语句
String sql="select * from team;";
ps=conn.prepareStatement(sql);
//执行查询
rs = ps.executeQuery();
//遍历结果集
List<Team> list=new ArrayList<>();
while (rs.next()){
Team team=new Team();
team.setTeamName(rs.getString("teamName"));
team.setTeamId(rs.getInt("teamId"));
team.setCreateTime(rs.getDate("createTime"));
team.setLocation(rs.getString("location"));
list.add(team);
}
list.forEach(team -> System.out.println(team));
}catch (Exception e){
e.printStackTrace();
}finally {
try {
//关闭资源
if (rs != null){
rs.close();
}
if (ps != null){
ps.close();
}
if (conn != null){
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
如上看出,我们在学习JDBC时,想调用数据库进行仅仅简单的查找,便需要写47行代码之多。这必然有更好的解决方案。
1.3 MyBatis解决问题
- 数据库连接的创建、释放连接的频繁操作造成资源的浪费从而影响系统的性能。
- SQL语句编写在代码中,硬编码造成代码不容易维护,实际应用中SQL语句变化的可能性比较大,一旦变动就需要改变java类。
- 对结果集的解析中也存在硬编码。
2、MyBatis入门
2.1 创建数据库
CREATE TABLE `team` (
`teamId` int NOT NULL AUTO_INCREMENT COMMENT '球队ID',
`teamName` varchar(50) DEFAULT NULL COMMENT '球队名称',
`location` varchar(50) DEFAULT NULL COMMENT '球队位置',
`createTime` date DEFAULT NULL COMMENT '球队建立时间',
PRIMARY KEY (`teamId`)
) ENGINE=InnoDB AUTO_INCREMENT=1003 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
2.2 创建maven
项目添加Mybatis的jar依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
2.3 配置MyBatis的配置文件
配置文件的名称可以自定义,我这里中使用的是mybatis.xml
。配置文件放置在java/resources
中。
<?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>
<!--配置 mybatis 环境-->
<environments default="development">
<!--id:数据源的名称-->
<environment id="development">
<!--事务类型:使用 JDBC 事务,使用 Connection 的提交和回滚-->
<transactionManager type="JDBC"></transactionManager>
<!--数据源 dataSource:创建数据库 Connection 对象
type: POOLED 使用数据库的连接池
-->
<dataSource type="POOLED">
<!--连接数据库的四大参数注意数据库版本使用的是MySQL8,如果是mysql5的话,driver和url都不一样,参考学过的JDBC-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
</configuration>
2.4 编写实体类
在编写实体类时应当注意其属性必须与表中的列名一致。
package com.xaf.pojo;
import java.util.Date;
/**
* ClassName: Team
* 球队的实体类
* @author wanglina
* @version 1.0
*/
public class Team {
private Integer teamId;
private String teamName;
private String location;
private Date createTime;
@Override
public String toString() {
return "Team{" +
"teamId=" + teamId +
", teamName='" + teamName + '\'' +
", location='" + location + '\'' +
", createTime=" + createTime +
'}';
}
//省略set get方法
}
2.5 编写ORM映射文件
首先在写映射文件中应该明确几点:
- XML映射文件请务必放进与实体类一个包下。
- 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 namespace="com.xaf.pojo.Team">
<!-- id="自定义名称,id不能重复;相当于dao中的方法名称"
resultType="使用的要求:实体类中的属性名与表中的列名一致"
-->
<select id="queryAll" resultType="com.xaf.pojo.Team">
select * from team;
</select>
</mapper>
2.6 将映射文件注册到mybatis
配置文件中
<?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>
<environments default="development">
<environment id="development">
......
</environment>
</environments>
<!-- 注册映射文件 -->
<mappers>
<mapper resource="com/xaf/pojo/Team.xml"/>
</mappers>
</configuration>
2.7 配置映射文件的扫描位置
这里用pom.xml
文件配置映射文件的扫描路径。
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
//省略
</plugins>
</build>
2.8 使用MyBatis框架核心接口测试
这里使用junit
单元测试在测试类前面标注方法@test
即可。
2.9 入门案例的增删改查
2.9.1 根据ID单号查询单个对象
<!--
根据ID查询
parameterType="参数的类型",目前只支持一个参数
where teamId=#{id}: #{id}表示参数 id-自定义,只需要符合命名规范即可,没有实际对应意义
-->
<select id="findById" parameterType="int" resultType="com.xaf.pojo.Team">
select * from team where teamId=#{id}
</select>
2.9.2 增删改
<!--删除一个球队 -->
<delete id="del" >
delete from team where teamId=#{id}
</delete>
<!--更新一个球队 -->
<update id="update" parameterType="com.kkb.pojo.Team">
update team set teamName=#{teamName},location=#{location}
where teamId=#{teamId}
</update>
<!--添加一个球队
parameterType="com.kkb.pojo.Team" 将对象作为参数,
#{值} 值必须是实体类中的属性名称,其实就是占位符?
-->
<insert id="add" parameterType="com.kkb.pojo.Team" >
INSERT INTO `team` (`teamName`, `location`, `createTime`)
VALUES (#{teamName}, #{location}, #{createTime})
</insert>
3、Mybatis对象分析
3.1 Resources
Resources
类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。
3.2 SqlSessionFactoryBuilder
SqlSessionFactory
的创建 , 需要使用 SqlSessionFactoryBuilder
对象 的 build()
方法 。事实上使用SqlSessionFactoryBuilder
的原因是将SqlSessionFactory
这个复杂对象的创建交由Builder
来执行,也就是使用了建造者设计模式。
创建者模式: 又称生成器模式,是一种对象的创建模式。 可以将一个产品的内部表象与产品的生成过程分割开来, 从而可以使一个建造过程生成具有不同的内部表象的产品(将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示). 这样用户只需指定需要建造的类型就可以得到具体产品,而不需要了解具体的建造过程和细节.
在建造者模式中,角色分指导者(Director)与建造者(Builder): 用户联系指导者, 指导者指挥建造者, 最后得到产品. 建造者模式可以强制实行一种分步骤进行的建造过程.
3.3 SqlSessionFactory
SqlSessionFactory
接口对象是线程安全的,所以一个应用只需要一个该对象即可。
其中对于SqlSession
需要使用SqlSessionFactory
接口的openSession()
方法。
其中,openSession
方法没有参数,它会创建以下特性的sqlSession
。
开启一个事务,但不自动提交
将从由当前环境配置的DataSource实例中获取Connection对象。事务隔离级别将会使用驱动或数据源的默认设置。
预处理语句不会被复用,也不会批量处理更新。
openSession(true):创建一个有自动提交功能的 SqlSession
openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
openSession():同 openSession(false)
3.4 SqlSession
SqlSession
接口对象用于执行持久化方法。一个 SqlSession
对应着一次数据库会话,一次会话以SqlSession
对象的创建开始,以 SqlSession
对象的关闭结束。
SqlSession
接口对象是线程不安全,所以每次数据库会话结束前,需要马上调用其 close()
方法,将其关闭。再次需要会话会再次创建。 SqlSession
在方法内部创建,使用完毕后关闭。
这些方法被用来执行定义在 SQL 映射的 XML 文件中的 SELECT、INSERT、UPDATE 和 DELETE 语句。它们都会自行解释,每一句都使用语句的 ID 属性和参数对象,参数可以是原生类型(自动装箱或包装类)、JavaBean、POJO 或 Map。
3.5 MyBatis架构
Mybatis.xml文件是mybatis框架的全局配置文件,配置了mybatis框架运行的环境等信息。Mapper1.xml.....是SQL的映射文件,文件中配置了所有的操作数据库的sql语句,这些文件需要在全局配置文件中加载。
通过mybatis环境等配置信息构建SqlSessionFactroy ,相当于是产生连接池
由会话工厂创建SqlSession即会话(连接),操作数据库需要通过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 statemen在执行SQL语句前将输入java对象映射到sql语句中,执行完毕SQL之后,输出映射就是JDBC编码中的对preparedStatement 执行结果的定义。
4、附加:配置日志文件
4.1 添加jar包依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
4.2 添加日志配置文件&在MyBatis.xml配置文件添加日志配置
在resource
下添加log4j.properties
配置文件。
# Global logging configuration info warning error
log4j.rootLogger=DEBUG,stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
其次进入MyBatis.xml
下添加配置。
<configuration>
<!--配置日志,注意顺序:查看属性点击configuration进入查看即可-->
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
......
配置完之后就可以开始使用了。
以上是结合材料对框架的基本学习和动手。谢谢大家阅读。