这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
MyBatis概述
MyBatis是一个半ORM优秀持久层框架,封装了JDBC操作的很多细节,免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,使我们只需关注SQL语句本身,它使用ORM思想实现对结果集的封装。ORM (Object Relationalp Mapping)对象关系映射把数据库表和实体类对应起来(数据库表与我们的实体类相对应,数据库表中的一行行记录就与我们一个一个实例对象相对应,数据库表字段就与我们类的属性所对应),让我们可以通过操作实体类来操作数据库表。
- 首先看传统的JDBC编码
//1. 加载数据库连接驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 获取连接
Connection connection = DriverManager.getConnection("url","username", "password");
//3. 获取预编译语句
PreparedStatement preparedStatement = connection.prepareStatement("select * from test where username=?");
//4.设置预编译参数
preparedStatement.setString(1, "param");
//5. 执行SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
//6. 处理返回结果集
List<Object> result = dealResultSet(resultSet);
//7. 关闭连接
connection.close()
从以上我们可以看出使用JDBC来进行数据库操作首先需要获得数据库的链接connection,然后创建预编译语句preparedStatement对象并向其注入参数,执行查询语句返回ResultSet结果集,从结果集中获取数据构造对象。那么有了MyBatis后,像这些数据库连接、参数注入、获取结果集的工作就不用我们来实现,而是交给MyBatis来处理,我们只需关注SQL语句本身。
MyBatis与Hibernate的区别
- MyBatis是一种半自动映射的ORM框架。所谓半自动是指我们需要手动配置POJO、SQL和映射关系,而Hibernate只需提供POJO和映射关系即可。MyBatis支持配置动态SQL和SQL优化,且MyBatis支持存储过程。
- Hibernate是一种全自动映射的ORM框架,我们只需要定义好持久化对象到数据库表的映射关系,就可以完成持久岑操作。
MyBatis的使用
入门程序
目录结构
创建一个Maven工程,引入Mybatis的相关依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
创建一个实体类
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
- MySQL数据库中创建的数据库表
Create Table CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8
创建Dao接口
public interface UserDao {
User getUserById(int id);
}
创建映射配置文件UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.mybatis.dao.UserDao">
<select id="getUserById" resultType="com.demo.mybatis.pojo.User">
select * from user where id=#{id};
</select>
</mapper>
创建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">
<!--mybatis的 主配置文件-->
<configuration>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--transactionManager代表配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置连接数据库的4个基本信息-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/students?serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
测试
public static void main(String[] args) throws IOException {
//1、读取配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//2、创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
//3、使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4、使用SqlSeesion创建Dao接口的代理对象
UserDao userDao = session.getMapper(UserDao.class);
//5、使用代理对象执行方法
System.out.println(userDao.getUserById(42));
//6、释放资源
session.close();
is.close();
}
以上就是MyBatis简单的入门程序,在现实的开发中我们并不会去用这种方式,而是用Mybatis与Spring整合、或者在SpringBoot中引入Mybatis的方式来进行开发。
MyBatis执行步骤
MyBatis操作数据库可以分成以下几个步骤:
-
首先Mybatis会通过Io流读取主配置文件
SqlMapConfig.xml以及所有的Mapper.xml映射文件。 -
构建会话工厂SqlSessionFactory。使用
new SqlSessionFactoryBuilder().bulid(InputStream in)获取构造对象,利用build方法获取SqlSessionFactory接口的实现类DefaultSqlSessionFactory,在build方法中使用XMLConfigBuilder的parse()方法将数据库、映射文件、配置文件等相关信息封装为Configuration对象,将获取的Configuration对象作为创建DefaultSqlSessionFactory的参数。 -
创建SqlSession对象。通过前面创建的DefaultSqlSessionFactory来创建SqlSession对象,该对象中包含了执行SQL的所有方法(其底层封装了JDBC连接、可以直接使用其实例来执行已映射SQL语句)
-
Executor执行器是MySQL用来操作数据库的一个接口,他会根据SqlSession传递的参数动态地生成需要执行的SQL语句。
-
在Executor接口中的方法都包含有一个MapperStatement类型的参数,该参数是对映射信息的封装,用于存储要执行的SQL语句的id,参数等。Mapper.xml映射文件中的一个SQL语句就对应一个MapperStatement对象,SQL语句配置的id就是MapperStatement的id。
-
输入参数映射。在执行持久层接口方法时,MappedStatement对象会对执行SQL语句的参数进行定义,然后Executor会通过MappedStatment对象,在执行SQL前将输入的Java对象映射到SQL语句中。
-
输出结果映射。执行完SQL语句后,MappedStatement会对数据结果进行定义,将然后Exeutor会通过MappedStatement将SQL执行后的输出结果映射为Java对象。
Mybatis核心配置文件详解
< configuration >
<configuration>是Mybatis核心配置文件的根标签。所有的其他标签都必须包含在< configuration >标签中。
< environments>
用于对数据库环境进行配置。它包含< dataSource> 和< transactionManager>两个子标签。< dataSource>用于配置数据源,他的type属性用于指定哪种数据源。< transactionManager>用于配置事务管理,他的type属性用于指定使用哪种事务管理器。
< settings >
< settings >下包含报个< setting >标签,
<setting>标签主要用于改变Mybatis运行时的行为,如开启二级缓存,开启延迟加载等。常见参数如下:
cacheEnabled:是否开启二级缓存,默认为falselazyLoadingEnabled:是否开启延迟加载,默认为falsemultipleResultSetsEnabled:是否允许单一语句返回多结果集,默认为true
< typeAliases>
配置别名,用于为配置文件中的Java类型设置一个简短的名字。< typeAliases>标签有两个子标签分别为< typeAlias>和< package>, < typeAlias>子标签只能对单个Java类设置别名,而< package name="包名">子标签,可以将所配置的包下面的所有Java类统一设置别名。▶ps:也可以通过在实体类上使用@Alias(value = "别名")注解来设置
< typeHandlers>
标签中有< typeHandler>和< package>子标签,< typeHandlers>标签的作用就是配置一个类型处理器,将预处理语句中传入的参数从Java类型转换为JDBC类型,或者对从数据库取出的结果由JDBC类型转换为Java类型。
< mappers>
标签用于指定映射文件的位置。包含子标签,其中mapper子标签有以下属性:
resource:使用类路径指定映射文件位置url:使用本地文件路径指定映射文件位置class:使用接口口指定Mapper映射文件位置package:使用包名指定Mapper映射文件的位置
Mapper映射文件
Mapper映射文件主要是用来定义操作数据库的SQL语句,在Mapper文件中,以mapper作为根节点,其下面可以配置的子节点有: select, insert, update, delete, cache, cache-ref, resultMap,下面将对他们逐个描述。
< mapper>根标签
其namespace属性用于指定该映射文件所映射的Dao接口的全限定类名。
< select>
用于映射查询语句。其包含以下几个常用属性:
id:命名空间的唯一标识,即接口Dao接口中的方法名称useCache:将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。parameterType:标识传入SQL语句额参数类的全限定类名,可选属性,因为MyBatis的类型处理器TypeHandler会推断出具体的传入参数类型。resultType:执行SQL后返回额结果集类型的全限定类名。useCache:用于控制二级缓存的开闭。resultMap:对外部 resultMap 的命名引用。resultType 和 resultMap 之间只能同时使用一个。flushCache:将其设置为true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。
< insert>
用于映射插入语句,其包含以下几个属性:
keyProperty:用于将插入或更新操作时的返回值赋值给POJO的某个属性,通常设置为主键对应的属性,如我们需要返回插入成功后的新数据的主键值,就可以利用该属性。keyColumn:当主键不是第一列时,用于设置第几列是主键。
< update>、< delete>
用于映射更新和删除的SQL语句。
< resultMap>
表示用于结果集映射,< resultMap>中包含两个常用的子标签,分别为< collection>和< association>,他们是用来处理多表时的关联关系的,< collection>用于一对多的关联关系,< association>用于一对一的关联关系。
< cache-ref>
对某一namespace命名空间的语句,只会使用该命名空间的缓存进行缓存或刷新。如果想要在多个命名空间中共享相同的缓存配置和实例,可以使用 cache-ref标签来引用另一个缓存。如<cache-ref namespace="com.demo.mybatis.EmployeeMapper"/>
< cache >
默认情况下,MyBatis只启用了本地的会话缓存即SqlSession对象的缓存(一级缓存),它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存即多个SqlSession共享缓存,那么需要在你的Mapper映射文件中添加< cache/>标签。
🏁以上就是MyBatis入门的简单介绍,后面还回继续推出系列文章,如果有错误的地方,还请留言指正,如果觉得本文对你有帮助那就点个赞👍吧😻😍