Mybatis

MyBatis

基本介绍

Hibernate:全自动化的持久化(把内存中的瞬时数据永久的保存在磁盘上/数据库中的过程)框架

MyBatis:ORM 半自动化的持久化框架(SQL语句可以自己管理)

都是ORM (对象 关系 映射)框架

  • O:javabean
  • R:关系型数据库
  • M:映射

在这里插入图片描述

MyBatis开发(常规)

① 下载地址

https://github.com/mybatis/mybatis-3/releases

https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.4.6

② 导入相应jar
在这里插入图片描述

③ 创建核心配置文件

<?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.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/user?useUnicode=true&amp;characterEncoding=utf8" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- 加载sql映射文件 -->
	<mappers>
		<mapper resource="mapper/User.xml" />
	</mappers>
</configuration>

在url后加上?useUnicode=true&characterEncoding=utf8是因为可能会出现字符集不匹配的问题

④ 创建实体映射bean

⑤ 创建sql映射文件(mapper文件)

<?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="org.mybatis.example.BlogMapper">
	<select id="selectUser" parameterType="int" resultType="bean.User">
		select * from usertable where uid = #{uid}
	</select>
</mapper>

⑥ 在核心配置文件中加载sql映射文件

	<mappers>
		<mapper resource="mapper/User.xml" />
	</mappers>

⑦ 测试

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

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 bean.User;

public class Test {

	public static void main(String[] args) {

		String resource = "configuration.xml";
		SqlSession session = null;
		
		InputStream is = Test.class.getClassLoader().getResourceAsStream(resource);
		SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
		session = ssf.openSession();
		//User user1 = (User)session.selectOne("namespace1.selectUser", 1);
		
		//接口方式
		UserDao userdao = session.getMapper(UserDao.class);
		User user2 = userdao.selectUser(1);
		System.out.println(user2);
		session.close();
	
	}

}

⑧ 日志显示
在这里插入图片描述

MyBatis开发(接口)

① 创建接口和映射文件

  • 映射文件的namespace和接口全路径一致 (让接口和映射文件进行动态绑定)
  • 接口中抽象方法名、参数、返回值类型和映射文件中SQL的id、parameterType、resultType一致, (让接口方法和映射文件SQL进行动态绑定 )

② 核心配置文件中加载映射文件或接口

在这里插入图片描述

package dao;

import bean.User;

public interface UserDao {
	
	public User selectUser(int uid);
	
}
<?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="dao.UserDao">
	<select id="selectUser" parameterType="int" resultType="bean.User">
		select * from usertable where uid = #{uid}
	</select>
</mapper>

③ 测试

mybatis通过接口方式是以Java动态代理模式进行实现的。

MyBatis开发(注解)

① 无需创建xml映射文件

② 创建接口DAO,并在接口方法前通过@Select定义sql语句

在这里插入图片描述

​ “_name” --> @Param指定当前参数(sql中)的值

③ 在核心配置文件(configuration.xml)中加载接口

在这里插入图片描述

④ 测试

以接口的方式进行测试即可

MyBatis的基本架构

在这里插入图片描述

MyBatis的作用域和生命周期

1. 作用域

●SqISessionFactoryBuilder

​ 可以在任何时候被实例化、使用和销毁。一旦您创造 了SqISessionFactory就不需要再保留

●SqlSessionFactory

​ SqlSessionFactory 一旦创建将会存在于您的应用程序整个运行生命周期中,不要在一个应用中多次创 建SqlSessionFactory

●SqISession

每个线程都有一个SqlSession 实例,SqlSession 实例是不被共享的,并且是线程不安全的作用域是request或者method

2. SqlSessionFactory对象的自定义获取

import java.beans.PropertyVetoException;
import javax.sql.DataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import bean.User;
import dao.UserDao;

public class Test2 {

	public static void main(String[] args) {

		TransactionFactory transactionFactory = new JdbcTransactionFactory();
		Environment environment = new Environment("deve", transactionFactory, getDataSource());
		Configuration config = new Configuration(environment);
		
		//加载映射文件
		config.addMapper(UserDao.class);
		
		SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
		SqlSession session = ssf.openSession();
		System.out.println("----------注解方式-------------");
		UserDao userdao = session.getMapper(UserDao.class);
		int i = userdao.selectUidByName("吴治峰");
		System.out.println(i);
		session.close();

	}

