Mybatis的使用及原理

本文深入探讨MyBatis框架的使用方法,包括配置、参数传递、动态SQL、缓存机制等核心功能,以及如何整合第三方组件提升应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1).MyBatis
处理JDBC和数据的一个框架(Dao层的)
1.需要导入3个jar包
log4j.jar : 日志包,可以在控制台看到使用的SQL语句,占位符的值,受影响的行数
需要配置log4j.xml并把下面代码拷贝

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

<log4j:configuration
xmlns:log4j=“http://jakarta.apache.org/log4j/”>

<appender name="STDOUT"
	class="org.apache.log4j.ConsoleAppender">
	<param name="Encoding" value="UTF-8" />
	<layout class="org.apache.log4j.PatternLayout">
		<param name="ConversionPattern"
			value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
	</layout>
</appender>
<logger name="java.sql">
	<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
	<level value="info" />
</logger>
<root>
	<level value="debug" />
	<appender-ref ref="STDOUT" />
</root>

</log4j:configuration>

DEBUG 09-28 19:57:39,176 ==> Preparing: select id ,last_name lastName ,email ,gender from employee where id = ? (BaseJdbcLogger.java:145) 使用的SQL语句
DEBUG 09-28 19:57:39,214 > Parameters: 1(Integer) (BaseJdbcLogger.java:145) 占位符的值
DEBUG 09-28 19:57:39,266 <
Total: 1 (BaseJdbcLogger.java:145) 受影响的行数/返回结果集个数

		mybatis-3.4.1.jar  :   使用MyBatis必须导入的包
			创建mybatis-config.xml配置文件并拷贝下面代码
<?xml version="1.0" encoding="UTF-8" ?>
<!-- mybatis全局配置 -->
<environments default="development">
	<environment id="development">
		<transactionManager type="JDBC" />
		
		<dataSource type="POOLED"> 
          <!-- driver:驱动全类名
                url:路径
                
          -->
			<property name="driver" value="com.mysql.jdbc.Driver" />
			<property name="url" value="jdbc:mysql://localhost:3306/javaee_0715" />
			<property name="username" value="root" />
			<property name="password" value="root" />
		</dataSource>
	</environment>
</environments>
<!-- 引入SQL映射文件,Mapper映射文件,即下面定义的xml文件名(面向接口开发) 	-->
<mappers>
	<mapper resource="EmployeeMapper.xml" />
</mappers>
		mysql-connector-java-5.1.37-bin.jar :  使用MySql数据库需要导入的包,即数据源

2).使用
Mapper面向接口开发: 以前在Dao(即数据库连接层,Interface接口层)层,DaoImpl层(实现层)需要写的
Mapper现在面向接口开发,只需要定义interface接口层即可不需要实现层,再在配置文件中配置即可

<?xml version="1.0" encoding="UTF-8" ?> window-->perfebnrences-->XML-->XML Catalog --> add
                    在key的输入栏中黏贴该地址,并把key Type设置成URI
                    在location中点击File System找到约束文件后选中即可

–>

update tbl_employee set last_name = #{lastName}, email = #{email}, gender = #{gender} where id = #{id} delete from tbl_employee where id = #{id} select id ,last_name lastName ,email ,gender from employee where id = #{id}
	在java类中
     //导入配置文件
     String resource = "mybatis-config.xml";
     //获取输入流
	InputStream inputStream = Resources.getResourceAsStream(resource);
	//获取sqlSession工厂(Factory:工厂)
	SqlSessionFactory sqlSessionFactory = 
			new SqlSessionFactoryBuilder().build(inputStream);
     //获取sqlSession对象
	SqlSession session = sqlSessionFactory.openSession();
     //获取Dao层对象(因为使用了面向接口开发,所以不用实现类)
	EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
	//调用该接口类的方法
	Employee employee = mapper.selectEmployeeById(1);

	细节:  使用后记得关闭资源(调用其.close()方法)
		使用面向接口开发时,在配置mybatis的mappers属性时,不应该在使用mapper属性,而应该使用packge
		且,接口类的属性文件应该何其放在同一个包中

