MyBatis源码分析-SQL语句执行的完整流程(1)

合集下载

sql语句执行流程

sql语句执行流程

sql语句执行流程SQL语句执行流程SQL是结构化查询语言的缩写,它是一种用于管理关系型数据库的语言。

在数据库中,SQL语句被用来创建、更新、删除和查询数据。

下面将详细介绍SQL语句执行的流程。

1. 解析阶段当用户输入SQL语句时,首先需要对其进行解析。

解析器会检查语法和拼写错误,并将SQL语句转换为计算机可以理解的格式。

在这个阶段,还会确定要执行的操作类型(如SELECT、INSERT、UPDATE或DELETE)以及要操作的表名和列名。

2. 编译阶段在编译阶段,数据库管理系统(DBMS)会将解析后的SQL语句转换为可执行代码。

这个代码通常称为查询计划或执行计划。

查询计划包含了一系列操作指令,用于读取和修改数据。

3. 优化阶段在优化阶段,DBMS会尝试找到最有效的查询计划。

它会考虑许多因素,如表大小、索引数量和可用内存等。

优化器还可以使用统计信息来估算每个可能的执行计划所需的时间和资源。

4. 执行阶段在执行阶段,DBMS会按照查询计划中指定的顺序读取数据并进行处理。

如果需要,在此期间还可以对数据进行排序、过滤和聚合等操作。

执行阶段还可以包括锁定和事务管理等步骤,以确保数据的一致性和安全性。

5. 返回结果最后,DBMS会将处理后的结果返回给用户。

如果是SELECT语句,结果将是一个数据集,包含满足查询条件的所有行。

如果是INSERT、UPDATE或DELETE语句,则返回受影响的行数。

总结SQL语句执行流程包括解析、编译、优化、执行和返回结果五个阶段。

在每个阶段,DBMS都会进行不同的操作以确保SQL语句能够正确地执行并返回正确的结果。

了解SQL语句执行流程对于优化查询性能和调试错误非常重要。

mybatis工作原理流程

mybatis工作原理流程

mybatis工作原理流程
MyBatis是一种基于Java的持久化框架,它通过XML或注解的
方式将Java对象映射到数据库中的数据。

MyBatis的工作原理可以简单地概括为以下流程:
1. 配置文件加载
MyBatis的配置文件包含数据源配置、映射文件配置、缓存配置等内容,它通过解析配置文件来获取相关配置信息。

2. SqlSessionFactory创建
SqlSessionFactory是MyBatis的核心接口,它负责创建SqlSession对象,SqlSession对象是与数据库交互的主要接口。

3. SqlSession创建
SqlSession是MyBatis与数据库交互的主要接口,它提供了各
种操作数据库的方法,如插入、更新、删除和查询等。

4. Mapper接口调用
Mapper接口是MyBatis中定义操作数据库的接口,它通过动态
代理方式生成接口的实现类,并调用相应的SQL语句完成数据库操作。

5. SQL语句执行
MyBatis通过动态生成SQL语句,将Java对象与数据库中的数
据进行映射。

在执行SQL语句前,MyBatis会将SQL语句进行预编译,提高SQL语句的执行效率。

6. 数据库操作结果返回
MyBatis通过执行SQL语句,将数据库操作结果返回给Java程
序,Java程序可以根据返回结果进行相应的处理。

以上就是MyBatis的工作原理流程,通过理解MyBatis的工作原理,我们可以更好地使用MyBatis框架进行Java开发。

MyBatis运行动态sql及存储过程

MyBatis运行动态sql及存储过程

MyBatis运⾏动态sql及存储过程1 利⽤MyBatis进⾏模糊查询在利⽤MyBatis进⾏模糊查询时候。

须要⽤到concat,注意在Oracle中concat连接的是两个參数。

不是三个參数。

持久化类:package com.web.entity;public class Student {private Integer studentId;private String studentName;private Classes classes;public Integer getStudentId() {return studentId;}public void setStudentId(Integer studentId) {this.studentId = studentId;}public String getStudentName() {return studentName;}public void setStudentName(String studentName) {this.studentName = studentName;}public Classes getClasses() {return classes;}public void setClasses(Classes classes) {this.classes = classes;}}dao中⽅法:package com.web.dao;import java.io.InputStream;import java.util.HashMap;import java.util.Map;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 com.web.entity.Student;public class StudentDao {private int res=-1;private SqlSession sqlSession=null;public SqlSession getSqlSession(){try{String resource="mybatis-config.xml";InputStream is=Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);sqlSession=sqlSessionFactory.openSession(true);}catch(Exception e){System.out.println("出错");e.printStackTrace();}return sqlSession;}public Student findTStudentByName(Student student){sqlSession=getSqlSession();Student s=sqlSession.selectOne("lk", student);return s;}/*public int getCount(Integer classesid){int result=-1;Map<String, Integer> map=new HashMap<String, Integer>();map.put("classesid", classesid);map.put("studentcount", -1);sqlSession=getSqlSession();sqlSession.selectOne("gc", map);result=map.get("studentcount");return result;}*/}映射⽂件:<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.pb.dao.StudentDao"><!-- <resultMap type="Student" id="ts"><id property="studentId" column="studentId" /><result property="studentName" column="studentName" /><association property="classes" column="classesId"javaType="Classes"><id property="classesId" column="classesId" /><result property="classesName" column="classesName" /></association></resultMap><select id="selectonetoone" resultMap="ts" parameterType="Student">selects.studentid,s.studentname,c.classesnamefromstudent sleft join classes con s.classesid=c.classesidwhere s.studentid=#{studentId}</select> --><select id="lk" resultMap="ts" parameterType="Student">select * from student s where s.studentname like concat(concat('%','h'),'%')</select><!-- <select id="gc" parameterMap="gm" statementType="CALLABLE">call pro_student(?,?)</select><parameterMap type="java.util.Map" id="gm"><parameter property="classesid" mode="IN" jdbcType="INTEGER"/><parameter property="studentcount" mode="OUT" jdbcType="INTEGER"/></parameterMap> --></mapper>2 利⽤MyBatis运⾏存储过程:在映射⽂件⾥定义⼀个parameterMap作为參数,设置statementType="CALLABLE",过程的參数放置?站位符。

