深入源碼分析mybatis查詢原理(一)

   MyBatis是目前非常流行的ORM框架,它的功能很強大,然而其實現卻比較簡單、優雅。我主要是結合mybatis CRUD實例,深入代碼,來探究MyBatis的實現。

前言:這篇文章的案例來源於 ArryLuo123 的案例,我主要是想跟蹤源碼,分析mybatis一次查詢都是怎麼實現的,因此就找了案例,不過這個案例數據庫是由oracle實現的,而我的機子沒有安裝oracle,所以我修改爲mysql的實現,好了,閒話少說。

這篇博文主要是把項目構建出來
由於那位哥們並沒有把數據庫表的設計整理出來,那我整理成sql語句吧:
CREATE TABLE `emp` (
  `EMPNO` int(11) NOT NULL AUTO_INCREMENT,
  `ENAME` varchar(36) DEFAULT NULL,
  `JOB` varchar(255) DEFAULT NULL,
  `MGR` int(11) DEFAULT NULL,
  `HIREDATE` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `SAL` int(11) DEFAULT NULL,
  `COMM` int(11) DEFAULT NULL,
  `DEPTNO` int(11) DEFAULT NULL,
  PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;


項目結構如下:


以下把代碼粘貼下來:

Dept.java

package com.shandian.bean;


public class Dept {
	private Integer deptno;
	private String dname;
	private String loc;


	public Integer getDeptno() {
		return deptno;
	}


	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}


	public String getDname() {
		return dname;
	}


	public void setDname(String dname) {
		this.dname = dname;
	}


	public String getLoc() {
		return loc;
	}


	public void setLoc(String loc) {
		this.loc = loc;
	}

	@Override
	public String toString() {
		return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
	}
}
Emp.java
package com.shandian.bean;


import java.sql.Timestamp;


public class Emp {


	private Integer empno;
	private String ename;
	private String job;
	private Integer mgr;
	private Timestamp hiredate;
	private Integer sal;
	private Integer comm;
	private Integer Integerno;


	public Integer getEmpno() {
		return empno;
	}


	public void setEmpno(Integer empno) {
		this.empno = empno;
	}


	public String getEname() {
		return ename;
	}


	public void setEname(String ename) {
		this.ename = ename;
	}


	public String getJob() {
		return job;
	}


	public void setJob(String job) {
		this.job = job;
	}


	public Integer getMgr() {
		return mgr;
	}


	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}


	public Timestamp getHiredate() {
		return hiredate;
	}


	public void setHiredate(Timestamp hiredate) {
		this.hiredate = hiredate;
	}


	public Integer getSal() {
		return sal;
	}


	public void setSal(Integer sal) {
		this.sal = sal;
	}


	public Integer getComm() {
		return comm;
	}


	public void setComm(Integer comm) {
		this.comm = comm;
	}


	public Integer getIntegerno() {
		return Integerno;
	}


	public void setIntegerno(Integer Integerno) {
		this.Integerno = Integerno;
	}


	@Override
	public String toString() {
		return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate
				+ ", sal=" + sal + ", comm=" + comm + ", Integerno=" + Integerno + "]";
	}


}

empmapper.java

package com.shandian.mapper;

import java.util.List;

import com.shandian.bean.Emp;

//注意,這裏的名字必須與com.shandian.mapper.empmapper,中empmapper的名字一致且必須在同一包中,不然就不能映射
public interface empmapper {
	// 這個方法名必須與empmaper中進行添加操作的名字一樣的.
	// 參數的類型也要一致
	void add(Emp emp);


	// 查詢全部
	List<Emp> queryall();


	// 進行刪除
	void delete(int id);


	// 修改
	void update(Emp emp);
}

empmapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "--mybatismapper--" "mybatis-3-mapper.dtd" >
<mapper namespace="com.shandian.mapper.empmapper">
	<!--resultType的值引用了config中typeAliases> <typeAlias type="com.shandian.bean.Emp" 
		alias="emp" /> </typeAliases>的alias的值 -->
	<select id="queryall" resultType="emp" resultMap="empResult">
		select *from
		emp
	</select>
	<!-- 添加 -->
	<!-- 添加操作並沒有結果集,結果類型也沒有 -->
	<insert id="add" parameterType="emp" useGeneratedKeys="true" keyProperty="empno"  keyColumn = "EMPNO">
		insert into emp(ename,job)
		values(#{ename},#{job})
	</insert>
	<!-- 進行刪除操作 -->
	<!-- id的意思表示命名空間的唯一標識,與映射接口中的方法一致 -->
	<delete id="delete" parameterType="int">
		delete from emp where
		empno=#{empno}
	</delete>
	<!-- 修改 -->
	<update id="update" parameterType="emp">
		update emp
		<!-- 動態的sql修改 -->
		<set>
			<!--test裏面的值是你bean裏面的變量名,而不是數據庫中的字段名 -->
			<if test="ename!=null">


				ENAME=#{ename},
			</if>
			<if test="job!=null">
				JOB=#{job},
			</if>
			<if test="mgr!=null">
				MGR=#{mgr},
			</if>
			<if test="hiredate!=null">
				HIREDATE=#{hiredate},
			</if>
			<if test="sal!=null">
				SAL=#{sal},
			</if>
			<if test="comm!=null">
				COMM=#{comm},
			</if>
			<if test="Integerno!=null">
				DEPTNO=#{Integerno}
			</if>
		</set>
		where empno=#{empno}
	</update>
	<resultMap type="emp" id="empResult">
		<id column="EMPNO" property="empno" />
		<result column="ENAME" property="ename" />
		<result column="JOB" property="job" />
		<result column="MGR" property="mgr" />
		<result column="HIREDATE" property="hiredate" />
		<result column="SAL" property="sal" />
		<result column="COMM" property="comm" />
		<result column="DEPTNO" property="Integerno" />
	</resultMap>
</mapper>

mybatisconfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "--mybatisconfig--" "mybatis-3-config.dtd" >
<configuration>
	<typeAliases>
		<typeAlias type="com.shandian.bean.Emp" alias="emp" />
	</typeAliases>
	<environments default="development">


		<environment id="development">


			<transactionManager type="JDBC">
			</transactionManager>
			<!--連接池 -->
			<dataSource type="POOLED">
				<!--連接數據庫驅動 -->
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<!-- URL -->
				<property name="url" value="jdbc:mysql://localhost:3306/mytest" />
				<!--用戶名 -->
				<property name="username" value="root" />
				<property name="password" value="" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
	<!--引用你的empmapper.xml文件  -->
		<mapper resource="com/shandian/mapper/empmapper.xml" />
	</mappers>
</configuration>

EmpTexst.java

package com.shandian.texst;

import java.io.IOException;
import java.io.Reader;
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 com.shandian.bean.Emp;
import com.shandian.mapper.empmapper;


public class EmpTexst {
	// 測試
	public static void main(String[] args) {
		// 查詢全部
        t1();
		// 添加
        //t2();
		// 刪除
		// t3();
		// 修改
        //t4();
	}

	private static void t4() {
		// TODO Auto-generated method stub
		try {
			Reader reader = Resources.getResourceAsReader("mybatisconfig.xml");
			SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
			SqlSessionFactory factory = builder.build(reader);
			SqlSession session = factory.openSession();
			Emp emp = new Emp();
			emp.setEmpno(7720);
			emp.setEname("java");
			emp.setJob("java");
			empmapper empmapper = session.getMapper(empmapper.class);
			empmapper.update(emp);
			session.commit();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	private static void t3() {
		// TODO Auto-generated method stub
		try {
			Reader reader = Resources.getResourceAsReader("mybatisconfig.xml");
			SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
			SqlSessionFactory factory = builder.build(reader);
			SqlSession session = factory.openSession();
			empmapper empmapper = session.getMapper(empmapper.class);
			empmapper.delete(7717);
			session.commit();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	private static void t2() {
		// TODO Auto-generated method stub
		try {
			// 加載配置
			Reader reader = Resources.getResourceAsReader("mybatisconfig.xml");
			// 創建
			SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
			SqlSessionFactory factory = builder.build(reader);
			SqlSession session = factory.openSession();
			Emp emp = new Emp();
			emp.setEname("admin");
			emp.setJob("Android33");
			// 添加1操作
			/*
			 * session.insert("com.shandian.mapper.empmapper.add", emp);
			 * session.commit();
			 */
			// 添加2操作,這種做法是官方推薦的
			empmapper empMapper = session.getMapper(empmapper.class);
			empMapper.add(emp);
			session.commit();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	private static void t1() {
		// TODO Auto-generated method stub
		// 加載配置
		try {
			Reader reader = Resources.getResourceAsReader("mybatisconfig.xml");
			// 創建
			SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
			// 解析資源
			SqlSessionFactory factory = builder.build(reader);
			// 打開session
			SqlSession session = factory.openSession();
			// 1傳統寫法,不推薦
			/*
			 * List<Emp> list =
			 * session.selectList("com.shandian.mapper.empmapper.queryall"); for
			 * (Emp emp : list) { System.out.println(emp); }
			 */
			// 2,用接口映射的形式進行查詢,官方推薦
			empmapper empmapper = session.getMapper(empmapper.class);
			List<Emp> list = empmapper.queryall();
			for (Emp emp : list) {
				System.out.println(emp);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

pom.xml 依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mybatis</groupId>
	<artifactId>mybatisDemo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
	<dependencies>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.1</version>
		</dependency>
		<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.31</version>
	     </dependency>
	      <dependency>
	       <groupId>junit</groupId>
	       <artifactId>junit</artifactId>
	       <version>4.10</version>
	      </dependency>
	</dependencies>
   
</project>

還有兩個約束:

mybatis-3-config.dtd

<?xml version="1.0" encoding="UTF-8" ?>
<!--


       Copyright 2009-2016 the original author or authors.


       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at


          http://www.apache.org/licenses/LICENSE-2.0


       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.


-->
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>


<!ELEMENT databaseIdProvider (property*)>
<!ATTLIST databaseIdProvider
type CDATA #REQUIRED
>


<!ELEMENT properties (property*)>
<!ATTLIST properties
resource CDATA #IMPLIED
url CDATA #IMPLIED
>


<!ELEMENT property EMPTY>
<!ATTLIST property
name CDATA #REQUIRED
value CDATA #REQUIRED
>


<!ELEMENT settings (setting+)>


<!ELEMENT setting EMPTY>
<!ATTLIST setting
name CDATA #REQUIRED
value CDATA #REQUIRED
>


<!ELEMENT typeAliases (typeAlias*,package*)>


<!ELEMENT typeAlias EMPTY>
<!ATTLIST typeAlias
type CDATA #REQUIRED
alias CDATA #IMPLIED
>


<!ELEMENT typeHandlers (typeHandler*,package*)>


<!ELEMENT typeHandler EMPTY>
<!ATTLIST typeHandler
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
handler CDATA #REQUIRED
>


<!ELEMENT objectFactory (property*)>
<!ATTLIST objectFactory
type CDATA #REQUIRED
>


<!ELEMENT objectWrapperFactory (property*)>
<!ATTLIST objectWrapperFactory
type CDATA #REQUIRED
>


<!ELEMENT reflectorFactory EMPTY>
<!ATTLIST reflectorFactory
type CDATA #REQUIRED
>


<!ELEMENT plugins (plugin+)>


<!ELEMENT plugin (property*)>
<!ATTLIST plugin
interceptor CDATA #REQUIRED
>


<!ELEMENT environments (environment+)>
<!ATTLIST environments
default CDATA #REQUIRED
>


<!ELEMENT environment (transactionManager,dataSource)>
<!ATTLIST environment
id CDATA #REQUIRED
>


<!ELEMENT transactionManager (property*)>
<!ATTLIST transactionManager
type CDATA #REQUIRED
>


<!ELEMENT dataSource (property*)>
<!ATTLIST dataSource
type CDATA #REQUIRED
>


<!ELEMENT mappers (mapper*,package*)>


<!ELEMENT mapper EMPTY>
<!ATTLIST mapper
resource CDATA #IMPLIED
url CDATA #IMPLIED
class CDATA #IMPLIED
>


<!ELEMENT package EMPTY>
<!ATTLIST package
name CDATA #REQUIRED
>

mybatis-3-mapper.dtd


<?xml version="1.0" encoding="UTF-8" ?>
<!--


       Copyright 2009-2011 The MyBatis Team


       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at


          http://www.apache.org/licenses/LICENSE-2.0


       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.


-->


<!ELEMENT mapper (cache-ref | cache | resultMap* | parameterMap* | sql* | insert* | update* | delete* | select* )+>
<!ATTLIST mapper
xmlns:fo CDATA #IMPLIED
namespace CDATA #IMPLIED
>


<!ELEMENT cache-ref EMPTY>
<!ATTLIST cache-ref
namespace CDATA #REQUIRED
>


<!ELEMENT cache (property*)>
<!ATTLIST cache
type CDATA #IMPLIED
eviction CDATA #IMPLIED
flushInterval CDATA #IMPLIED
size CDATA #IMPLIED
readOnly CDATA #IMPLIED
>


<!ELEMENT parameterMap (parameter+)?>
<!ATTLIST parameterMap
id CDATA #REQUIRED
type CDATA #REQUIRED
>


<!ELEMENT parameter EMPTY>
<!ATTLIST parameter
property CDATA #REQUIRED
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
mode (IN | OUT | INOUT) #IMPLIED
resultMap CDATA #IMPLIED
scale CDATA #IMPLIED
typeHandler CDATA #IMPLIED
>


<!ELEMENT resultMap (constructor?,id*,result*,association*,collection*, discriminator?)>
<!ATTLIST resultMap
id CDATA #REQUIRED
type CDATA #REQUIRED
extends CDATA #IMPLIED
autoMapping (true|false) #IMPLIED
>


<!ELEMENT constructor (idArg*,arg*)>


<!ELEMENT id EMPTY>
<!ATTLIST id
property CDATA #IMPLIED
javaType CDATA #IMPLIED
column CDATA #IMPLIED
jdbcType CDATA #IMPLIED
typeHandler CDATA #IMPLIED
>


<!ELEMENT result EMPTY>
<!ATTLIST result
property CDATA #IMPLIED
javaType CDATA #IMPLIED
column CDATA #IMPLIED
jdbcType CDATA #IMPLIED
typeHandler CDATA #IMPLIED
>


<!ELEMENT idArg EMPTY>
<!ATTLIST idArg
javaType CDATA #IMPLIED
column CDATA #IMPLIED
jdbcType CDATA #IMPLIED
typeHandler CDATA #IMPLIED
select CDATA #IMPLIED
resultMap CDATA #IMPLIED
>


<!ELEMENT arg EMPTY>
<!ATTLIST arg
javaType CDATA #IMPLIED
column CDATA #IMPLIED
jdbcType CDATA #IMPLIED
typeHandler CDATA #IMPLIED
select CDATA #IMPLIED
resultMap CDATA #IMPLIED
>


<!ELEMENT collection (constructor?,id*,result*,association*,collection*, discriminator?)>
<!ATTLIST collection
property CDATA #REQUIRED
column CDATA #IMPLIED
javaType CDATA #IMPLIED
ofType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
select CDATA #IMPLIED
resultMap CDATA #IMPLIED
typeHandler CDATA #IMPLIED
notNullColumn CDATA #IMPLIED
columnPrefix CDATA #IMPLIED
>


<!ELEMENT association (constructor?,id*,result*,association*,collection*, discriminator?)>
<!ATTLIST association
property CDATA #REQUIRED
column CDATA #IMPLIED
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
select CDATA #IMPLIED
resultMap CDATA #IMPLIED
typeHandler CDATA #IMPLIED
notNullColumn CDATA #IMPLIED
columnPrefix CDATA #IMPLIED
>


<!ELEMENT discriminator (case+)>
<!ATTLIST discriminator
column CDATA #IMPLIED
javaType CDATA #REQUIRED
jdbcType CDATA #IMPLIED
typeHandler CDATA #IMPLIED
>


<!ELEMENT case (constructor?,id*,result*,association*,collection*, discriminator?)>
<!ATTLIST case
value CDATA #REQUIRED
resultMap CDATA #IMPLIED 
resultType CDATA #IMPLIED
>


<!ELEMENT property EMPTY>
<!ATTLIST property
name CDATA #REQUIRED
value CDATA #REQUIRED
>


<!ELEMENT typeAlias EMPTY>
<!ATTLIST typeAlias
alias CDATA #REQUIRED
type CDATA #REQUIRED
>


<!ELEMENT select (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST select
id CDATA #REQUIRED
parameterMap CDATA #IMPLIED
parameterType CDATA #IMPLIED
resultMap CDATA #IMPLIED
resultType CDATA #IMPLIED
resultSetType (FORWARD_ONLY | SCROLL_INSENSITIVE | SCROLL_SENSITIVE) #IMPLIED
statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED
fetchSize CDATA #IMPLIED
timeout CDATA #IMPLIED
flushCache (true|false) #IMPLIED
useCache (true|false) #IMPLIED
databaseId CDATA #IMPLIED
>


<!ELEMENT insert (#PCDATA | selectKey | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST insert
id CDATA #REQUIRED
parameterMap CDATA #IMPLIED
parameterType CDATA #IMPLIED
timeout CDATA #IMPLIED
flushCache (true|false) #IMPLIED
statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED
keyProperty CDATA #IMPLIED
useGeneratedKeys (true|false) #IMPLIED
keyColumn CDATA #IMPLIED
databaseId CDATA #IMPLIED
>


<!ELEMENT selectKey (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST selectKey
resultType CDATA #IMPLIED
statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED
keyProperty CDATA #IMPLIED
order (BEFORE|AFTER) #IMPLIED
databaseId CDATA #IMPLIED
>


<!ELEMENT update (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST update
id CDATA #REQUIRED
parameterMap CDATA #IMPLIED
parameterType CDATA #IMPLIED
timeout CDATA #IMPLIED
flushCache (true|false) #IMPLIED
statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED
databaseId CDATA #IMPLIED
>


<!ELEMENT delete (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST delete
id CDATA #REQUIRED
parameterMap CDATA #IMPLIED
parameterType CDATA #IMPLIED
timeout CDATA #IMPLIED
flushCache (true|false) #IMPLIED
statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED
databaseId CDATA #IMPLIED
>


<!-- Dynamic -->


<!ELEMENT include EMPTY>
<!ATTLIST include
refid CDATA #REQUIRED
>


<!ELEMENT sql (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST sql
id CDATA #REQUIRED
>


<!ELEMENT trim (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST trim
prefix CDATA #IMPLIED
prefixOverrides CDATA #IMPLIED
suffix CDATA #IMPLIED
suffixOverrides CDATA #IMPLIED
>
<!ELEMENT where (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ELEMENT set (#PCDATA | include | trim | where | set | foreach | choose | if)*>


<!ELEMENT foreach (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST foreach
collection CDATA #REQUIRED
item CDATA #IMPLIED
index CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
separator CDATA #IMPLIED
>


<!ELEMENT choose (when* , otherwise?)>
<!ELEMENT when (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST when
test CDATA #REQUIRED
>
<!ELEMENT otherwise (#PCDATA | include | trim | where | set | foreach | choose | if)*>


<!ELEMENT if (#PCDATA | include | trim | where | set | foreach | choose | if)*>
<!ATTLIST if
test CDATA #REQUIRED
>
好了,以上是項目需要的所有文件


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