As we all know, MyBatis
is a product that encapsulates JDBC
, so , before talking about MyBatis source code, we must first understand JDBC
.
JDCB
JDBC Case:
public class JdbcDemo { public static final String URL = "jdbc:mysql://localhost:3306/mblog"; public static final String USER = "root"; public static final String PASSWORD = "123456"; public static void main(String[] args) throws Exception { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1"); while(rs.next()){ System.out.println("name: "+rs.getString("name")+" 年龄:"+rs.getInt("age")); } } }
Description:
Database driver:
Class.forName("com.mysql.jdbc.Driver");
Get connection:
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
Create Statement
or PreparedStatement
object:
Statement stmt = conn.createStatement();
执行sql数据库查询:
ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1");
解析结果集:
System.out.println("name: "+rs.getString("name")+" 年龄:"+rs.getInt("age"));
在使用的时候,业务处理完成后记得关闭相关资源
使用过JDCB的朋友都知道,JDBC如果用到我们项目中基本上都会存在以下几个问题:
传统JDBC的问题
创建数据库的连接存在大量的硬编码, 执行statement时存在硬编码. 频繁的开启和关闭数据库连接,会严重影响数据库的性能,浪费数据库的资源. 存在大量的重复性编码
针对上面这些问题,于是一大堆持久化框架应运而生。
持久化框
做持久层的框架有很多,有orm
系和utils
系列。
-
## Representatives of theorm
series include:hibernate
,eclipseLink
,topLink
; -
#utils series include:
MyBatis,
dbUtils,
jdbcTemplate, etc.;
In fact, you can support MyBatis and spring-data-jpa at the same time in one project. For complex SQL, use mybatis, and for common SQL, use spring-data-jpa.In view of the number of uses in actual development, we selected
MyBatis for analysis.
mybatis
Friends who are new to development may not know the predecessor of MyBatis. Before 2010, I will not pay MyBatis
, called ibatis
.
MyBatis
is an excellent persistence layer framework that supports customized SQL, stored procedures and advanced mapping. MyBatis avoids almost all JDBC code and manual setting of parameters and retrieval of result sets. MyBatis
You can use simple XML or annotations to configure and map native information, mapping interfaces and Java's POJOs
(Plain Ordinary Java Object, ordinary Java objects) into records in the database .
特点
简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。 灵活:MyBatis 不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。 提供映射标签,支持对象与数据库的orm字段关系映射 提供对象关系映射标签,支持对象关系组建维护 提供xml标签,支持编写动态sql。
案例
需要来源两个jar包:MyBatis
的jar包和MySQL
数据库连接jar包。
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency>
创建一个表t_user(数据库也是肯定要自己创建的哈)
CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
插入一条数据:
INSERT INTO `t_user` VALUES ('1', 'tian', '19', '1');
创建该数据库表的实体类:
public class User { private Integer id; private String name; private Integer age; //set get }
创建mapper配置文件:UserMapper.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.tian.mapper.UserMapper"> <select id="selectUserById" resultType="com.tian.domain.User"> select * from t_user where id = #{id} </select> </mapper>
创建mapper接口:UserMapper.java
import com.tian.domain.User; public interface UserMapper { User selectUserById(Integer id); }
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"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mblog?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mappers/UserMapper.xml"/> </mappers> </configuration>
上面这些就是我们使用MyBatis
基本开发代码。
下面我们来写一个测试类:
import com.tian.domain.User; import com.tian.mapper.UserMapper; 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 java.io.IOException; import java.io.InputStream; public class MybatisApplication { public static void main(String[] args) { String resource = "mybatis-config.xml"; InputStream inputStream = null; SqlSession sqlSession =null; try { //读取配置文件 inputStream = Resources.getResourceAsStream(resource); //创建SqlSession工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //创建sql操作会话 sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper=sqlSession.getMapper(UserMapper.class); //获取数据并解析成User对象 User user = userMapper.selectUserById(1); //输出 System.out.println(user); } catch (Exception e) { e.printStackTrace(); }finally { //关闭相关资源 try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } sqlSession.close(); } } }
测试结果:
User{id=1, name='tian', age=19}
如上面的代码所示,SqlSession
是MyBatis中提供的与数据库交互的接口,SqlSession实例通过工厂模式创建。
为了创建SqlSession
对象,首先需要创建SqlSessionFactory
对象,而SqlSessionFactory
对象的创建依赖于SqlSessionFactoryBuilder
类,该类提供了一系列重载的build()方法,我们需要以主配置文件的输入流作为参数调用SqlSessionFactoryBuilder
对象的bulid()
方法,该方法返回一个SqlSessionFactory
对象。
After you have the SqlSessionFactory
object, call the SqlSessionFactory
object's openSession()
method to obtain a SqlSession## that establishes a connection with the database. #Instance.
UserMapper interface earlier. Here we need to call the
getMapper() method of
SqlSession to create a dynamic proxy object, and then call
UserMapperThe method of proxy instance can complete the interaction with the database.
MyBatis.
Configuration
is used to describe the main configuration information of MyBatis
, others When a component needs to obtain configuration information, it can be obtained directly through the Configuration
object. In addition, MyBatis registers Mapper configuration information, type aliases, TypeHandler
, etc. into the Configuration
component when the application starts. When other components need this information, they can also download it from Configuration
Obtained from the object.
MappedStatement
MappedStatement is used to describe the SQL configuration information in Mapper, which is a reference to the Mapper XML
configuration file# An encapsulation of configuration information with tags such as ##
SqlSession is the user-oriented API provided by MyBatis, which represents the session object when interacting with the database. Used to complete the addition, deletion, modification and query functions of the database.
SqlSession is the appearance of the Executor component, which aims to provide an easy-to-understand and use database operation interface to the outside world.
Executor
Executor
is the SQL executor of MyBatis. All add, delete, modify and query operations on the database in MyBatis are performed by Executor The component is completed.
StatementHandler
StatementHandler
encapsulates operations on JDBC Statement
objects, such as Statement The object sets parameters, calls the methods provided by the Statement interface to interact with the database, and so on.
ParameterHandler
When the Statement type used by the MyBatis
framework is CallableStatement
and When PreparedStatement
is used, ParameterHandler
is used to set values for Statement object parameter placeholders.
ResultSetHandler
ResultSetHandler
encapsulates the operation of the ResultSet object in JDBC, when executing the SQL type SELECT statement , ResultSetHandler is used to convert query results into Java objects.
TypeHandler
TypeHandler
is the type processor in MyBatis, used to handle the mapping between Java types and JDBC types. Its function is mainly reflected in the ability to call the PreparedStatement
or CallableStatement
method corresponding to the setXXX()
object according to the Java type, and can set the value for the Statement object according to the Java type Call getXXX()
corresponding to the ResultSet object to obtain the SQL execution result.
Using JDBC API
to develop applications, one of the more cumbersome aspects is processing the conversion between JDBC types and Java types. The two situations involving Java type and JDBC type conversion are as follows:
PreparedStatement
When the object sets the value for the parameter placeholder, it needs to call a series ofsetXXX()## provided in the
PreparedStatementinterface #Method, convert Java types to corresponding JDBC types and assign values to parameter placeholders.
- After executing the SQL statement to obtain the
ResultSet object, you need to call the
getXXX()method of the ResultSet object to obtain the field value. At this time, the JDBC Type conversion to Java type.
MyBatis provides
TypeHandler and the corresponding relationship between Java types and JDBC types:
We use the
SqlSession component, which is a user-level API. In fact,
SqlSession is the appearance of the Executor component, which aims to provide users with a more friendly database operation interface. This is a typical application of the appearance pattern in the design pattern.
StatementHandler component to operate the JDBC Statement object.
When the Statement type is CallableStatement
and PreparedStatement
, the parameter placeholder will be assigned a value through the ParameterHandler component. ParameterHandler
The component will find the corresponding TypeHandler
object based on the Java type. The TypeHandler will use the setXXX()
method provided by the Statement
object ( For example, the setString() method) sets the value for the parameter placeholder in the Statement object.
StatementHandler
After the component uses the Statement object in JDBC to complete the interaction with the database, when the SQL statement type is SELECT, MyBatis obtains the ResultSet from the Statement object through the ResultSetHandler
component. object and then convert the ResultSet object to a Java object.
Advanced Skills
Design patterns are widely used in MyBatis. In MyBatis we can learn several design patterns:
Factory pattern Template method pattern Agent pattern Builder pattern Singleton pattern Adaptation pattern Decorator pattern Chain of responsibility model ....
Cache
In web applications, caching is an essential component. Usually we use caching middleware such as Redis or memcached to intercept a large number of requests to the database and reduce the pressure on the database. As an important component, MyBatis naturally also provides corresponding support internally. By adding caching functions at the framework level, the pressure on the database can be reduced and the query speed can be improved at the same time. It can be said that it kills two birds with one stone.
MyBatis cache structure consists of level one cache
and second level cache
. Both levels of cache are implementation classes using the Cache interface. Therefore, in the following chapters, I will first introduce you to the source code of several Cache implementation classes, and then analyze the implementation of first-level and second-level cache.
The use of MyBatis first-level cache and second-level cache: MyBatis first-level cache is a SqlSession-level cache. It is enabled by default and cannot be turned off; the second-level cache needs to be set in the MyBatis main configuration file by setting the cacheEnabled parameter. value to enable.
The first level cache is implemented in Executor. MyBatis's Executor component has three different implementations, namely SimpleExecutor
, ReuseExecutor
and BatchExecutor
. These classes all inherit from BaseExecutor
. In the query() method of the BaseExecutor class, the query results are first obtained from the cache. If not, the results are retrieved from the database, and then the query results are cached. The second-level cache of MyBatis is implemented through the decorator mode. When the second-level cache is enabled through the cacheEnabled parameter, the MyBatis framework will use CachingExecutor to SimpleExecutor
, ReuseExecutor
or BatchExecutor
is decorated. When a query operation is performed, the query results are cached, and when an update operation is performed, the secondary cache is updated. This chapter finally introduces how MyBatis
integrates Redis as a secondary cache.
In addition, MyBatis also supports Ehcache
, OSCache
, etc. This feature is not commonly used.
Plug-ins
Most frameworks support plug-ins. Users can extend their functions by writing plug-ins, and Mybatis is no exception.
MyBatis provides an extension mechanism that can change the execution behavior of SQL when executing Mapper. This extension mechanism is implemented through interceptors, and user-defined interceptors are also called MyBatis plug-ins.
MyBatis framework supports interception of the methods of four components: Executor
, ParameterHandler
, ResultSetHandler
, StatementHandler
. Master the implementation principle of the MyBatis plug-in, and then implement a paging query plug-in and a slow SQL statistics plug-in. When the functions we need cannot be satisfied by the MyBatis framework, we can consider implementing them through custom plug-ins.
Classic implementation: PageHelper.
Log
MyBatis provides corresponding implementations of the Log interface for different logging frameworks. The implementation class of the Log interface is shown in the figure below Show. As can be seen from the implementation class, MyBatis supports 7 different log implementations, as detailed below.
The following is a brief explanation of the commonly used ones:
Apache Commons Logging: Using JCL Output log. Log4j 2: Use Log4j 2 framework to input logs. Java Util Logging: Use the JDK's built-in log module to output logs. Log4j: Use the Log4j framework to output logs. No Logging: No logs are output. SLF4J: Use the SLF4J log facade to output logs. Stdout: Output logs to the standard output device (such as the console).
The order in which MyBatis searches for log frames is
SLF4J→JCL→Log4j2→Log4j→JUL→No Logging.
If there is no logging framework under the Classpath, use the NoLoggingImpl log implementation class, that is, no logs will be output.
Dynamic SQL Binding
Dynamic SQL refers to the specific conditions that cannot be predicted in advance and need to be dynamically generated according to the specific situation at runtime. Generate SQL statements.
There are a wealth of dynamic SQL tags in MyBatis, such as: <where></where>
, <if></if>
, <choose>, <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: " operator mono consolas monaco menlo monospace break-all rgb><foreach></foreach>
, etc.
There is a SqlSource object in the MyBatis source code that will be saved in the MappedStatement object as a property of the MappedStatement object. When Mapper is executed, the getBoundSql() method of the SqlSource object is called based on the incoming parameter information to obtain the BoundSql object. This process completes the process of converting the SqlNode object into a SQL statement.
For example:, #{}
The placeholder will be replaced with "?", and then the setXXX() method of the PreparedStatement object in JDBC is called to set the value for the parameter placeholder, and $ The {} placeholder will be directly replaced with the passed parameter text content.
Summary
This article is the overall experience of MyBatis source code analysis. I hope it will be of some help to you.
The above is the detailed content of After learning the MyBatis source code in one week, I got a 10,000-word summary. For more information, please follow other related articles on the PHP Chinese website!

缓存的概述和分类概述缓存就是一块内存空间.保存临时数据为什么使用缓存将数据源(数据库或者文件)中的数据读取出来存放到缓存中,再次获取的时候,直接从缓存中获取,可以减少和数据库交互的次数,这样可以提升程序的性能!缓存的适用情况适用于缓存的:经常查询但不经常修改的(eg:省市,类别数据),数据的正确与否对最终结果影响不大的不适用缓存的:经常改变的数据,敏感数据(例如:股市的牌价,银行的汇率,银行卡里面的钱)等等MyBatis缓存类别一级缓存:它是sqlSession对象的缓存,自带的(不需要配置)不

MyBatis允许使用插件来拦截的方法Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)ParameterHandler(getParameterObject,setParameters)ResultSetHandler(handleResultSets,handleOutputParameters)StatementHandler(prepare,parameterize,ba

mybatis分页的方式:1、借助数组进行分页,首先查询出全部数据,然后再list中截取需要的部分。2、借助Sql语句进行分页,在sql语句后面添加limit分页语句即可。3、利用拦截器分页,通过拦截器给sql语句末尾加上limit语句来分页查询。4、利用RowBounds实现分页,需要一次获取所有符合条件的数据,然后在内存中对大数据进行操作即可实现分页效果。

背景实际开发过程中经常需要查询节点树,根据指定节点获取子节点列表,以下记录了获取节点树的操作,以备不时之需。使用场景可以用于系统部门组织机构、商品分类、城市关系等带有层级关系的数据结构;设计思路递归模型即根节点、枝干节点、叶子节点,数据模型如下:idcodenameparent_code110000电脑0220000手机0310001联想笔记本10000410002惠普笔记本1000051000101联想拯救者1000161000102联想小新系列10001实现代码表结构CREATETABLE`

当某些sql因为不知名原因堵塞时,为了不影响后台服务运行,想要给sql增加执行时间限制,超时后就抛异常,保证后台线程不会因为sql堵塞而堵塞。一、yml全局配置单数据源可以,多数据源时会失效二、java配置类配置成功抛出超时异常。importcom.alibaba.druid.pool.DruidDataSource;importcom.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;importorg.apache.

简介今天开发时想将自己写好的代码拿来优化,因为不想在开发服弄,怕搞坏了到时候GIT到生产服一大堆问题,然后把它分离到我轮子(工具)项目上,最后运行后发现我获取List的时候很卡至少10秒,我惊了平时也就我的正常版本是800ms左右(不要看它很久,因为数据量很大,也很正常。),前提是我也知道很慢,就等的确需要优化时,我在放出我优化的plus版本,回到10秒哪里,最开始我刚刚接到这个app项目时,在我用PageHelper.startPage(page,num);(分页),还没等查到的数据封装(Pa

一、什么是缓存缓存是内存当中一块存储数据的区域,目的是提高查询效率。MyBatis会将查询结果存储在缓存当中,当下次执行相同的SQL时不访问数据库,而是直接从缓存中获取结果,从而减少服务器的压力。什么是缓存?存在于内存中的一块数据。缓存有什么作用?减少程序和数据库的交互,提高查询效率,降低服务器和数据库的压力。什么样的数据使用缓存?经常查询但不常改变的,改变后对结果影响不大的数据。MyBatis缓存分为哪几类?一级缓存和二级缓存如何判断两次Sql是相同的?查询的Sql语句相同传递的参数值相同对结

一、思路将分页所需的内容都放到一个实体类中分页数据所需要的实体类!内包含页码,页大小,总条数,总页数,起始行pagehelpr提供了这个类pageInfo,不需要我们自己创建二、主要逻辑select*from表名limit起始行,展示几条数据#第n页每页展示五条数据select*from表名limit(n-1)*5,5#每页展示多少条pageSize3#总共有多少条totalselectcount(*)from表名#总页数pagespages=total%pagesSize==0?total/p


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Linux new version
SublimeText3 Linux latest version

Notepad++7.3.1
Easy-to-use and free code editor

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

Dreamweaver CS6
Visual web development tools