MyBatis执行动态SQL语句详解

MyBatis执行动态SQL语句详解

MyBatis执⾏动态SQL语句详解⼤家基本上都知道如何使⽤ MyBatis 执⾏任意 SQL,使⽤⽅法很简单,例如在⼀个 XXMapper.xml 中:<select id="executeSql" resultType="map">${_parameter}</select>你可以如下调⽤:sqlSession.selectList("executeSql", "select * from sysuser where enabled = 1");或者你可以在 XXMapper.java 接⼝中定义如下⽅法:List<Map> executeSql(String sql);然后使⽤接⼝调⽤⽅法:xxMapper.executeSql("select * from sysuser where enabled = 1");上⾯这些内容可能都会,下⾯在此基础上再复杂⼀点。

假如像上⾯SQL中的enabled = 1我想使⽤参数⽅式传值,也就是写成 enabled = #{enabled},如果你没有遇到过类似这种需求,可能不明⽩为什么要这么写,举个例⼦,要实现⼀种动态查询,可以在前台通过配置 SQL,提供⼀些查询条件就能实现⼀个查询的功能(为了安全,这些配置肯定是开发或者实施做的,不可能让⽤户直接操作数据库)。

针对这个功能,使⽤ MyBatis 实现起来相当容易。

配置 SQL 肯定要执⾏,⽤上⾯讲的这种⽅式肯定可以执⾏ SQL,如何提供参数呢?参数就是enabled = #{enabled}中的#{enabled}部分。

如果再多⼀些条件,⼀个配置好的 SQL 如下:select * from sysuserwhere enabled = #{enabled}and userName like concat('%',#{userName},'%')这种情况下,该怎么⽤ MyBatis 实现呢?⾸先 XML 中修改如下:<select id="executeSql" resultType="map">${sql}</select>接⼝中的⽅法修改为:List<Map> executeSql(Map map);然后调⽤⽅法:Map map = new HashMap();//这⾥的 sql 对应 XML 中的 ${sql}map.put("sql", "select * from sysuser "+ " where enabled = #{enabled} "+ " and userName like concat('%',#{userName},'%')");//#{enabled}map.put("enabled", 1);//#{userName}map.put("userName", "admin");//接⼝⽅式调⽤List<Map> list = xxMapper.executeSql(map);//sqlSession⽅式调⽤sqlSession.selectList("executeSql", map);有了这个SQL之后,就可以将 enabled 和 userName 作为条件提供给⽤户。

Mybatis中的动态SQL语句解析

Mybatis中的动态SQL语句解析

Mybatis中的动态SQL语句解析这篇⽂章主要介绍了Mybatis中的动态SQL语句解析,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下 Mybatis中配置SQL有两种⽅式,⼀种是利⽤xml ⽅式进⾏配置,⼀种是利⽤注解进⾏配置。

Mybatis使⽤注解配置SQL,但是由于配置功能受限,⽽且对于复杂的SQL⽽⾔可读性很差,所以很少使⽤。

Mybatis常⽤xml配置的⽅式,使⽤xml的⼏个简单的元素,便能完成动态SQL的功能,⼤量的判断都可以在mybaties的映射xml⾥⾯配置,以达到许多需要⼤量代码才能实现的功能,⼤⼤减少了代码量,体现了Mybatis的灵活、⾼度可配置性和维护性。

元素作⽤备注if判断语句单条件分⽀判断choose(when,otherwise)相当于Java中的switch和case语句多条件分⽀判断trim辅助元素,⽤于处理特定的SQL拼装问题⽤于处理SQL拼装的问题foreach循环语句在in语句等列表条件常⽤if元素 if元素是最常⽤的判断语句,相当于Java中国的 if 语句,它常常与test属性联合使⽤。

