1.數(shù)據(jù)庫(kù)的環(huán)境切換
2.注解方式
?## 推薦使用xml
a.將sql語(yǔ)句寫(xiě)在接口的方法前面
b.將接口的全類名寫(xiě)入到<mapper>,讓mybatis知道sql語(yǔ)句此時(shí)是存儲(chǔ)在接口中的。


注意:注解和XML都支持批量引入
<mappers>
<!--以下可以將com.itt.mapper包中的注解接口和xml
全部一次性引入-->
<package name="com.itt.mapper"/>
</mappers>
3.增刪改的返回問(wèn)題
- 返回值 可以是void ,Integer,Long,Boolean,只需要在接口中改返回值就可以了!
4.事務(wù)提交方式
- 手動(dòng)提交:
SqlSession session = sessionFactory.openSession();
session.commit();//執(zhí)行完commit時(shí),手動(dòng)提交 事務(wù)
- 自動(dòng)提交 :每一個(gè)dml語(yǔ)句自動(dòng)提交
SqlSession session = sessionFactory.openSession(true);
5.參數(shù)問(wèn)題
目前將多個(gè)參數(shù)封裝到一個(gè)javabean對(duì)象(pojo),然后使用該對(duì)象傳遞
-
a.傳入多個(gè)參數(shù)時(shí),不用在mapper.xml中編寫(xiě)parameterType
異常提示:
-
stuNo不能使用,使用的是:【arg3,arg2,arg1,arg0,param3,param2,param1】
<insert id="insertEmpInfo"> insert into empinfo(id,name,age,job,phone) values (#{arg0},#{arg1},#{arg2},#{arg3},#{arg4}) </insert> -
b. 命名參數(shù)的方式
可以在接口中通過(guò)@Param("")來(lái)指定sql中參數(shù)的名字
void insertEmpInfo(@Param("sId") String id, @Param("sName") String name, @Param("sAge") String age, @Param("sJob") String job, @Param("sPhone") String phone);<insert id="insertEmpInfo"> insert into empinfo(id,name,age,job,phone) values (#{sId},#{sName},#{sAge},#{sJob},#{sPhone}) </insert> -
c. 綜合使用的情況
//一個(gè)是簡(jiǎn)單類型 ,一個(gè)是對(duì)象類型 void insertEmpInfo(@Param("sId") String id,@Param("empInfo") EmpInfo empInfo);<insert id="insertEmpInfo"> insert into empinfo(id,name,age,job,phone) values (#{sId},#{empInfo.name},#{empInfo.age},#{empInfo.job},#{empInfo.phone}) </insert>
6.增加null
oracle:如果插入的 字段是null,提示錯(cuò)誤:Other 而不是gnull
mysql:如果插入的字段是null,可以正常執(zhí)行(沒(méi)有約束)
原因:
各個(gè)數(shù)據(jù)庫(kù)在Mybatis中對(duì)各種數(shù)據(jù)類型的默認(rèn)值不一致。
?mybatis中,jdbcTypeForNull(如果是null),則默認(rèn)值OTHER。
在mysql中,mybatis將Other當(dāng)做NULL來(lái)處理了,但是oracle不行。
解決:
? oracle:null -> OTHER 手工告訴oracle:other -> null
a. 當(dāng)某個(gè)數(shù)據(jù)類型oracle無(wú)法處理進(jìn),告訴它用默認(rèn)值null 來(lái)處理
//使用#{empInfo.name,jdbcType=null}這個(gè)就可以了
<insert id="insertEmpInfo">
insert into empinfo(id,name,age,job,phone)
values (#{sId},#{empInfo.name,jdbcType=null},#{empInfo.age},#{empInfo.job},#{empInfo.phone})
</insert>
b. 配置mybatis全局配置文件conf.xml
<settings>
<setting name="jdbcTypeForNull" value="NUll"/>
</settings>
7.返回值為HashMap的情況
- 注意:在mysql中@MapKey("id")字段為小寫(xiě)
- 在oracle中為全大寫(xiě)
- map:
- key:id value:Student
- 程序根據(jù)select的返回值,知道m(xù)ap的value就是EmpInfo,根據(jù)@MapKey("id")知道Map的key是id
@MapKey("id")
HashMap<String,EmpInfo> queryAllEmp();
<select id="queryAllEmp" resultType="HashMap">
select * from empinfo
</select>
8.ResultMap:字段和屬性名的相應(yīng)
- column指的是數(shù)據(jù)庫(kù)中的列名
- property指的是類中的名字
<select id="queryAllEmpins" resultType="HashMap"
resultMap="EmpInoMap">
select * from empinfo
</select>
<resultMap id="EmpInoMap" type="empInfo">
<id column="eid" property="id"/>
<result column="ename" property="name"/>
<result column="eage" property="age"/>
<result column="ejob" property="job"/>
<result column="ephone" property="phone"/>
</resultMap>
9.別名問(wèn)題
<!--設(shè)置單個(gè)/多個(gè)別名-->
<typeAliases>
<!--單個(gè)別名(別名 忽略大小寫(xiě))-->
<!--<typeAlias type="com.itt.entity.Student" alias="student"/>-->
<!--批量定義別名,以下會(huì)自動(dòng)將該包中的所有類 批量定義別名:別名就是類名(不帶包名的類名)-->
<package name="com.itt.entity"/>
</typeAliases>
- 當(dāng)這個(gè)包下的子包 與Student重名時(shí),必須使用注解的方式重新命名
@Alias("myempinfo")
public class EmpInfo {
}
10.處理where子句后面的and的三種方式
- trim標(biāo)簽可以去掉后面的 and
- <trim>可以處理拼接sql中【開(kāi)頭或結(jié)尾】第一個(gè)and
<select id="queryByINP" parameterType="EmpInfo" resultType="EmpInfo">
select * from empinfo where
<trim>
<if test="id != null and id != 0">
id = #{id} and
</if>
<if test="name != null and name != ''">
name like '%${name}%' and
</if>
<if test="phone != null and phone != ''">
phone = #{phone} and
</if>
</trim>
</select>
- prefix="where":在整個(gè)語(yǔ)句中加where
- prefix="set":在整個(gè)語(yǔ)句中加set,可用于更新
- prefixOverrides="and":智能處理前面的and
- suffixOverrides="and":智能處理后面的and
- suffixOverrides=",":智能處理后面的,常用于更新
<trim prefix="where" prefixOverrides="and">
<if test="id != null and id != 0">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name like '%${name}%'
</if>
<if test="phone != null and phone != ''">
and phone = #{phone}
</if>
</trim>
- <where>標(biāo)簽可以去掉前面的and
<select id="queryByINP" parameterType="EmpInfo" resultType="EmpInfo">
select * from empinfo
<where>
<if test="id != null and id != 0">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name like '%${name}%'
</if>
<if test="phone != null and phone != ''">
and phone = #{phone}
</if>
</where>
</select>
- 直接 在where后面加:1 = 1
<select id="queryByINP" parameterType="EmpInfo" resultType="EmpInfo">
select * from empinfo where 1 = 1
<if test="id != null and id != 0">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name like '%${name}%'
</if>
<if test="phone != null and phone != ''">
and phone = #{phone}
</if>
</select>
11.內(nèi)置參數(shù)
- _paramter:代表Mybatis的輸入?yún)?shù)
<select id="queryByINP" parameterType="EmpInfo" resultType="EmpInfo">
select * from empinfo
<trim prefix="where" prefixOverrides="and">
<if test="id != null and id != 0">
and id = #{id}
</if>
<if test="name != null and name != ''">
and ename like '%${name}%'
</if>
//_parameter替代parameterType這個(gè)輸入的對(duì)象
<if test="_parameter.phone != null and _parameter.phone != ''">
and phone = #{_parameter.phone}
</if>
</trim>
</select>
- _databaseId:代表當(dāng)前數(shù)據(jù)庫(kù)的名字
12.模糊查詢?nèi)N方式
12.1
- ${}原樣輸出
stuName like '%${stuName}%'
-
{}自動(dòng)拼接' ':可以防止SQL注入
12.2 傳值時(shí),直接 傳 %x%
student.setStuName("%s%");
stuName like #{stuName}
12.3 bind參數(shù)
<bind name="_queryName" value="'%'+name+'%'"/>
<if test="name != null and name != ''">
and name like #{_queryName}
</if>
I:\MyBatisIdea\MyBatisGenerator\src\main\java
13.逆向工程
1.導(dǎo)入依賴
2.xml模板文件(修改生成路徑、表名)
3.根據(jù)java模板類一鍵生成
- 根據(jù)學(xué)生表->學(xué)生類、學(xué)生Mapper接口、studentMapper.xml
4.如何使用
? * 增加Mybatis配置文件 conf.xml
- 對(duì)于like模糊查詢,逆向工程需要在傳值時(shí) 寫(xiě)入%x%
逆向工程的實(shí)例:使用的是StudentExample
- 測(cè)試類
@Test
public void queryAllEmpById() throws Exception{
//Connection - SqlSession操作myBatis
//config.xml -> reader
Reader reader = Resources.getResourceAsReader("conf.xml");
//reader ->SqlSession
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
StudentExample example = new StudentExample();
StudentExample.Criteria criteria = example.createCriteria();
criteria.andStunameLike("%d%");
StudentExample example1 = new StudentExample();
StudentExample.Criteria criteria1 = example1.createCriteria();
//模糊查詢
criteria1.andStunoEqualTo(10);
criteria1.andStunameLike("%k%");
//使用exampl整合的方式實(shí)現(xiàn)or操作
example.or(criteria1);
//Example中的Criteria:為查詢的條件
List<Student> students = mapper.selectByExample(example);
System.out.println(students);
session.close();
}
14.MyBatis架構(gòu)和源碼解析
-
Mybatis源碼的幾個(gè)主要部件
MyBatis中步驟:
- 1.獲取SqlSessionFactory對(duì)象
- 2.獲取SqlSession對(duì)象
- 3.獲取xxxMapper對(duì)象(代理接口 中的方法、mapper.xml中的<select>標(biāo)簽)
- 4.執(zhí)行標(biāo)簽中定義的SQL語(yǔ)句
1.獲取SqlSessionFactory對(duì)象
- parse解析器
-
通過(guò)Configuration標(biāo)簽設(shè)置了properties、typeAliases、environments等
-
通過(guò)Configuration標(biāo)簽設(shè)置了properties、typeAliases、environments等
-
Mybatis將所有的配置信息存放到了Configuration configuration對(duì)象中
-
mapperElement的過(guò)程
-
mapperElement的過(guò)程
-
<select id="",resultType="",parameterType="">等屬性是通過(guò)
parseStatementNode()這個(gè)方法解析的