	private static DataSource getDataSource() {
		
		ComboPooledDataSource ds = new ComboPooledDataSource();
		try {
			ds.setDriverClass("com.mysql.cj.jdbc.Driver");
			ds.setJdbcUrl("jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC");
			ds.setUser("root");
			ds.setPassword("123456");
		} catch (PropertyVetoException e) {
			e.printStackTrace();
		}
		return ds;
	}

}

MyBatis的简单封装

package utils;

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class GetSqlSession {
	
	/**
	 * 获取SqlSession对象
	 * @return SqlSession
	 */
	public static SqlSession getSqlSession() {
		
		String resource = "configuration.xml";
		Reader reader = null;
		try {
			reader = Resources.getResourceAsReader(resource);
		} catch (IOException e) {
			e.printStackTrace();
		}
		SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
		SqlSession session = ssf.openSession();
		return session;
	}
	
	
}

核心配置文件Configuration.xml的几种元素

在这里插入图片描述

① properties

引入外部属性文件

在这里插入图片描述

② Settings

设置或改变Mybatis运行过程中的行为方式
在这里插入图片描述

如上例子:mapUnderscoreToCamelCase选项开启,则开启驼峰命名映射,

如果数据库字段为A_NAME,则会映射为aName,首字母小写,去掉下划线,后面驼峰

③ typeAliases

在这里插入图片描述

别名使用注意:

在这里插入图片描述

④ Typehandlers

在这里插入图片描述

⑤ Plugins

在这里插入图片描述

⑥ Environments

在这里插入图片描述

⑦ databaseIdProvider

在这里插入图片描述

⑧ Mappers

在这里插入图片描述

核心映射文件Mappers.xml

在这里插入图片描述

1. 修改sql操作

public class Test4 {