<select id="findRole1" parameterType="string" resultMap="roleResultMap">select role_no, role_name, note from t_role where 1=1<if test="roleName != null and roleName !=''">and role_name like concat('%', #{roleName}, '%')</if></select> 当参数roleName传递进映射器时,如果参数不为空,则采取构造对 roleName 的模糊查询,否则就不要去构造这个条件。

mysql 中的 sql执行流程

mysql 中的 sql执行流程

mysql 中的 sql执行流程Mysql 中的 SQL 执行流程概述•MySQL 是一款广泛使用的开源关系型数据库管理系统,它使用SQL 语言进行数据管理和操作。

•SQL 执行流程是指 MySQL 在执行 SQL 语句时的内部运行过程,包括解析 SQL 语句、优化执行计划、执行计划等多个步骤。

SQL 执行流程步骤1.解析 SQL 语句–MySQL 首先会对输入的 SQL 语句进行解析,判断语法的正确性和合法性。

–解析过程包括词法分析和语法分析,将 SQL 语句转换成抽象语法树(AST)表示。

2.语义分析–在语义分析阶段,MySQL 对解析得到的抽象语法树进行分析,并验证 SQL 语句是否符合语义规则。

–语义分析会检查表名、列名的存在性、权限等,并进行相应的错误提示或警告。

3.优化执行计划–在优化执行计划阶段,MySQL 会根据 SQL 语句的查询需求和数据库的特点,生成多个执行计划。

–MySQL 内部会使用优化器选择出最优的执行计划,以提高查询效率。

–优化过程包括索引选择、连接顺序优化、子查询优化等。

4.执行计划–在执行计划阶段,MySQL 会根据最优的执行计划,按照特定的流程执行 SQL 语句。

–MySQL 会使用存储引擎的接口,读取和写入数据。

存储引擎的作用•存储引擎是 MySQL 中负责底层数据存储和管理的模块,不同的存储引擎有不同的特点和适用场景。

•MySQL 支持多种存储引擎,如 InnoDB、MyISAM、Memory 等。

InnoDB 存储引擎•InnoDB 是 MySQL 中最常用和性能较好的存储引擎。

•InnoDB 支持事务和行级锁,具有高并发性和数据一致性。

MyISAM 存储引擎•MyISAM 是 MySQL 的另一个常用的存储引擎。

•MyISAM 不支持事务,但在读写比较均衡的场景下,有较好的性能。

Memory 存储引擎•Memory 存储引擎将数据存储在内存中,适用于一些读写频繁但数据不需要长期存储的场景。

MyBatis原理与执行流程

MyBatis原理与执行流程

MyBatis原理与执⾏流程⾸先感谢尚硅⾕的⽼师讲解!Mybatis流程分四步:1. 返回创建SqlSessionFactory对象2. 返回SqlSession的实现类DefaultSqlSession对象3. 返回⼀个MapperProxy的代理对象4. 执⾏询流程。

第⼀步返回创建SqlSessionFactory对象SqlSessionFactoryBuilder().build(inputStream);如何得到配置⽂件的内容?创建解析器解析全局配置⽂件XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);得到全局配置⽂件的配置内容 , 解析每⼀个标签把详细信息保存在Configuration中//解析配置⽂件标签build(parser.parse());propertiesElement(root.evalNode("properties"));Properties settings = settingsAsProperties(root.evalNode("settings"));loadCustomVfs(settings);typeAliasesElement(root.evalNode("typeAliases"));pluginElement(root.evalNode("plugins"));objectFactoryElement(root.evalNode("objectFactory"));全局配置⽂件中有该属性可以解析mapper.xml⽂件也保存到Configuration中mappers><package name="dao"/></mappers>Mapper.xml中的每个元素解析出来保存到全局配置中将增删改查标签的每⼀个标签每⼀个属性也解析出来封装到⼀个MapperedStatement中⼀个MapperedStatement就代表⼀个增删改查标签的详细信息最后 return configuration;包括全局配置信息和mapper.xml映射⽂件的各种信息返回的configuration通过buildreturn new DefaultSqlSessionFactory(config);configuration中mapperRegistry属性保存的是代理类信息mappedStatement属性保存的是增删查改等标签内容总结:配置⽂件的信息解析保存到Configureation对象中返回包含Configureation的DefaultSqlSessionFactory第⼆步返回SqlSession的实现类DefaultSqlSession对象他⾥⾯包含了Executor(是⽤来增删改查的)和Configuration。

1条sql执行的完整过程

1条sql执行的完整过程

1条sql执行的完整过程当一条SQL语句被提交给数据库执行时,它需要经过多个步骤才能完成。

以下是SQL语句执行的完整过程:1. **解析(Parsing)**:* 查询首先被解析器解析。

解析器检查SQL语句的语法和结构,并创建一个解析树。

* 语法错误在这个阶段会被检测出来。

2. **预处理(Preprocessing)**:* 在预处理器中,解析器检查是否有任何语法错误,并确保所有的对象(如表和视图)都存在并且可以访问。

* 预处理器还会处理一些简单的查询重写,例如处理别名和子查询。

3. **优化(Optimization)**:* 在这个阶段,查询优化器会生成多个可能的执行计划,并选择一个最优的计划来执行查询。

* 优化器会考虑多种因素,如表的大小、索引的存在与否、数据的分布等,来决定最佳的执行策略。

4. **生成执行计划(Plan Generation)**:* 一旦选择了最优的执行计划,就会生成一个或多个执行计划。

这些计划描述了数据库如何实际执行查询。

5. **执行(Execution)**:* 在这个阶段,数据库引擎根据执行计划执行查询。

这可能涉及到读取数据、连接表、过滤记录等操作。

6. **返回结果(Result Returning)**:* 最后,查询的结果被返回给客户端。

这可能是一个表、一行数据、一个状态码等,具体取决于查询的类型和需求。

7. **后处理(Postprocessing)**:* 在某些情况下,可能还需要进行一些后处理步骤,例如处理事务或清理资源。

注意:不同的数据库系统可能会有不同的执行步骤或略有不同的执行顺序。

上述过程是一个通用的概述。

SQL执行过程范文

SQL执行过程范文

SQL执行过程范文SQL(Structured Query Language)是一种用于管理关系型数据库的语言。

当我们在数据库中执行SQL语句时,数据库管理系统(DBMS)会按照一定的步骤来处理和执行这些SQL语句。

下面是一个SQL执行的一般流程,以及涉及的步骤和过程,详细说明了SQL执行的过程。

1.SQL语句分析在执行SQL语句之前,DBMS首先对SQL语句进行分析。

这个过程包括词法分析和语法分析。

在词法分析阶段,DBMS将SQL语句分解为多个单词(即标记),如SELECT、FROM、WHERE等。

在语法分析阶段,DBMS 将这些标记按照SQL语法规则进行组合和解析,确定语句的结构和含义。

2.查询优化一旦SQL语句被分析后,DBMS会对查询进行优化。

