Mybatis框架:逆向工程,運行原理(底層原碼分析)

逆向工程

逆向工程就是根據你的表,自動來創建相應的POJO,mapper接口,sql映射文件
主要看官方文檔的說明的例子,這裏給個例子

XML配置文檔

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	
	<!-- context是一些環境設置
	The <context> element is used to specify the environment for generating a set of objects.
	 -->
	<context id="DB2Tables" targetRuntime="MyBatis3">
		<!-- jdbcConnection:指定如何連接到目標數據庫 -->
		<jdbcConnection
			driverClass="com.mysql.cj.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8" 
			userId="root" 
			password="1234">
		</jdbcConnection>
		
		<!-- 類型解析器,默認就行 -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>
		
		<!-- javaModelGenerator:指定JavaBean的生成策略
				targetPackage:指定目標包名
				targetProject:指定目標工程
		 -->
		<javaModelGenerator 
			targetPackage="bean"
			targetProject=".\src">
			<property name="enableSubPackages" value="true" />
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		
		<!-- sqlMapGenerator:sql映射生成策略,就是那個映射xml文件
				targetPackage:包
				targetProject:工程
		 -->
		<sqlMapGenerator 
			targetPackage="bean"
			targetProject=".\conf">
			<property name="enableSubPackages" value="true" />
		</sqlMapGenerator>
		
		<!--javaClientGenerator:mapper接口生成策略 
		 -->
		<javaClientGenerator 
			type="XMLMAPPER"
			targetPackage="bean" 
			targetProject=".\src">
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>
		
		<!-- 指定要逆向分析哪些表,根據表創建JavaBean -->
		<table tableName="emp" domainObjectName="Emp"></table>
		<table tableName="dept" domainObjectName="Dept"></table>

	</context>
</generatorConfiguration>

自動生成的Java代碼

	@org.junit.Test
	public void test2() throws Exception
	{
		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		File configFile = new File("mbg.xml");
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
		myBatisGenerator.generate(null);
	}

使用自動生成的查詢

生成後的類你會發現還有一個是EmpExample的類
這就是自動生成的具有QBC(Query By Criteria)風格的複雜查詢,
下面就使用一下

	@org.junit.Test
	public void test1() throws IOException
	{
		String resource = "mybatis.xml"; 
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession openSession = sqlSessionFactory.openSession();
		try
		{
			EmpMapper mapper = openSession.getMapper(EmpMapper.class);
			//xxxByExample就是用來封裝查詢條件的
			//查詢所有的數據
			//發送的sql是:select id, lastname, email, gender, did from emp
//			List<Emp> selectByExample = mapper.selectByExample(null);
//			for (Emp emp : selectByExample)
//			{
//				System.out.println(emp);
//			}
			
			/*
			 * 現在想複雜查詢,查詢名字帶有e的男性員工,或者email中帶有e的員工
			 * 1.首先example是封裝員工查詢條件的類
			 * 2.而criteria是拼接查詢條件的
			 * 如果是and的條件,全部放在第一個criteria裏面就行,它會以and方式進行拼接
			 * 如果是or的條件,這得新建一個criteria,並且調用example.or(criteria2);
			 * 發的SQL語句:select id, lastname, email, gender, did from emp WHERE ( lastname like ? and gender = ? ) or( email like ? )
			 */
			
			EmpExample example=new EmpExample();
			Criteria criteria = example.createCriteria();
			criteria.andLastnameLike("%e%");
			criteria.andGenderEqualTo("男");
			
			Criteria criteria2 = example.createCriteria();
			criteria2.andEmailLike("%e%");
			example.or(criteria2);
			
			List<Emp> selectByExample = mapper.selectByExample(example);
			for (Emp emp : selectByExample)
			{
				System.out.println(emp);
			}
			
		}finally
		{
			openSession.close();
		}
	}

運行原理

結構層次

在這裏插入圖片描述

1.獲取sqlSessionFactory對象

根據配置文件創建SQLSessionFactory
在這裏插入圖片描述
Configuration封裝了所有配置文件的詳細信息
步驟是:
在這裏插入圖片描述
一些重要的對象的操作過程
解析器,使用DOM4j的解析器
在這裏插入圖片描述
解析器對映射文件的解析,也是使用DOM4j的解析器
在這裏插入圖片描述

Configuration對象保存了所有配置文件的詳細信息
在這裏插入圖片描述

全局Configuration中的一個重要屬性:mappedStatements,每一個代表一個增刪改查標籤
在這裏插入圖片描述

全局Configuration中的一個重要屬性:mapperRegistry
mapperRegistry裏面是mapper接口的代理工廠,代理對象就是由工廠創建的
在這裏插入圖片描述

總結:把配置文件的信息解析並保存在Configuration對象中,返回包含了Configuration的DefaultSqlSession對象。

2.獲取sqlSession對象

返回SqlSession的實現類DefaultSqlSession對象。
他裏面包含了Executor和Configuration;
Executor會在這一步被創建

步驟是
在這裏插入圖片描述

getMapper

getMapper返回接口的代理對象包含了SqlSession對象
在這裏插入圖片描述
步驟是
在這裏插入圖片描述

查詢

步驟
在這裏插入圖片描述

重要對象
boundSql對象:是在執行executor.query()的時候創建的,裏面包含很多SQL語句,設置參數,參數的Java類型等等信息
在這裏插入圖片描述
使用緩存,緩存中保存的key:方法id+sql+參數xxx
在這裏插入圖片描述

總結
StatementHandler:處理sql語句預編譯,設置參數等相關工作;
ParameterHandler:設置預編譯參數用的
ResultHandler:處理結果集
TypeHandler:在整個過程中,進行數據庫類型和javaBean類型的映射

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章