MyBatis介绍及教程

  • Post author:
  • Post category:其他




MyBatis简介

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。



MyBatis的优缺点


优点:

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
  • 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql。


缺点:

  • 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
  • SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
  • 框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
  • 二级缓存机制不佳



MyBatis如何安装?

如果使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可。

github下载地址(https://github.com/mybatis/mybatis-3/releases)

如果使用 Maven 来构建项目,则需将下面的 dependency 代码置于 pom.xml 文件中:

<dependency>  <groupId>org.mybatis</groupId>  <artifactId>mybatis</artifactId>  <version>x.x.x</version></dependency>



MyBatis开发流程



1、准备工作

在数据库中建表,并且添加几条数据

在这里插入图片描述

将相关jar包导入项目

在这里插入图片描述

druid:数据源,替换mybatis自带的数据源(不替换也可以)

log4j:日志

lombok:可以省去写get,set等冗长的方法(详细看

关于lombok.jar的使用_橘子恶霸、的博客-CSDN博客

mybatis:mybaris(必须)

mysql-connector:mysql驱动(必须)



2、创建实体类与dao层

在这里插入图片描述

Book.java:

package com.dyit.entity;

import java.io.Serializable;
import java.util.Date;

import org.apache.ibatis.type.Alias;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Alias("Book")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book implements Serializable{

	private Integer id;
	private String isbn;//出版编号
	private String title;//书籍名称
	private String author;//作者
	private String cover;//封面
	private Double price;//价格
	private Date date;//出版日期
}

说明:@Alias(“Book”)为类的别名

IBookMapper.java

package com.dyit.mapper;

import org.apache.ibatis.annotations.Param;

import com.dyit.entity.Book;

public interface IBookMapper {
    //添加树
	void updateAuthorOrPrice(@Param("id")int id,@Param("price")Double price,@Param("author")String author);
    //通过id查找书
	Book findById(@Param("id") int id);
}

说明:@Param(注解绑定参数)



3、数据库配置信息

在src\resource\druid下创建druid.properties(使用的是druid数据源)

druid.driver = com.mysql.cj.jdbc.Driver
druid.url = jdbc:mysql://localhost:3306/mybatis_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
druid.username=root
druid.password=123456

按照自己的数据库配置



4、创建并编写MyBatis配置文件(mybatis-config.xml)

在src/resource/config下创建mybatis-config.xml

在这里插入图片描述

mybatis-config.xml初始模板:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <!--配置标签的顺序:(properties?, settings?, typeAliases?,
        typeHandlers?, objectFactory?, objectWrapperFactory?,
        reflectorFactory?, plugins?, environments?,
        databaseIdProvider?, mappers?)-->


</configuration>

配置相关信息

<?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="resource/druid/druid.properties"/>
	<!-- 读取实体类别名 -->
	<typeAliases>
		<package name="com.dyit.entity"/>
	</typeAliases>
	
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC"/><!-- 配置数据库事务管理 -->
				<dataSource type="com.dyit.util.MybatisDataSource"><!-- 读取数据源信息 -->
					<property name="driverClassName" value="${druid.driver}"/>
					<property name="url" value="${druid.url}"/>
					<property name="username" value="${druid.username}"/>
					<property name="password" value="${druid.password}"/>
				</dataSource>			
		</environment>
	</environments>
	
	<!-- 加载xxx.mapper.xml -->
	<mappers>
		<mapper resource="resource/mapper/Book.mapper.xml"/>
	</mappers>
</configuration>

在environments标签项中配置相关信息,default属性和id属性可根据自己意愿填写(其实就是个名字而已),我们在这选用的不是是MyBatis默认的连接池,使用dataSource 标签的type属性读取druid



5、日志配置

在src下创建log4j.properties配置日志信息

log4j.rootLogger=debug,stdout,logfile
#console output
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.stdout.PatternLayout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}<-->%F<-->%p<-->%m%n 
#file output
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=D:/logs/log.log
log4j.appender.logfile.layout=org.apache.log4j.SimpleLayout
log4j.appender.logfile.PatternLayout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}<-->%F<-->%p<-->%m%n

#mybatis log 
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG




6、配置xxx.mapper.xml

IBookMapper.java中的抽象方法,如何去实现它们呢?

这就要靠我们的Mapper配置文件了,一个Dao接口文件对应一个Mapper配置文件。MyBatis替我们封装了数据访问的其他操作,我们只需要关注Sql语句本身就可以了,而Sql语句写在哪呢?就是Mappe配置文件中。

在src\resource\mapper下创建Book.mapper.xml

下面是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="com.dao.UserDao">