查询优化是一个关键的步骤,它的目标是通过选择最佳的执行路径,以提高查询的性能。

查询优化的过程包括以下几个步骤:a.查询重写:DBMS可能会重写查询,以便更高效地执行。

例如,将一个复杂的查询分解为多个简单的查询。

b.查询转换:DBMS可以将查询转换为更高效的形式。

例如,将子查询转换为连接操作。

c.索引选择:DBMS会选择合适的索引来加速查询的执行。

它会考虑索引的选择性、大小和可用性等因素。

d.表连接顺序:如果查询涉及到多个表的连接,DBMS会决定连接的顺序,以最小化查询的成本。

e.统计信息使用:DBMS使用表的统计信息来估计查询成本,以便选择最佳的执行计划。

3.执行计划生成一旦查询优化完成,DBMS会根据优化后的查询生成一个执行计划。

执行计划是一个描述查询执行方式的计划,它定义了DBMS执行查询时需要采取的操作和顺序。

执行计划可以是一棵查询执行树,也可以是一组查询执行操作。

执行计划被存储在数据库的缓冲区中,以便DBMS在执行查询时能够快速获取。

4.数据获取在执行查询之前,DBMS需要获取查询所需的数据。

这包括从磁盘读取表的数据和索引到内存中,以便后续的查询操作。

MyBatis源码解析----MyBatis动态SQL底层原理分析

MyBatis源码解析----MyBatis动态SQL底层原理分析

MyBatis源码解析----MyBatis动态SQL底层原理分析前⾔废话不多说,直接进⼊⽂章。

我们在使⽤mybatis的时候,会在xml中编写sql语句。

⽐如这段动态sql代码:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<update id="update"parameterType="er"> UPDATE users<trim prefix="SET"prefixOverrides=","><if test="name != null and name != ''">name = #{name}</if><if test="age != null and age != ''">, age = #{age}</if><if test="birthday != null and birthday != ''">, birthday = #{birthday}</if></trim>where id = ${id}</update>mybatis底层是如何构造这段sql的?这⽅⾯的知识⽹上资料不多,于是就写了这么⼀篇⽂章。

下⾯带着这个疑问,我们⼀步⼀步分析。

介绍MyBatis中⼀些关于动态SQL的接⼝和类SqlNode接⼝,简单理解就是xml中的每个标签,⽐如上述sql的update,trim,if标签:1 2 3public interface SqlNode {boolean apply(DynamicContext context); }SqlSource Sql源接⼝,代表从xml⽂件或注解映射的sql内容,主要就是⽤于创建BoundSql,有实现类DynamicSqlSource(动态Sql 源),StaticSqlSource(静态Sql源)等:1 2 3public interface SqlSource {BoundSql getBoundSql(Object parameterObject); }BoundSql类,封装mybatis最终产⽣sql的类,包括sql语句,参数,参数源数据等参数:XNode,⼀个Dom API中的Node接⼝的扩展类。

mybatis动态sql语法

mybatis动态sql语法

mybatis动态sql语法在使用MyBatis进行数据库操作时,使用动态SQL可以有效地处理不同查询条件下的不同SQL语句。

MyBatis提供了一套灵活的动态SQL语法,使得我们能够根据需要动态生成SQL语句,以满足各种查询需求。

本文将详细介绍MyBatis动态SQL语法的使用。

一、if语句if语句是MyBatis中最常用的动态SQL语法之一。

通过if语句,我们可以根据条件判断来生成不同的SQL片段。

示例代码如下:```<select id="getUserList" resultType="User">SELECT *FROM userWHERE 1 = 1<if test="username != null and username != ''">AND username = #{username}</if><if test="age != null">AND age = #{age}</if></select>```在上述代码中,我们使用了if语句来生成动态的WHERE子句。

首先,我们判断username字段是否为空,如果不为空,则将其加入WHERE子句;然后,我们判断age字段是否为空,如果不为空,则同样将其加入WHERE子句。

通过这种方式,我们可以根据不同的查询条件动态生成不同的SQL语句。

二、choose语句choose语句也是常用的动态SQL语法之一。

它类似于Java中的switch语句,根据条件判断来选择执行不同的分支。

示例代码如下:```<select id="getUserList" resultType="User">SELECT *FROM user<where><choose><when test="username != null and username != ''">AND username = #{username}</when><when test="age != null">AND age = #{age}</when><otherwise>AND status = 1</otherwise></choose></where></select>```在上述代码中,我们使用choose语句来生成动态的WHERE子句。

mybatisd 的 sqlsession 详解 -回复

mybatisd 的 sqlsession 详解 -回复

mybatisd 的sqlsession 详解-回复MyBatis是Java中一个流行的ORM(对象关系映射)框架,可以通过简化数据库操作和提供强大的SQL映射功能来提高开发人员的效率。

SQLSession是MyBatis中最重要的组件之一,它作为一个会话层,提供了执行SQL语句和管理事务的方法。

本文将详细介绍MyBatis的SQLSession,并按照以下步骤一步一步回答中括号内的内容。

第一步:创建SqlSessionFactory在使用MyBatis之前,我们需要创建一个SqlSessionFactory实例。

SqlSessionFactory是MyBatis的核心接口,它负责创建和管理SqlSession对象。

我们可以通过SqlSessionFactoryBuilder将配置文件(mybatis-config.xml)加载到类路径中,并根据配置文件创建SqlSessionFactory对象。

第二步:打开SqlSession在获得了SqlSessionFactory之后,我们可以通过SqlSessionFactory的openSession方法来打开一个新的SqlSession。

SqlSession是一个线程不安全的对象,因此每个线程都应该有自己的SqlSession实例。