3).配置MyBatis时的其他属性
configuration:
1.properties:做一些属性的配置,引入属性文件(配置文件,例如jdbc的一些属性)
resource: 引入类路径下的资源文件
url : 引入网路路径或者是磁盘路径下的资源文件


		2. settings : 包含很多重要的设置项.
     <settings>
 	<!-- 映射下划线到驼峰命名 -->
 	<setting name="mapUnderscoreToCamelCase" value="true"/>
            <!-- 开启延迟加载 -->
 	<setting name="lazyLoadingEnabled" value="true"/>
 	<!-- 全部加载 还是按需加载 -->
 	<setting name="aggressiveLazyLoading" value="false"/>
 </settings>

		3. typeAliases : 别名处理 
			typeAlias: 给单个的java类型取别名,默认别名就是 简单类名, 不区分大小写. 
			package: 为指定包以及子包下的所有的类取默认的别名.
					 如果有别名冲突的情况,使用@Alias来给某个类取别名. 
    <typeAliases>
	<!-- <typeAlias type="com.atguigu.mybatis.beans.Employee" alias="employee"/> -->
	<package name="com.atguigu.mybatis.beans"/>
</typeAliases>

		4. environments :  环境的配置。 MyBatis支持配置多个环境. 
				default: 指定当前使用的环境. 
			environment: 具体的环境配置
	   			id: 唯一标识
				transactionManager : 事务管理
					JDBC  :  JdbcTransactionFactory
					MANAGED :ManagedTransactionFactory
					最终: 将事务管理交给Spring完成. 
				dataSource: 数据源	
					UNPOOLED :UnpooledDataSourceFactory
					POOLED   :PooledDataSourceFactory
					JNDI     :JndiDataSourceFactory 
					最终: 将数据源交给Spring管理. 
				
	   		Configuration类中查看别名的注册情况. 
	<environment id="development">
		<transactionManager type="JDBC" />
		<dataSource type="POOLED">
			<property name="driver" value="${jdbc.driver}" />
			<property name="url" value="${jdbc.url}" />
			<property name="username" value="${jdbc.username}" />
			<property name="password" value="${jdbc.password}" />
		</dataSource>
	</environment>
	
	<!-- <environment id="test">
		<transactionManager type=""></transactionManager>
		<dataSource type=""></dataSource>
	</environment> -->
	
</environments>

		5. mappers 引入SQL映射文件
	 		mapper: 引入单个的SQL映射文件
	 		package: 引入指定包下的所有的映射文件
	 				 要求: Mapper接口 与 SQL映射文件同名同位置 
     <mappers>
	<!-- <mapper resource="EmployeeMapper.xml" /> -->
	<package name="com.atguigu.mybatis.dao"/>
</mappers>

4).参数传递
如果传递的是多个参数,Mybatis在底层要做特殊的处理. 会将传递的多个参数封装成一个Map.
1.单个参数
employeeMapper.xml


select id,last_name,email,gender from employee where id = #{id};

employeeMapper.java
//单个参数传递
public Employee getEmployeeById(Integer id);
2.多个参数
employeeMapper.xml


