导语
首先Mybatis作为如今最为流行的ORM框架之一,那么首先需要了解的就是什么是ORM框架。
文章目录
ORM框架
ORM 对象关系模型(Object Relational Mapping),是一种为了解决面向对象与关系型数据库存在的互不匹配现象的技术,从简单的角度上来说就是通过描述对象与数据库之间的对应关系,将程序中的对象自动持久化到数据库中。
为什么需要ORM这种技术呢?
&esmp;首先在开发一个应用程序的时候,不用对象关系映射可能会用到JDBC来写很多的底层的访问数据库的代码,从而保证应用程序可以对数据库中的数据进行操作。在DAL中有很多的方法来读取对象数据、改变对象的状态等等任务,要实现这些功能代码都是重复的,所以出现了ORM这样的方案来解决这个问题。简化了将程序中的对象持久化到关系数据库中的操作。
而对于ORM来说本质就是来简化编程中对于数据库操作的编码问题。在Java中发展到现在就有两个框架是最为流行的,一个是对外宣称不需要写SQL的hibernate,而另一个就是Mybatis了,对于两者来说各自有各自的特点。在企业级的开发中可以根据需求灵活使用,在很多的传统的企业中更多的使用Hibernate,而在流行的互联网企业中通常使用的Mybatis。
Mybatis简介
在之前的博客中提到过关于Mybatis的一些知识。
首先介绍一下,Mybatis是一个标准的ORM框架,被很多的互联网企业所应用。Mybatis最早是Apache公司的一个开源的项目iBatis,在2010年的时候被迁移到了Google,并且更名为Mybatis,在2013年的时候被迁移GitHub,GitHub作为全球最大的开源代码托管平台,博主也有很多的代码在上面。
Mybatis是一个支持普通的SQL查询,存储过程和高级映射的持久层框架,几乎消除了所有的JDBC代码和参数手工设置以及对结果集的检索和封装。Mybatis可以使用XML或者基于注解的方式进行映射关系配置,将接口与Java 的POJO(Plain Old Java Objects),也就是常说的JavaBean对象进行映射称为数据库中的记录。
那么作为一个被使用广泛的框架它有那些优点呢?
- SQL 被统一的进行提取,便于统一的管理和优化操作
- SQL和代码解耦,将业务逻辑和数据访问逻辑分离,使得系统的设计更为清晰、易于维护、便于测试
- 提供的很多的映射标签,支持对象与数据库的ORM字段映射
- 提供对象关系标签,支持对象关系组件的维护
- 可以灵活的编写SQL,支持各种条件生成的动态的SQL
那么最为一个优秀的框它有没有缺点呢?
- 编写SQL语句的时候工作量很大,尤其是在关系复杂、字段多的情况下,
- SQL语句依赖与数据库,导致对于数据库的移植性很差,例如在MySQL数据库中的有些语句在Oracle中是不支持的。
Mybatis的几个重要概念
Mapper配置可以使用基于XML的Mapper配置文件来实现,也可以通过基于Java注解的方式来实现,甚至可以直接使用Mybatis提供的API来实现。
Mapper接口
这里的Mapper接口是指自定义的数据操作接口,也就是DAO层的接口。在早期的Mapper接口需要自定义实现,而在Mybatis会自动为Mapper接口创建动态代理对象。Mapper接口方法通常与Mapper配置文件中select、insert、update、delete等语句存在一一对应的关系。
Executor
在Mybatis中的所有的Mapper中的语句都是通过Executor来执行操作的,Executor是Mybatis的一个核心接口。
SqlSession
作为Mybatis的关键对象,执行持久化独享,类似于JDBC中的Connection,SqlSession对象完全是包含数据库为背景的所有执行SQL操作的方法,底层封装了JDBC连接,可以用SqlSession实例来直接执行被映射的SQL语句。
SqlSessionFactory
作为Mybatis的关键对象之一,它是单个数据库映射关系经过编译后的内存镜像,SQLSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象类获取,而SqlSessionFactoryBuilder则可以通过XML配置文件或者预先的Configuration的实例中进行构建。
- 首先加载Mapper配置的SQL映射文件,或者是注解SQL内容。
- 创建会话工厂,Mybatis通过读取配置文件的信息来构造出会话工厂(SqlSessionFacotory)。
- 创建会话。根据会话工厂,Mybatis就可以通过它来创建会话对象(SqlSession),会话对象是一个接口,该接口中包含了对数据库操作的增删改查的方法。
- 创建执行器,一个会话本身是不能直接操作数据库的,所以它使用了一个数据库执行器(Executor)的接口来执行操作
- 封装SQL对象,到这里,执行器将会处理SQL信息封装到一个对象中(MappedStatement),这个对象包括了SQL语句、输入参数映射信息和输出结果映射信息。
- 操作数据库,拥有了执行器和SQL的信息封装对象就是用这些信息进行数据库的访问操作,之后再返回处理结果,结束对应的流程。
具体的操作如上图流程所展示,那么SpringBoot是怎么整合Mybatis框架呢?
什么是Mybatis-Spring-Boot-Starter
mybatis-spring-boot-starter 是Mybatis快速集成SpringBoot提供的一个组件包,使用这个组件可以做到如下的几点
- 构建独立的应用
- 零配置
- 配置很少的XML
注意
mybatis-spring-boot-starter 是Mybatis官方开发的Starter,并不是由SpringBoot官方开发的启动包,其实是因为Mybatis看到SpringBoot的市场占有率很高,所以主动开发了自己组件整合SpringBoot的启动包,通过这种方式简化了两者整合的配置。它主要提供了两种解决方案,一种是简化后的XML配置,一种是通过注解的方式解决一切问题。
在之前的时候使用Mybatis只有通过XML的形式进行配置,到后来Spring大量的推出了注解版本的使用,Mybatis也就顺应潮流提供了注解版的支持,从这一点可以看出Mybatis也在不断的更新自己的技术支持。
下面就来演示一下如何使用XML版本。
简单示例
首先为了演示这小例子需要创建一张数据库表。
创建数据表
CREATE TABLE `user` (
`id` varchar(255) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
引入对应的依赖
首先在任何情况下都要导入Mybatis的启动器,当然这里选择的版本是SpringBoot 2.0.3,Mybatis Starter的版本是2.0.0。
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
application的配置
这里提供的是properties配置文件的方式,当然大家也可以使用Yml配置文件的形式,这个没有一定的要求,按照大家的喜好来进行配置
# Mybatis配置文件的路径
mybatis.config-location=classpath:mybatis/mybatis-config.xml
# Mybatis映射文件的路径
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
# 配置文件中实体类所在的包路径
mybatis.type-aliases-package=com.nh.mybatisxml.dao.model
#数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTF&userUnicode=true&chatacerEncoding=utf-8&userSSL=true
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
# Mybatis配置文件的路径
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
type-aliases-package: com.nh.mybatisxml.dao.model
mapper-locations: classpath:mybatis/mapper/*.xml
spring:
datasource:
url:jdbc:mysql://localhost:3306/test?serverTimezone=UTF&userUnicode=true&chatacerEncoding=utf-8&userSSL=true
password:123456
username:root
driver-class-name: com.mysql.jdbc.Driver
启动类
在启动类中添加了一个注解@MapperScan这注解表示SpringBoot在启动的时候回到指定的路径下去加载Mapper的接口。或者也可以在接口上加上@Mpper注解,当然两种方式都可以,但是有时候为了防止在开发的时候忘记加入@Mapper注解最好在启动类上标注这个注解@MapperScan。
@SpringBootApplication
@MapperScan("com.nh.mybatisxml.dao.mapper")
public class MybatisXmlApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisXmlApplication.class, args);
}
}
Mybatis公有属性
在上面提到了一个配置文件mybatis-config.xml,这个主要是通过XML的形式配置一些Mybatis的常用配置,当然刚刚在SpringBoot的配置文件的中的内容也可以通过如下的方式来进行编写当然这种方式只是一个示例,在实际使用的时候以自己项目为主。
<?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>
<!--环境配置,连接的数据库,这里使用的是MySQL-->
<environments default="mysql">
<environment id="mysql">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybbs"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<mappers>
<!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名,
如果在某包下,则要写明路径,如:com/mybatistest/config/User.xml-->
<mapper resource="User.xml"></mapper>
</mappers>
</configuration>
在自定义的这个文件中主要是配置了一些别名,这些别名在实际使用的时候就可以通过定义的别名直接进行定位,当然这里演示的是一种比较保守的方式,在高版本的Mybatis整合SpringBoot框架中可以直接使用Java类型进行映射操作。
<?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>
<typeAliases>
<typeAlias type="java.lang.Integer" alias="Integer"/>
<typeAlias type="java.lang.Long" alias="Long"/>
<typeAlias type="java.util.LinkedHashMap" alias="LinkHashMap"/>
<typeAlias type="java.util.ArrayList" alias="ArrayList"/>
<typeAlias type="java.util.LinkedList" alias="LinkedList"/>
</typeAliases>
</configuration>
添加User映射文件 User.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">
<mapper namespace="com.nh.mybatisxml.dao.mapper.UserMapper">
</mapper>
第二步,配置表结构关系
第三步,编写具体的SQL语句
<?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="com.nh.mybatisxml.dao.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.nh.mybatisxml.dao.model.User">
<id column="id" property="id" jdbcType="VARCHAR"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="password" property="password" jdbcType="VARCHAR"/>
</resultMap>
<select id="getAllUser" resultMap="BaseResultMap">
select
*
from user
</select>
</mapper>
当然Mybatis XML有的特点就是可复用,也就是说在SQL语句中一些公共的片段可以提取出来如下
<?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="com.nh.mybatisxml.dao.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.nh.mybatisxml.dao.model.User">
<id column="id" property="id" jdbcType="VARCHAR"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="password" property="password" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,name,password
</sql>
<select id="getAllUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user
</select>
</mapper>
上面这个语句就是说,需要定义了一些查询的字段通过include标签进行引入。避免一些重复的内容。
编写CRUD语句
<?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="com.nh.mybatisxml.dao.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.nh.mybatisxml.dao.model.User">
<id column="id" property="id" jdbcType="VARCHAR"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="password" property="password" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,name,password
</sql>
<select id="getAllUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user
</select>
<select id="getUserById" parameterType="String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user
where id = #{id}
</select>
<insert id="addUser" parameterType="com.nh.mybatisxml.dao.model.User">
insert into
user (id ,name ,password)
values (#{id},#{name},#{password})
</insert>
<update id="updateUser" parameterType="com.nh.mybatisxml.dao.model.User">
update user
set
<if test="name!=null">name=#{name}</if>
<if test="password!=null">password=#{name}</if>
where id = #{id}
</update>
<delete id="deleteUserById" parameterType="String">
delete from
user
where id = #{id}
</delete>
</mapper>
在配置文件中看到了if语句,这就是说在实际开发过程中可以动态的加载语句,也就是Mybatis的最大特点。
编写Dao层代码
public interface UserMapper {
public List<User> getAllUser();
public User getUserById(String id);
public int addUser(User user);
public int updateUser(User user);
public int deleteUserById(String id);
}
这里需要说明一点的,为什么在配置文件中没有写返回值,而在这里的时候需给这些接口函数加上返回值呢?其实在使用MySQL进行CRUD操作的时候每条语句都是带有返回值的,而这个返回值就是操作数据的条数,如果操作失败则返回数据为0表示没有一条语句执行成功。所以可以根据返回的操作数来判断执行是否成功了。
到这里我们关于Mybatis的配置就完成了。接下来就是进行测试了,这里提供两种测试方式,一种是通过SpringBoot提供的测试类来测试,一种是基于编写Service层以及Controller或者可以直接使用Controller进行调用也可以。
总结
上面的内容简单的构建了Dao层到数据库的逻辑,通过上面的示例简单的了解的惯有Mybatis与SpringBoot的整合操作,下次博客中会继续这个项目进行分页操作的讲解。谢谢大家关注