	public static void main(String[] args) {

		String resource = "configuration.xml";
		SqlSession session = GetSqlSession.getSqlSession(resource);
		
		User user = new User(0,"张五","24",1);
		UserDao userdao = session.getMapper(UserDao.class);
		int i = userdao.insert(user);
		if( i == 1) {
			System.out.println("插入成功");
		} else {
			System.out.println("插入失败");
		}
		//session.commit();需要此函数才能提交到数据库
		//或者SqlSession session = ssf.openSession(true);
        //封装在了GetSqlSession.getSqlSession()里
		session.close();

	}

}
<mapper namespace="dao.UserDao">
	<select id="selectUser" parameterType="int" resultType="bean.User">
		select * from usertable where uid = #{uid}
	</select>
	
	<insert id="insert" parameterType="bean.User" useGeneratedKeys="true" keyProperty="uid">
		insert into usertable(name,age,sex) values(#{name},#{age},#{sex})
	</insert>
	
	<delete id="delete" parameterType="int">
		delete from usertable where uid = #{uid}
	</delete>
	
	<update id="updateAge" parameterType="User">
		update usertable set age = #{age} where uid = #{uid}
	</update>
</mapper>

扩展:

插入数据时mybatis自动获取从数据库生成的主键(mysql自增长主键)方法:

​ 解:java中对象之间支持值传递,不支持引用传递,即测试用例中的user和传过去的参数user指向同一块内存地址,如果在insert之后得到主键uid,可以改变这块内存地址user的主键, 再用getUid()便可以获取到。

​ 设置useGeneratedKeys,允许JDBC支持自动生成主键,并在执行添加记录之后可以获取到数据库自动生成的主键ID。

​ 设置keyProperty指定接受返回的属性,不指定的话也不会生成。

<insert id="insert" parameterType="bean.User" useGeneratedKeys="true" keyProperty="uid">
		insert into usertable(name,age,sex) values(#{name},#{age},#{sex})</insert>
		User user = new User(0,"张五","24",1);
		UserDao userdao = session.getMapper(UserDao.class);
		int i = userdao.insert(user);
		if( i == 1) {
			System.out.println("插入成功,uid为:" + user.getUid());
		} else {
			System.out.println("插入失败");
		}

插入数据时获取插入的主键值(非自增长主键):

在这里插入图片描述

​ order设置为BEFORE表示先执行selectKey,在insert,AFTER相反,一般是BRFORE

​ rand()返回一个随机数,0~1。会有重复,这里仅演示,并不严谨。(后面的id是别名)

2. 入参处理

参数处理方式

① 单个参数

MyBatis中可以接受基本类型以及对象类型的参数

基本类型:直接通过#{name}获取即可,name可自定义

对象类型:直接通过#{属性名}获取即可[建议]

Mybatis可以接受一个Map集合作为参数类型,sql中就可以通过获取map的key来得到参数值

② 多个参数

MyBatis可以接受任意多个参数

多个参数传入时都会被重新包装成一个Map,Map的key是arg0,arg1… 或者 param1,param2…,Map的值就是入参的值,在sql语句中获取Map的key从而得到参数的值

在这里插入图片描述

③ 命名参数

多个参数传入时,为了方便在sql中获取对于的参数值,从而可以在方法入参前指定sql中获取的参数名称

	<!-- 多个参数
	<update id="updateParamAge">
		update usertable set age = #{param1} where uid = #{param2}
	</update>
	 -->
	 <!-- 取别名,增加可读性 -->
	 <update id="updateParamAge">
		update usertable set age = #{Param1_age} where uid = #{Param1_uid}
	</update>
	public int updateParamAge(@Param("Param1_age")int age,@Param("Param1_uid")int uid);

在这里插入图片描述

入参处理源码分析

在调用接口处打上断点进行代码跟踪:

在这里插入图片描述

3. Sql中的取值方式

① 两种方式:#{name}-通过Preparestatement的方式进行设置 ${name}-通过statement的方式进行设置

${}方式取值:

在这里插入图片描述

② mybatis对所有传入的NULL值映射的都是原生jdbc的OTHER类型(jdbcTypes.class文件中定义的枚举类型)

③ Mysql能够识别出OTHER类型,但是Oracle数据库则不能处理OTHER类型,可以在取值表达式中手动定义Null值得处理:*#{name,jdbcType=NULL}* 或者在核心配置文件在这里插入图片描述
中设置全局null值处理,如下:

4. 返回值类型的处理

① Int/bean对象 对修改操作的返回值

② List 在sql映射文件中指定resultType的类型,此类型是List中的元素类型,mybatis会把查询结果中的每一条数据封装成一个resultType指定的类型并添加到List中

public List<User> selectParam(User user);
<select id="selectParam" parameterType="User" resultType="User">
		select uid,name,sex from usertable where name like #{name,jdbcType=NULL} order by #{sex}
	</select>

③ Map<String,Object>

A、返回单条记录:key就是列名,value为列的值,resultType=”map”/“Map”

public Map<String,Object> selectMapOne(int uid);
<select id="selectMapOne" parameterType="int" resultType="Map">
		select uid,name,sex from usertable where uid = #{uid}
	</select>

B、返回多条记录Map<String,User>:key为指定的属性值,value为当前对象(一个属性值对应一条记录),resultType=”map中值(value)的类型”,另外需要在接口方法前通过@MapKey(“uid”)来指定key

@MapKey("name")//指定某个bean的属性值作为Map的key,这里指定的是name
	public Map<String,User> selectMap(int uid);
<select id="selectMap" parameterType="int" resultType="Map">
		select uid,name,sex from usertable where uid &lt; #{uid}
	</select>
System.out.println("--------返回List---------");
		User user = new User(5, "张%", "age", 1);
		List<User> list = userdao.selectParam(user);
		for(User t :list) {
			System.out.println(t);
		}
		
		System.out.println("--------返回Map(单条记录)---------");
		Map<String,Object> map = userdao.selectMapOne(1);
		for(Entry<String,Object> entry : map.entrySet()) {
			System.out.println(entry.getKey()+":"+entry.getValue());
		}
		
		System.out.println("--------返回Map(多条记录)---------");
		Map<String,User> map1 = userdao.selectMap(5);
		for(Entry<String,User> entry : map1.entrySet()) {
			System.out.println(entry.getKey()+":"+entry.getValue());
		}
符号转义字符说明
<<小于
<=<=小于等于
>>大于
>=>=大于等于
&&逻辑与
‘xxx’'单引号
“xxx”"双引号

5. select元素

① parameterType可省略,mybatis会根据TypeHandler.class and TypeHandlerRegistry.class进行自动匹配转换

② 元素属性

在这里插入图片描述

6. 返回结果映射规则

① 可在全局setting中进行设置,实现的是自动映射

Setting的属性:默认是开启自动映射的功能,要求列名和属性名要一致,如果把值设为null,则取消自动映射
在这里插入图片描述

② 驼峰映射规则:A_COLUMN 自动映射成属性 aColumn,需要开启mapUnderscoreToCamelCase

③ 手动映射配置
在这里插入图片描述

级联关系-association

1. N-1

方式一:对象限定符

① 在N端定义1端的对象属性

② 定义resultMap映射

<resultMap id="myMap1" type="User" >
		<id column="uid" property="uid" jdbcType="INTEGER" javaType="int"/>
		<result column="name" property="name" jdbcType="VARCHAR" javaType="String"/>
		<result column="age" property="age" jdbcType="VARCHAR" javaType="String"/>
		<result column="sex" property="sex" jdbcType="INTEGER" javaType="int"/>
		<result column="aid" property="address.aid" jdbcType="INTEGER" javaType="int"/>
		<result column="aname" property="address.aname" jdbcType="VARCHAR" javaType="String"/>
	</resultMap>

③ Sql语句

	<select id="getUserN1" parameterType="int" resultMap="myMap1">
		select uid,name,sex,a.aid aid,aname
			from usertable u ,address a
				where u.aid=a.aid and uid = #{uid}
	</select>	 
方式二:association赋值
<resultMap id="myMap2" type="User" >
		<id column="uid" property="uid" jdbcType="INTEGER" javaType="int"/>
		<result column="name" property="name" jdbcType="VARCHAR" javaType="String"/>
		<result column="age" property="age" jdbcType="VARCHAR" javaType="String"/>
		<result column="sex" property="sex" jdbcType="INTEGER" javaType="int"/>
		<association property="address" javaType="bean.Address">
			<id column="aid" property="aid" jdbcType="INTEGER" javaType="int"/>
			<result column="aname" property="aname" jdbcType="VARCHAR" javaType="String"/>
		</association>
	</resultMap>
方式三:分步查询

① 创建1端的根据id查询对象的映射文件

<?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="dao.AddressDao">

	<select id="selectAnameByAid" parameterType="int" resultType="Address">
		select aid,aname from address where aid = #{aid}
	</select>	 
</mapper>

② 在N端通过association元素进行映射

	<resultMap id="myMap3" type="User" >
		<id column="uid" property="uid" jdbcType="INTEGER" javaType="int"/>
		<result column="name" property="name" jdbcType="VARCHAR" javaType="String"/>
		<result column="age" property="age" jdbcType="VARCHAR" javaType="String"/>
		<result column="sex" property="sex" jdbcType="INTEGER" javaType="int"/>
		<association column="aid" select="dao.AddressDao.selectAnameByAid" property="address" >
        <!-- column 是N端(user)查询的外键列字段名,作为select指定sql的入参 -->
		</association>
	</resultMap>
<select id="getUserN1_Step" parameterType="int" resultMap="myMap3">
		select uid,name,sex,aid
			from usertable
				where uid = #{uid}
	</select>	 

③ 延迟加载 | 懒加载

当开发者代码中调用哪个对象时才会向数据库发送sql请求

在全局配置文件中进行设置:
在这里插入图片描述

		System.out.println("----------延迟加载/懒加载----");
		User user3 = userdao.getUserN1_Step(1);
//		System.out.println(user3);
		//当直接输出对象时,因为address是它的属性,所以会立即加载
		System.out.println(user3.getName());
		//当输出的属性不涉及address时,延迟加载。
		System.out.println(user3.getAddress());
		

2. 1-N

方式一:collection元素进行赋值

① 在1端的bean中创建接收N端的集合

在这里插入图片描述

② 在1端的映射文件中创建resultMap结果集的映射

<resultMap type="Address" id="map1_N">
		<id column="aid" property="aid"/>
		<result column="aname" property="aname"/>
		<collection property="userlist" ofType="User">
			<id column="uid" property="uid" jdbcType="INTEGER" javaType="int"/>
			<result column="name" property="name" jdbcType="VARCHAR" javaType="String"/>
		</collection>
	</resultMap>
	
	
	<select id="getUserByAid" parameterType="int" resultMap="map1_N">
		select a.aid aid,aname,uid,name from address a, usertable u
		where a.aid = u.aid and a.aid = #{aid}
	</select>
方式二:分步查询
<resultMap type="Address" id="map1_N_Step">
		<id column="aid" property="aid"/>
		<result column="aname" property="aname"/>
		<!-- 把1端的某个字段作为参数值传入N端作为N端的入参 -->
		<collection property="userlist" ofType="User"
					column="aid" select="dao.UserDao.getUserByAid" >
		</collection>
	</resultMap>

	<select id="getAnameByAid" parameterType="int" resultMap="map1_N_Step">
		select aid,aname from address
		where aid = #{aid}
	</select>
		<resultMap id="myMap4" type="User" >
		<id column="uid" property="uid" jdbcType="INTEGER" javaType="int"/>
		<result column="name" property="name" jdbcType="VARCHAR" javaType="String"/>
	</resultMap>
	<select id="getUserByAid" parameterType="int" resultMap="myMap4">
		select uid,name from usertable 
				where aid = #{aid}
	</select>	

注意:映射文件中的sql元素需要和接口中的方法名要一致,mybatis是通过接口的动态代理去调用sql元素

懒加载策略和N-1中的一致

分步查询中传递多个参数:

把1端的多个元素作为查询的条件

在这里插入图片描述

延迟加载策略属性:

在这里插入图片描述

3. Discriminator鉴别器

根据得到的某个参数值,不同的值/情况将会有不同的动作,其实就是if/else

在这里插入图片描述

动态sql

动态sql可以灵活的根据业务逻辑条件自动组装最终执行的sql语句

OGNL:对象图导航语言,object.name

先附上测试:

public static void main(String[] args) {

		String resource = "configuration.xml";
		SqlSession session = GetSqlSession.getSqlSession(resource);
		
		UserDao userDao = session.getMapper(UserDao.class);
		User user = new User(0, "张%", "45", 1);
		
//		System.out.println("----------动态sql:if/choose-----------");
//		List<User> userlist = userDao.getUser_if_choose(user);
//		for(User u : userlist) {
//			System.out.println(u);
//		}
		
//		System.out.println("----------动态sql:where/trim-----------");
//		List<User> userlist1 = userDao.getUser_where_trim(user);
//		for(User u : userlist1) {
//			System.out.println(u);
//		}
		
//		System.out.println("----------动态sql:set-----------");
//		User user1 = new User(9, "王五", "45", 0);
//		int i = userDao.updateUser_set(user1);
//		System.out.println(i);
		
		System.out.println("----------动态sql:foreach-----------");
		List<Integer> list = Arrays.asList(1,2,4,5,9);
		List<User> userlist2 = userDao.getUser_foreach(list);
		for(User u : userlist2) {
			System.out.println(u);
		}
		session.close();

	}

1. if

​ test是条件,特殊字符用转义字符来写,&—>& “”

2. choose

从多个选项中选择一个值,类似switch…case

子标签:when otherwise

	<select id="getUser_if_choose" resultType="User">
		select <include refid="commonsql"></include> from usertable
			 where 1 = 1
		<!-- 
		<if test="name != null &amp;&amp; name.trim() != &quot;&quot;">
			 and name like #{name}
		</if>
		<if test="age != 0">
			and sex = #{sex}
		</if>
		 -->
		 <choose>
		 	<when test="name != null &amp;&amp; name.trim() != &quot;&quot;">
		 		and name like #{name}
		 	</when>
		 	<when test="age != 0">
		 		and sex = #{sex}
		 	</when>
		 	<otherwise>
		 		and age = #{age}
		 	</otherwise>
		 </choose>
	</select>

3. where

4. trim

注意:prefix(加前缀),suffix(加后缀), prefixOverrides(去掉首个…),suffixOverrides(去掉最后的…)

<select id="getUser_where_trim" resultType="User">
		select <include refid="commonsql"></include>
			from usertable
			<!-- 会自动加上where关键字,并且去除where后的第一个条件连接关键字(and/or)
				<where>
					<if test="name != null &amp;&amp; name.trim() != &quot;&quot;">
						 and name like #{name}
					</if>
					<if test="age != 0">
						and sex = #{sex}
					</if>
				</where>
			 -->
			 <trim prefix="where" prefixOverrides="and">
			 	<if test="name != null &amp;&amp; name.trim() != &quot;&quot;">
					 and name like #{name}
				</if>
				<if test="age != 0">
					and sex = #{sex}
				</if>
			 </trim>
	</select>

5. set

	<update id="updateUser_set">
		update usertable
		<set>
			<if test="name != null &amp;&amp; name.trim() != &quot;&quot;">
				name = #{name},
			</if>
			<if test="age != 0">
				age = #{age},
			</if>
		</set>
		where uid = #{uid}
	</update>

使用trim替换set实现:

在这里插入图片描述

6. foreach

接口中的参数可以是集合或数组类型,MyBatis会把参数自动的封装成Map对象,其中List对象的key是“list”,数组对象的key是”array”。

<select id="getUser_foreach" resultType="User">
	select <include refid="commonsql"></include>
		from usertable where uid in 
		<foreach collection="list" open="(" separator="," close=")" index="index" item="item">
			#{item}			
		</foreach>
</select>

批量保存:
在这里插入图片描述

7. bind标签

把某一个参数值绑定到上下文中的一个变量中,可以在sql中重复使用

在这里插入图片描述

8. Sql片段

在这里插入图片描述

MyBatis内置参数

在这里插入图片描述

特殊字符处理

在这里插入图片描述

MyBatis的缓存

MyBatis中默认的缓存有两级缓存,分别是一级缓存和二级缓存

在这里插入图片描述

一级缓存LocalCaching

与数据库在同一次会话期间所查询的数据会自动缓存到一级缓存中(本地缓存),如果后续对相同数据的查询,那么就会直接从本地缓存中进行获取,就不会再去查询数据库了。

		String resource = "configuration.xml";
		SqlSession session = GetSqlSession.getSqlSession(resource);
		//注意是同一个session
		UserDao userDao = session.getMapper(UserDao.class);
		//首次查询的结果会放入一级缓存中
		User user = userDao.selectUser(1);
		System.out.println(user);
		//第二次查询相同的数据时就直接从以及缓存中获取
		User user1 = userDao.selectUser(1);
		System.out.println(user1);
		System.out.println(user==user1);
		session.close();

在这里插入图片描述

二级缓存CachingExecutor

① 二级缓存介绍

在这里插入图片描述

import java.io.IOException;
import java.io.Reader;
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 bean.User;
import dao.UserDao;

public class TestGlobalCache {

	public static void main(String[] args) {

		String resource = "configuration.xml";
		Reader reader = null;
		try {
			reader = Resources.getResourceAsReader(resource);
		} catch (IOException e) {
			e.printStackTrace();
		}
		SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
		SqlSession session = ssf.openSession(true);
		UserDao userDao = session.getMapper(UserDao.class);
		//首次查询的结果放在一级缓存里
		User user = userDao.selectUser(1);
		System.out.println(user);
		//关闭session,会把一级缓存里的内容转移到二级缓存里
		session.close();
		
		SqlSession session1 = ssf.openSession(true);
		UserDao userDao1 = session1.getMapper(UserDao.class);
		//查找: 先二级缓存,在一级缓存,最后DB
		User user1 = userDao1.selectUser(1);
		System.out.println(user1);
		System.out.println(user==user1);//true
		session1.close();

	}

}

SqlSessionFactory要是同一个!!!

③ 二级缓存的运行过程
在这里插入图片描述

第三方缓存接口Ehcache

MyBatis主要是处理ORM的业务,并非专门做缓存处理的,MyBatis定义了Cache缓存接口方便开发者自定义缓存扩展,MyBatis官方提供了很多种集成缓存的Adapter适配器。

Ehcache是纯java写的缓存框架,是Hibernate中默认的缓存策略。

在这里插入图片描述

SSM框架整合

SSM主要是指spring和mybatis的整合,spring和mybatis的整合需要在mybatis官网上下载mybatis-spring.jar整合包

① 创建web工程,引入ssm的jar

② 搭建Mybatis的环境

③ 搭建SpringMVC的环境

④ 搭建Spring的环境(Spring整合MyBatis的配置)

MBG

在这里插入图片描述

MyBatis源码分析

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值