select id,last_name,email,gender from employee where id = #{id} and last_name = #{lastname};

		employeeMapper.java
			//多个参数
		public Employee getEmployeeByIdAndLastName(@Param("id")Integer id,@Param("lastname")					String lastname);
	3.@Param 
		基于上面而出现的注解@Param命名参数
			public Employee getEmployeeByIdAndLastName(@Param("id")Integer id
		详情参考上面代码		
	4.list
		employeeMapper.xml
			<!--list集合 public List<Employee> getEmployeeListById(Integer id); -->
			<select id="getEmployeeListById" resultType="com.china.mybatis.beans.Employee">
				select id,last_name,email,gender from employee where gender = #{id};
			</select>
		employeeMapper.java
			//获取list集合数据
			public List<Employee> getEmployeeListById(Integer id);
	5.map 一条数据返回一个map
		employeeMapper.xml
			<!--查询一条数据返回一个mappublic Map<Integer,Object> getEmployeeMapById(Integer                         id);
				注意resultType
			 -->
			<select id="getEmployeeMapById" resultType="java.util.Map">
				select id,last_name,email,gender from employee where id = #{id};
			</select>
		employeeMapper.java
			//查询一条数据返回一个map
			public Map<Integer,Object> getEmployeeMapById(Integer id);
	6.map 多条数据返回一个map
		employeeMapper.xml
			<!--查询多条数据返回一个mappublic Map<Integer,Employee> getEmployeeAllMapById						(Integer id); -->
			<select id="getEmployeeAllMapById" resultType="com.china.mybatis.beans.Employee">
				select id,last_name,email,gender from employee where gender = #{id};
			</select>
		employeeMapper.java
			//查询多条数据返回一个map
			@MapKey("id")
			public Map<Integer,Employee> getEmployeeAllMapById(Integer id);


		如果只是一条数据,则resultType属性可以设置为Map的全类名,如果为多条数据时,则resultType设置				成映射的实体类全类名,然后在mapper接口类的该方法上面添加注解@MapKey
  1. 参数获取的方式
    #{} : 单个普通类型、 多个参数、 命名参数、 POJO 、Map 、集合等.
    ${} : 单个普通类型、 多个参数、 命名参数、 POJO 、Map 、集合等
    ${}获取单个普通类型参数时,不能随便写, 必须通过 _parameter 来获取. ${_parameter}
    _parameter : 是MyBatis的内置参数. 代表传递的整个参数.
    区别: #{}是通过占位符的方式来处理. 预编译 PreparedStatement
    KaTeX parse error: Expected 'EOF', got '#' at position 51: …入的问题 建议: 优先使用#̲{}, 但是原生JDBC不支持…{}.
    select 字段1,字段2… from 表 where 条件 group by 分组字段 having 条件 order by 排序字段 desc/asc limit 分页.
    5、 自动映射 自定义映射
    1. 自动映射
      通过autoMappingBehavior =PARTIAL 来开启自动映射. 要求 结果集的列名与JavaBean的属性名一致.
      通过 mapUnderscoreToCamelCase=true 来处理下划线到驼峰命名的映射.
      开启如上两个配置, 对于单表的查询, 都可以使用自动映射来完成. 具体来说,就是在
      标签中 通过resultType来指定结果集映射的类型.
    2. 自定义映射
      a. 自定义映射用于完成复杂结果集的映射. 例如 进行多表关联查询,结果集中的列来自于多个表,最终要封装为多 个对象.
      b. 通过标签定义映射规则.
      : 用于主键列的映射.
      : 用于普通列的映射.
      : 用于完成关联属性的映射 多对一
      property: 指定关联属性名
      javaType: 指定关联属性的类型
      select: 指定要调用的查询.
      column: 指定将结果集的哪些列传递给调用的查询.
      : 用于完成集合类型的关联属性的映射. 一对多
      property: 指定关联属性名
      ofType: 指定集合中元素的类型.
      select: 指定要调用的查询.
      column: 指定将结果集的哪些列传递给调用的查询.
      c. 分步查询使用延迟加载
      在全局配置文件中的settings中加入如下两个setting:
      lazyLoadingEnabled = true : 开启延迟加载
      aggressiveLazyLoading = false : 设置全部加载还是按需加载
      d. 扩展
      分步查询多列值的传递 : 需要封装成map进行传递,语法: {k1=v1,k2=v2…}, 还需要注意的是在取值的时候必须要 使用Map中的key来取。
      fetchType :用于设置某个查询是否需要使用延迟加载. 默认值是lazy ,代表使用延迟加载。 可以设置为eager, 表示立即加载.
      6 、动态SQL
  2. MyBatis为了解决 通过一些不确定性的条件进行SQL语句的拼接操作的问题, 提供了动态SQL. 具体来说,就是提供了
    一些标签 等.
    Mybatis 基于OGNL表达式来完成标签中需要编写的表达式.
    : 完成一些基本的判断.
    : 在SQL语句中添加WHERE关键字, 去掉where后面第一个条件前面的 and / or 。
    : 在判断完的SQL语句的前后 添加内容 或者去掉指定的内容.
    :在修改的操作中, 去掉SQL语句中多出的逗号
    : 用于分支判断,最终只会满足其中的一个分支. 类似于 switch case 语句.
    : 完成循环、迭代.
  3. 基于完成批量操作:

7、 缓存机制

  1. MyBatis拥有强大的缓存机制, 提升查询效率.
  2. 一级缓存
    a. 一级缓存又叫本地缓存,默认是开启的.
    b. 一级缓存是SqlSession级别的缓存,意味着每个SqlSession对象都拥有自己的一级缓存,且相互不共享.
    c. 一级缓存的工作机制: 同一个SqlSession第一次查询数据将从数据库查询到的数据会保存到对应的一级缓存中,
    后续查询相同的数据,可以从一级缓存中直接获取,不必须要再查询数据库.
    d. 在Mybatis中,一级缓存实际上就是一个Map.
    3. 一级缓存失效的几种情况:
    a.多个SqlSession
    b.SqlSession相同, 查询条件不同
    c.SqlSession相同, 在两次查询期间执行了任意一次增删改操作。
    d.SqlSession相同, 手动清空了缓存。 session.clearCache();
  3. 二级缓存
    a. 二级缓存又叫全局缓存. 实际上二级缓存默认也是开启的。但是还需要进行其他的配置才能使用.
    b. 二级缓存是namespace级别的. 也就是基于通过一个namespace的多个SqlSession,可以共享一个二级缓存.
    c. 二级缓存使用步骤:
    在全局的配置文件中的settings中, 开启二级缓存: cacheEnabled =true
    在使用二级缓存的SQL映射文件中,配置标签
    POJO必须要实现序列化接口.
    d. 二级缓存的工作机制:
    基于同一个namespace的多个SqlSession对象,其中一个SqlSession对象第一次从数据库中将数据查到,
    会将数据保存到当前SqlSession中的一级缓存中, 该SqlSession进行提交或者是关闭操作,才会将
    一级缓存中的数据保存到二级缓存中.
    e. :
    eviction: 缓存的回收策略. LRU FIFO
    flushInterval :缓存的刷新间隔。 默认不刷新
    readOnly : 缓存的只读设置
    size: 缓存的数据个数
    type: 指定使用的缓存类.
  4. 缓存相关的设置:
    a. 全局的 cacheEnabled =true , 如果改为false,关闭了二级缓存,一级缓存可以使用。
    b. 标签中 useCache=true, 如果改为false,二级缓存不能使用,一级依旧可以使用.
    c. 标签中 flushCache=true, 会清空一二级缓存.
    标签中 flushCache=false
    d. session.clearCache(): 只会清空一级缓存.
    6. 整合第三方缓存 EhCache
    a. 加入EhCache相关的jar包: EhCache 、 整合适配包 、 日志包
    b. 加入EhCache的配置文件 ehcache.xml
    c. 在标签中通过type指定要使用的缓存类.
    7. 缓存的查找顺序: 二级缓存==> 一级缓存==> 数据库

8 、 逆向工程
1.加入逆向工程相关的jar包.
2.配置逆向工程的配置文件: mbg.xml ==> 生成的版本 、 javaBean、Mapper接口、映射文件的生成策略 、 分析的表 .
3.执行生成代码.
9、 PageHelper

  1. 加入PageHelper相关的jar包
  2. 在全局配置文件中通过 注册分页插件
  3. 在测试方法中,通过PageHelper.startPage(当前页码,每页条数)设置分页信息.
    还可以将查询到的结果 封装到 PageInfo对象中,获取更详细的分页相关的数据.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值