SqlSession提供了很多与数据库交互的方法,包括执行SQL语句、插入、更新和删除数据等。

第三步:执行SQL语句通过SqlSession对象,我们可以执行各种类型的SQL语句,包括查询、插入、更新和删除。

SqlSession提供了selectOne、selectList、insert、update和delete等方法来执行对应的SQL语句。

我们可以通过传递SQL 语句的ID和参数来调用这些方法。

第四步:获取映射器(Mapper)MyBatis提供了一种将SQL语句与Java方法绑定的功能,被称为Mapper。

Mapper可以看作一个定义了SQL语句映射关系的类,它通常包含了一系列的方法,每个方法都对应一个SQL语句。

mybatis 执行原生sql的方法-概述说明以及解释

mybatis 执行原生sql的方法-概述说明以及解释

mybatis 执行原生sql的方法-概述说明以及解释1.引言1.1 概述MyBatis作为一款流行的Java持久化框架,提供了方便且灵活的数据库操作方式。

除了提供了常规的ORM(对象关系映射)功能外,MyBatis 也支持执行原生SQL语句。

执行原生SQL语句的方法为开发人员提供了更多自由发挥的空间,可以更精确地控制SQL语句的执行过程。

通过执行原生SQL语句,开发人员可以利用SQL的强大功能实现更复杂和高级的数据库操作。

与直接使用ORM方式相比,执行原生SQL 语句可以更好地满足一些特殊需求,例如复杂的联表查询、数据库特定函数的使用、原生SQL的优化等。

在MyBatis中,执行原生SQL语句的方法有多种:通过Statement 执行、通过PreparedStatement执行以及通过CallableStatement执行。

每种方法都有其适用的场景和注意事项,开发人员可以根据具体需求选择最合适的方法。

本文将详细介绍MyBatis执行原生SQL语句的方法,并探讨使用原生SQL的注意事项,希望读者通过阅读本文能够对MyBatis提供的原生SQL执行方法有更深入的了解,并能够在实际项目中正确使用和灵活应用这些方法。

文章结构部分的内容:文章的结构如下所示:1. 引言1.1 概述1.2 文章结构1.3 目的2. 正文2.1 MyBatis的基本介绍2.2 执行原生SQL的方法2.3 使用原生SQL的注意事项3. 结论3.1 总结3.2 对MyBatis执行原生SQL的方法的评价3.3 展望未来在引言部分,我们将对本文的主题进行概述,介绍MyBatis和执行原生SQL的方法的背景和重要性,并明确本文的目的。

正文部分将着重介绍MyBatis框架的基本概念和使用方法,包括MyBatis框架的起源、发展、特点以及与其他ORM框架的比较。

然后详细介绍执行原生SQL的方法,包括使用MyBatis的SQL语句和使用MyBatis的注解方式。

mybatis流程

mybatis流程

mybatis流程MyBatis是一个开源的持久层框架,它简化了Java应用程序与关系型数据库的交互过程。

它通过XML或注解的方式配置SQL映射,提供了灵活的查询和更新语句的编写方式,同时还支持对象关系映射(ORM)的功能。

MyBatis的工作流程可以分为三个主要的步骤:配置环境、编写映射文件、执行SQL语句。

首先,我们需要配置MyBatis的环境。

这包括数据源的配置,即数据库连接的信息,这些信息被保存在一个名为"mybatis-config.xml"的文件中。

在该文件中,我们需要指定数据库的连接URL、用户名、密码等信息。

同时,我们还需要配置MyBatis的一些全局参数,如自动提交事务、缓存策略等。

接下来是编写映射文件。

映射文件是将Java类与数据库表进行映射的文件,其中定义了SQL语句的编写方式。

每个映射文件对应一个Java类,包含了该类与数据库表的映射关系,以及相应的SQL语句。

在映射文件中,我们可以使用SQL语句的参数和结果集的处理方式,如参数的传递方式、结果集的映射方式等。

此外,还可以使用动态SQL语句来构建复杂的查询条件。

最后,我们执行SQL语句。

通过MyBatis的API,我们可以使用映射文件中定义的SQL语句来进行数据库操作。

MyBatis 提供了多种执行SQL语句的方式,包括查询单个结果、查询列表、插入、更新、删除等。

在执行SQL语句之前,我们需要创建一个SqlSession实例,该实例负责管理数据库连接和执行SQL语句。

使用SqlSession的API,我们可以执行SQL语句并获取结果。

总结来说,MyBatis的工作流程可以简化为三个步骤:配置环境、编写映射文件、执行SQL语句。

通过这三个步骤,我们可以轻松地实现Java应用程序与关系型数据库之间的交互,提高开发效率和代码的可维护性。

以上是关于MyBatis工作流程的简单介绍。

希望能对你理解MyBatis的使用有所帮助。

mybatissql语句的写法

mybatissql语句的写法

mybatissql语句的写法MyBatis 是一种用于Java 编程语言的持久层框架,它提供了一种优雅的方式来使用SQL 语句与数据库进行交互。

以下是MyBatis SQL 语句的一般写法,包括了常见的增删改查操作:1. 查询操作(SELECT):```xml<!--根据id 查询用户--><select id="selectUserById" resultType="User">SELECT * FROM users WHERE id = #{id}</select>```在这个例子中,`selectUserById` 是一个唯一标识符,`resultType` 指定了查询结果的类型,`#{id}` 是一个占位符,表示需要动态传入的参数。