</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="com.dyit.mapper.IBookMapper">
    
	<cache/><!-- 开启二级缓存 -->

	<resultMap type="Book" id="BookMap">
		<id property="id" column="book_id"/>
		<result property="isbn" column="book_isbn"/>
		<result property="title" column="book_title"/>
		<result property="author" column="book_author"/>
		<result property="price" column="book_price"/>
		<result property="cover" column="book_cover"/>
		<result property="date" column="book_date"/>
	</resultMap>
	
	<insert id="save">
		INSERT INTO book_tab(book_isbn,book_title,book_author,book_date,book_price,book_cover)
		 VALUES(#{isbn},#{title},#{author},#{date},#{price},#{cover})
	</insert>
	
	<select id="findById" resultMap="BookMap">
		SELECT * FROM book_tab WHERE book_id = #{id}
	</select>
	
</mapper>

resultMap 标签就是属性关系映射,来解决字段名不一致的问题,当我们需要用的时候,将select标签的resultType属性改为resultMap就可以了。



7、编写测试类

新建个test包创建单元测试

package test;

import com.dyit.entity.*;
import java.io.IOException;
import java.io.Reader;
import java.util.Date;
import java.util.List;

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.After;
import org.junit.Before;
import org.junit.Test;

import com.dyit.mapper.IBookMapper;

public class TestMybatis {
	
	private SqlSession sqlSession;
	
	@Before
	public void before() throws IOException {
		//读取mybatis-config.xml获取一个字符流
		Reader in = Resources.getResourceAsReader("resource/config/mybatis-config.xml");
		//通过字符流获取sqlSession工厂
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//拿到sqlSession
		sqlSession = sqlSessionFactory.openSession();
	}
	
	@After
	public void after() {
		//事务提交,关闭资源
		sqlSession.commit();
		sqlSession.close();
	}

	@Test
	public void testsave() throws IOException {
		IBookMapper mapper = sqlSession.getMapper(IBookMapper.class);
		
		Book book = new Book(null,"dyit-03","c#入门","张三","java.png",77.00,new Date());
		
		mapper.save(book);		
	}
	
	
	@Test
	public void testfindById() throws IOException {
		
		IBookMapper mapper = sqlSession.getMapper(IBookMapper.class);
		
		Book book = mapper.findById(1);
		System.out.println(book.toString());
		
	}	
	
}


savetest()测试结果

在这里插入图片描述

testfindById()测试结果

在这里插入图片描述



MyBatis的工作原理以及核心流程介绍

原文:(http://www.mybatis.cn/archives/706.html)

MyBatis的底层操作封装了JDBC的API,MyBatis的工作原理以及核心流程与JDBC的使用步骤一脉相承,MyBatis的核心对象(SqlSession,Executor)与JDBC的核心对象(Connection,Statement)相互对应。本文的核心观点是:从JDBC入手并立足于JDBC,才能深入的理解MyBatis的工作原理以及核心流程。



1、如何掌握MyBatis的工作原理?

关于MyBatis的工作原理,网上的文章是汗牛充栋,但是站长觉得,要结合JDBC来理解MyBatis的工作原理往往才能更透彻。我们知道,JDBC有四个核心对象:

(1)DriverManager,用于注册数据库连接

(2)Connection,与数据库连接对象

(3)Statement/PrepareStatement,操作数据库SQL语句的对象

(4)ResultSet,结果集或一张虚拟表

而MyBatis也有四大核心对象:

(1)SqlSession对象,该对象中包含了执行SQL语句的所有方法【1】。类似于JDBC里面的Connection 【2】。

(2)Executor接口,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。类似于JDBC里面的Statement/PrepareStatement。

(3)MappedStatement对象,该对象是对映射SQL的封装,用于存储要映射的SQL语句的id、参数等信息。

(4)ResultHandler对象,用于对返回的结果进行处理,最终得到自己想要的数据格式或类型。可以自定义返回类型。



2、MyBatis的工作原理以及核心流程详解

MyBatis的工作原理如下图所示:
在这里插入图片描述

上面中流程就是MyBatis内部核心流程,每一步流程的详细说明如下文所述:

(1)读取MyBatis的配置文件。mybatis-config.xml为MyBatis的全局配置文件,用于配置数据库连接信息。

(2)加载映射文件。映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在MyBatis配置文件mybatis-config.xml中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

(3)构造会话工厂。通过MyBatis的环境配置信息构建会话工厂SqlSessionFactory。

(4)创建会话对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法。

(5)Executor执行器。MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。

(6)MappedStatement对象。在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。

(7)输入参数映射。输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对preparedStatement对象设置参数的过程。

(8)输出结果映射。输出结果类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输出结果映射过程类似于JDBC对结果集的解析过程。



备注

备注【1】的说明如下:

在JDBC中,Connection不直接执行SQL方法,而是利用Statement或者PrepareStatement来执行方法。

在使用JDBC建立了连接之后,可以使用Connection接口的createStatement()方法来获取Statement对象,也可以调用prepareStatement()方法获得PrepareStatement对象,通过executeUpdate()方法来执行SQL语句。

而在MyBatis中,SqlSession对象包含了执行SQL语句的所有方法。但是它是委托Executor执行的。

从某种意义上来看,MyBatis里面的SqlSession类似于JDBC中的Connection,他们都是委托给其他类去执行。

最后说一点,虽然SqlSession对象包含了执行SQL语句的所有方法,但是它同样包括了:

<T> T getMapper(Class<T> type);

所以SqlSession也可以委托给映射器来执行数据的增删改查操作。如下代码所示:

// 获得mapper接口的代理对象
PersonMapper pm = session.getMapper(PersonMapper.class);
// 直接调用接口的方法,查询id为1的Peson数据
Person p2 = pm.selectPersonById(1);

这上面来看,SqlSession是不是也类似于JDBC中的Connection呢。



版权声明:本文为qq_55627064原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。