-
Mybatis會(huì)將xxxMapper.xml文件解析成MappedStatement對(duì)象
即parseStatementNode對(duì)象就是xxxMapper文件中的標(biāo)簽
MapperStatement -》存在于Configuration中
environment -》存在于Configuration中
-
所有的配置信息、增刪改標(biāo)簽全部存在于Configuration中
結(jié)論:
SqlSessionFactory對(duì)象—》DefaultSqlSessionFactory—》Configuration—》所有的配置信息
2.獲取SqlSession對(duì)象(Executor為執(zhí)行器)
-
configuration.newExecutor(tx, execType);-》默認(rèn)類型為simpleExecutor
- 并且根據(jù)不同的類型execType,產(chǎn)生不同的Executor,并對(duì)執(zhí)行器進(jìn)行攔截操作:
executor = (Executor) interceptorChain.pluginAll(executor);
作用:以后如果我們要給MyBatis寫(xiě)自己的插件,就可以通過(guò)攔截器實(shí)現(xiàn):
-
下圖就是使用攔截器一次次增強(qiáng)執(zhí)行器Executor,從而使Executor有更強(qiáng)大的功能!
返回的是:
DefaultSqlSession(configuration, executor, 事務(wù)問(wèn)題);SqlSession ->openSession()--->openSessionFromDataSource() -->DefaultSqlSession對(duì)象
-
執(zhí)行的流程
SqlSession -> DefaultSqlSession對(duì)象 -> 執(zhí)行SQL
插件開(kāi)發(fā):
1.寫(xiě)插件
2.把插件放入到攔截器中插件
select * from student --》攔截器
目標(biāo)對(duì)象target的包裝后的產(chǎn)物 --->metaObject.getValue("可以從target中獲取")
通過(guò)打印語(yǔ)句,可知,target就是 RoutingStatementHandler
----------》
metaObject.getValue("可以從RoutingStatementHandler中獲取")
可以從RoutingStatementHandler獲得:getBoundSql,getParameterHandler
------->--->metaObject.getValue("parameterHandler")
- metaObject.getValue("parameterHandler.parameterObject")//xxxMapper.xml中的語(yǔ)句中的參數(shù)值
- metaObject.getValue("parameterHandler.boundSql")//xxxMapper.xml中sql的語(yǔ)句

