2. 插入操作(INSERT):```xml<!--插入用户--><insert id="insertUser" parameterType="User">INSERT INTO users (id, username, password) VALUES (#{id}, #{username}, #{password}) </insert>```在这个例子中,`insertUser` 是插入操作的唯一标识符,`parameterType` 指定了插入操作的参数类型,`#{id}`, `#{username}`, `#{password}` 是插入的字段值。

3. 更新操作(UPDATE):```xml<!--更新用户信息--><update id="updateUser" parameterType="User">UPDATE users SET username=#{username}, password=#{password} WHERE id=#{id} </update>```在这个例子中,`updateUser` 是更新操作的唯一标识符,`parameterType` 指定了更新操作的参数类型,`#{username}`, `#{password}`, `#{id}` 是更新的字段值。

MyBatis之SQL语句执行过程

MyBatis之SQL语句执行过程

MyBatis之SQL语句执⾏过程⼀、重温JDBCJava Database Connectivity,简称JDBC。

是Java语⾔中⽤来规范客户端程序如何来访问数据库的应⽤程序接⼝,提供了诸如查询和更新数据库中数据的⽅法。

随着Java ORM框架的发展,已经很少有机会再在⽣产系统中写JDBC的代码来访问数据库了,但是基本流程我们还是要熟悉。

下⾯以⼀个简单的查询为例,温故⼀下JDBC。

public static void main(String[] args) throws Exception {Connection conn = getConnection();String sql = "select * from user where 1=1 and id = ?";PreparedStatement stmt = conn.prepareStatement(sql);stmt.setString(1, "501440165655347200");ResultSet rs = stmt.executeQuery();while(rs.next()){String username = rs.getString("username");System.out.print("姓名: " + username);}}从上⾯的代码来看,⼀次简单的数据库查询操作,可以分为⼏个步骤。

创建Connection连接传⼊参数化查询SQL语句构建预编译对象PreparedStatement设置参数执⾏SQL从结果集中获取数据那么,Mybatis是怎样完成这⼀过程的呢?⼆、sqlSession在上⼀章节的内容中,我们已经看到了在Service层通过@Autowired注⼊的userMapper是个代理类,在执⾏⽅法的时候实际上调⽤的是代理类的invoke通知⽅法。

Mybatis执行SQL的流程

Mybatis执行SQL的流程
//getDefaultExecutorType()传递的是SimpleExecutor //第一个参数:当前默认执行器的类型 //第二个参数:数据库的隔离级别 //第三个参数:是否自动提交事务 return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }
private final Configuration configuration; private final Executor executor; //SqlSession中的两个最重要的参数,configuration与初始化时的相同,Executor为执行器 //...... } Executor : Executor也是一个接口,他有三个常用的实现类: BatchExecutor (重用语句并执行批量更新) ReuseExecutor (重用预处理语句 prepared statements) SimpleExecutor (普通的执行器,默认) 源码分析:
// 3. 生产了DefaultSqlsession实例对象 设置了事务不自动提交 完成了executor对象的创建 SqlSession sqlSession = sqlSessionFactory.openSession(); //进入openSession方法 @Override public SqlSession openSession() {
Transaction tx = null; try {
// 获得 Environment (运行环境)对象 final Environment environment = configuration.getEnvironment(); // 创建 Transaction (事务)对象 final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); // 创建 Executor 对象 final Executor executor = configuration.newExecutor(tx, execType); // 创建 DefaultSqlSession 对象 return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { // 如果发生异常,则关闭 Transaction 对象 closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } 这一步我们就完成了SqlSession对象的创建 2. List objects = sqlSession.selectList("namespace.id"); // 4.(1)根据statementid来从Configuration中map集合中获取到了指定的MappedStatement对象 //(2)将查询任务委派了executor执行器 List<Object> objects = sqlSession.selectList("namespace.id"); //DefaultSqlSession.java @Override public <E> List<E> selectList(String statement) { return this.selectList(statement, null); }

Mybatis之是如何执行你的SQL的(SQL执行过程,参数解析过程,结果集封装过程)

Mybatis之是如何执行你的SQL的(SQL执行过程,参数解析过程,结果集封装过程)

Mybatis之是如何执⾏你的SQL的(SQL执⾏过程,参数解析过程,结果集封装过程)Myabtis的SQL的执⾏是通过SqlSession。

默认的实现类是DefalutSqlSession。

通过源码可以发现,selectOne最终会调⽤selectList这个⽅法。

1 @Override2public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {3try { //获取MappedStatement 通过id 到configuration⾥⾯4 MappedStatement ms = configuration.getMappedStatement(statement);5return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);6 } catch (Exception e) {7throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);8 } finally {9 ErrorContext.instance().reset();10 }11 }通过上⾯可以发现是通过Executor去执⾏查询。

但是executor是个接⼝,是什么时候指定的⽤什么执⾏器呢。

因为SqlSession是通过SqlSessionFactory接⼝获取的,实现类是DefaultSqlSessionFactory1private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {2 Transaction tx = null;3try {4final Environment environment = configuration.getEnvironment();5final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);6 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);7final Executor executor = configuration.newExecutor(tx, execType);8return new DefaultSqlSession(configuration, executor, autoCommit);9 } catch (Exception e) {10 closeTransaction(tx); // may have fetched a connection so lets call close()11throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);12 } finally {13 ErrorContext.instance().reset();14 }15 }1public Executor newExecutor(Transaction transaction, ExecutorType executorType) {2 executorType = executorType == null ? defaultExecutorType : executorType;3 executorType = executorType == null ? ExecutorType.SIMPLE : executorType;4 Executor executor;5if (ExecutorType.BATCH == executorType) {6 executor = new BatchExecutor(this, transaction);7 } else if (ExecutorType.REUSE == executorType) {8 executor = new ReuseExecutor(this, transaction);9 } else {10 executor = new SimpleExecutor(this, transaction);11 }12if (cacheEnabled) {13 executor = new CachingExecutor(executor);14 }15 executor = (Executor) interceptorChain.pluginAll(executor);16return executor;17 }可以看到默认的是SimpleExecutor;然后默认的是开启缓存的,所以最终应该是⼀个CachingExecutor,但是CachingExecutor有⼀个构造器参数是前⾯的执⾏器。

Mybatis执行SQL的完整过程及四大组件介绍

Mybatis执行SQL的完整过程及四大组件介绍

Mybatis执⾏SQL的完整过程及四⼤组件介绍⼀切的执⾏从MapperProxy开始,MapperProxy是MapperProxyFactory使⽤SqlSession创建出来的。

所以MapperProxy中包含SqlSession。

可以看到MapperProxy调⽤invoke⽅法,进⽽调⽤MapperMethod的execute(),这些MapperMethod就是和你要执⾏的命令相关,⽐如执⾏select语句,则会通过SqlSession的select()⽅法,最终调⽤到Executor的query⽅法。

Executor会再协调另外三个核⼼组件。

MapperProxyFactory⽤来创建MapperProxy,这个factory其实主要就是完成了InvokeHandler的bindTarget的功能。

⽽MapperProxy只需要完成invoke⽅法的功能。

MapperProxy包含SqlSessionSqlSesion包含四⼤组件Executor,StatementHandler,ParameterHandler,ResultHandler。

还包含ConfigurationConfiguration可以创建四⼤组件,同时Configuration还包含InterceptorChain,通过调⽤interceptorChain的pluginAll()⽅法,完成针对四⼤组件的插件的动态代理链的创建。

MapperProxy:因为Mapper接⼝不能直接被实例化,Mybatis利⽤JDK动态代理,创建MapperProxy间接实例化Mapper对象。

MapperProxy还可以缓存MapperMethod对象MapperMethod:负责解析Mapper接⼝的⽅法,并封装成MapperMethod对象将Sql命令的执⾏路由到恰当的SqlSesison⽅法上1public class MapperMethod {23// 保存了Sql命令的类型和键id4private final SqlCommand command;5// 保存了Mapper接⼝⽅法的解析信息6private final MethodSignature method;78public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {mand = new SqlCommand(config, mapperInterface, method);10this.method = new MethodSignature(config, method);11 }1213// 根据解析结果,路由到恰当的SqlSession⽅法上14public Object execute(SqlSession sqlSession, Object[] args) {15 Object result;16if (SqlCommandType.INSERT == command.getType()) {17 Object param = method.convertArgsToSqlCommandParam(args);18 result = rowCountResult(sqlSession.insert(command.getName(), param));19 } else if (SqlCommandType.UPDATE == command.getType()) {20 Object param = method.convertArgsToSqlCommandParam(args);21 result = rowCountResult(sqlSession.update(command.getName(), param));22 } else if (SqlCommandType.DELETE == command.getType()) {23 Object param = method.convertArgsToSqlCommandParam(args);24 result = rowCountResult(sqlSession.delete(command.getName(), param));25 } else if (SqlCommandType.SELECT == command.getType()) {26if (method.returnsVoid() && method.hasResultHandler()) {27 executeWithResultHandler(sqlSession, args);28 result = null;29 } else if (method.returnsMany()) {30 result = executeForMany(sqlSession, args);31 } else if (method.returnsMap()) {32 result = executeForMap(sqlSession, args);33 } else {34 Object param = method.convertArgsToSqlCommandParam(args);35 result = sqlSession.selectOne(command.getName(), param);36 }37 } else if (SqlCommandType.FLUSH == command.getType()) {38 result = sqlSession.flushStatements();39 } else {40throw new BindingException("Unknown execution method for: " + command.getName());41 }42if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {43throw new BindingException("Mapper method '" + command.getName()44 + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");45 }46return result;47 }48// ...插件的构建: 谈原理⾸先要知道StatementHandler,ParameterHandler,Result Handler都是代理,他们是Configuration创建,在创建过程中会调⽤interceptorChain.pluginAll()⽅法,为四⼤组件组装插件(再底层是通过Plugin.wrap(target,XX, new Plugin( interceptor))来来创建的)。

请简述mybatis框架的工作执行流程

请简述mybatis框架的工作执行流程

请简述mybatis框架的工作执行流程MyBatis是一个开源的持久层框架,它简化了数据库访问的过程,并提供了强大的查询功能和灵活的映射机制。

下面我将简述MyBatis框架的工作执行流程。

1. 配置:首先,我们需要在配置文件中定义数据库连接信息、映射文件的位置和其他相关配置。

MyBatis支持多种配置方式,包括XML配置文件和注解配置等。

2. 创建SqlSessionFactory:MyBatis的工作流程是先创建一个SqlSessionFactory对象,然后通过它来创建SqlSession对象。

SqlSessionFactory是一个线程安全的对象,通常在应用程序的启动阶段创建一次即可。

3. 创建SqlSession:SqlSession是与数据库交互的核心对象,它封装了所有与数据库操作相关的方法。

我们可以通过SqlSessionFactory来创建SqlSession对象,每个线程都应该有一个独立的SqlSession实例。

4. 执行SQL语句:在SqlSession中,我们可以通过调用其提供的方法来执行SQL语句。

MyBatis支持一系列的SQL语句,包括查询、插入、更新和删除等操作。

执行SQL语句后,MyBatis会返回相应的结果。

5. 映射文件:MyBatis采用了基于XML的映射方式,我们需要在映射文件中定义SQL语句和数据库表之间的映射关系。

映射文件中包含了SQL语句的编写和结果集的映射规则。

6. 参数映射:在执行SQL语句时,我们可以通过参数映射方式来传递参数。

MyBatis支持多种参数映射方式,包括基本类型、对象类型和注解方式等。

7. 结果映射:执行SQL语句后,MyBatis会自动将结果集映射到Java对象中。

我们可以通过在映射文件中定义结果映射规则来指定如何将数据库表的字段映射到Java对象的属性。

8. 事务管理:MyBatis提供了对事务的支持,可以通过配置文件或注解来管理事务。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MyBatis源码分析-SQL语句执行的完整流程MyBatis 是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。

MyBatis 避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集。

MyBatis 可以对配置和原生Map 使用简单的XML 或注解,将接口和Java 的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

如何新建MyBatis源码工程请点击MyBatis源码分析-IDEA 新建MyBatis源码工程。

MyBatis框架主要完成的是以下2件事情:根据JDBC规范建立与数据库的连接。

通过反射打通Java对象与数据库参数交互之间相互转换的关系。

MyBatis框架是一种典型的交互式框架,先准备好交互的必要条件,然后构建一个交互的环境,在交互环境中划分会话,在会话中与数据库进行交互数据。

1 MyBatis主要的类Configuration MyBatis所有的配置信息都维持在Configuration对象之中。

SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护StatementHandler 封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。

ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所需要的参数,ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换MappedStatement MappedStatement维护了一条<select|update|delete|insert>节点的封装,SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回BoundSql 表示动态生成的SQL语句以及相应的参数信息以上几个类在SQL操作中都会涉及,在SQL操作中重点关注下SQL参数什么时候写入和结果集怎么转换为Java对象,这两个过程正好对应的类是PreparedStatementHandler和ResultSetHandler类。

(图片来自《深入理解mybatis原理》MyBatis的架构设计以及实例分析)2 SQL执行流程MyBatis主要设计目的还是为了让我们在执行SQL时对输入输出的数据的管理更加方便,所以方便的让我们写出SQL和方便的获取SQL的执行结果是MyBatis的核心竞争力。

下面就用一个例子来从源码角度看一下SQL的完整执行流程。

新建配置文件conf.xml:conf.xml首先建立数据表,这里就以user表为例:复制代码DROP TABLE IF EXISTS user;CREATE TABLE user (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,name VARCHAR(32) NOT NULL,password VARCHAR(32) NOT NULL,email VARCHAR(32),phone VARCHAR(16),admin VARCHAR(16));复制代码然后新建与数据表对应的类User:User再新建usre表的配置文件:userMapper.xml最后新建测试类:复制代码/*** MyBatis测试类*/public class TestMain {public static void main(String[] args) throws IOException {String resouce = "conf.xml";InputStream is = Resources.getResourceAsStream(resouce);// 构建sqlSession工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);// 获取sqlSessionSqlSession session = sqlSessionFactory.openSession();User user;try {/*** 第一种方式: 直接执行已映射的SQL 语句*/String statement = "erDao.getById";user = session.selectOne(statement, 1);System.out.println(user);}finally {session.close();}/*** 第二种方式: 执行更清晰和类型安全的代码// UserDao userDao = session.getMapper(UserDao.class);// user = userDao.getById(1);// System.out.println(user);}}复制代码由于我们分析的是SQL的执行流程,那就重点关注下user = session.selectOne(statement, 1); 这行代码~ 注意,传进去的参数是1。

session是DefaultSqlSession类型的,因为sqlSessionFactory默认生成的SqlSession是DefaultSqlSession类型。

selectOne()会调用selectList()。

复制代码// DefaultSqlSession类public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {try {MappedStatement ms = configuration.getMappedStatement(statement);// CURD操作是交给Excetor去处理的return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);} catch (Exception e) {throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}复制代码在DefaultSqlSession.selectList中的各种CURD操作都是通多Executor进行的,这里executor的类型是CachingExecutor,接着跳转到其中的query方法中。

// CachingExecutor 类public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { BoundSql boundSql = ms.getBoundSql(parameterObject); // 获取绑定的sql命令,比如"SELECT * FROM xxx"CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}getBoundSql为了获取绑定的sql命令,在创建完cacheKey之后,就进入到CachingExecutor 类中的另一个query方法中。

复制代码// CachingExecutor 类@Overridepublic <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {Cache cache = ms.getCache();if (cache != null) {flushCacheIfRequired(ms);if (ms.isUseCache() && resultHandler == null) {@SuppressWarnings("unchecked")List<E> list = (List<E>) tcm.getObject(cache, key);if (list == null) {list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);tcm.putObject(cache, key, list); // issue #578 and #116}return list;}}return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}复制代码这里真正执行query操作的是SimplyExecutor代理来完成的,接着就进入到了SimplyExecutor的父类BaseExecutor的query方法中。

复制代码// SimplyExecutor的父类BaseExecutor类@SuppressWarnings("unchecked")@Overridepublic <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());if (closed) {throw new ExecutorException("Executor was closed.");}if (queryStack == 0 && ms.isFlushCacheRequired()) {clearLocalCache();}List<E> list;try {queryStack++;/*** localCache是一级缓存,如果找不到就调用queryFromDatabase从数据库中查找*/list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;if (list != null) {handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);} else {list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);}} finally {queryStack--;}if (queryStack == 0) {for (DeferredLoad deferredLoad : deferredLoads) {// issue #601deferredLoads.clear();if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {// issue #482clearLocalCache();}}return list;}复制代码因为是第一次SQL查询操作,所以会调用queryFromDatabase方法来执行查询。

相关文档
最新文档