Mybatis框架学习笔记

本文详细介绍了MyBatis框架的学习笔记,包括mybatis基础、全局配置文件、映射文件、参数处理、查询相关、动态SQL、缓存机制等内容。重点讲述了接口式编程的实现、sql映射文件的编写顺序、参数处理的各种方式,以及一级和二级缓存的工作原理。通过实例展示了MyBatis如何简化SQL操作,并提供了问题解决经验。
摘要由CSDN通过智能技术生成

学习完了雷丰阳老师视频教程的Mybatis,记录一下。
有些自己的体会,在对不同资源进行整合的时候对于普通java工程项目需要自行添加对应jar包文件到路径下,然后build path,如果是maven工程只需要写依赖就会自动导入。
MyBatis提供了非常丰富的对Sql进行自定义和调整的标签及其属性,很多东西我们只需要在xml文件中定义或者添加注解,MyBatis就会自动完成其他工作,框架开发应该也是这样的发展历程,需要手写的代码会越来越少。

mybatis基础

即ibatis3.0(源于Apache)之后的版本

三层架构:
表现层—展示数据
业务层—处理业务需求
持久层—和数据库交互

-持久层技术解决方案
JDBC技术(最底层):
Connection、PreparedStatement、ResultSet
Spring的JdbcTemplate:
Spring中对jdbc的简单封装
Apache的DBUtils:
和Spring的JdbcTemplate类似
以上都不是框架,jdbc是规范,剩下两个是工具包
-封装不够细致,需要关注加载驱动、创建连接、创建Statement等繁杂过程。
-功能简单,sql语句编写在java代码里,硬编码高耦合(sql变化时需要修改源码)

框架:整体解决方案

Hibernate:全自动全映射ORM框架,旨在消除sql。但是存在开发人员无法自主优化sql语句的缺点。

mybatis是优秀的基于java持久层的框架(半自动),它内部封装了jdbc,sql与java编码分离(sql单独提取到配置文件中,由开发者控制),开发者只需要关注sql语句本身(剩下的预编译、设置参数、执行sql、封装结果由框架完成)。它使用了ORM的思想实现了结果集的封装。

ORM:Object Relational Mapping 对象关系映射
将数据库表和实体类、实体类的属性对应起来,让我们可以实现操作实体类即操作数据表

​ mybatis通过xml或注解的方式将要执行的statement(sql语句)配置起来,通过java对象 和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行 语句并将结果映射为java对象返回。

mybatis实现总结

1.全局配置文件mybatis-config.xml
包含数据源、事务管理器、运行环境的信息
2.sql映射文件EmployeeMapper.xml -->关键文件,mybatis从该文件抽取出sql
配置每个sql,以及sql的封装规则(查出相应记录后如何封装)
3.将sql映射文件注册在全局配置文件中
4.写代码(MybatisTest.java)
关键:
1)根据配置文件获得SqlSessionFactory
2)使用SqlSessionFactory获取到SqlSession对象,使用该SqlSession对象中的方法进行增删查改
一个SqlSession就是和数据库的一次会话,使用完要关闭
使用sql的唯一标识(如selectOne方法的第一个参数)来告诉mybatis执行哪个sql

接口式编程(方便开发扩展)实现总结

1.创建一个接口(EmployeeMapper.java),其中定义抽象方法
2.将EmployeeMapper.xml中的namespace改为接口的全类名
3.将标签中的"id"改为与接口中定义的抽象方法相同的方法名
4.第2、3步实现了动态绑定,在标签中写方法的具体实现
5.在测试方法中不需要创建接口的实现类,mybatis会为接口自动创建一个代理对象去执行增删改查方法

在mybatis-config.xml和EmployeeMapper.xml文件的头部标签中xxx.dtd文件是约束,规定了xml文件编写规则,联网状态下会
自动加载,按Alt+/会有编写提示

遇到的问题

1.jUnit测试始终无法找到EmployeeMapper.xml映射文件
解决:config文件夹右键->Build Path->Use as Source Folder

2.测试运行MybatisTest的test方法时报错Client does not support authentication protocol
解决:更换mysql-connector-java-xxx.jar文件的版本

全局配置文件Config.xml

将数据库的连接信息提取到dbconfig.properties文件中,放在类路径config文件夹下
然后将全局配置文件中的

<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="123456" />

修改为

<property name="driver" value="${jdbc.driver}" />
				<property name="url"
					value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />

运行测试方法,一样成功。
项目庞大时更方便维护管理配置信息。
作为了解学习,使用spring整合后spring会帮我们完成配置。

properties设置

mybatis可以使用properties标签来引入外部properties配置文件的内容。

settings设置

极为重要的调整设置,它们会改变Mybatis运行时行为。

typeAliases设置

别名处理器,可自定义java类型别名。
包含单个处理和批量处理。
批量处理可能会出现别名冲突问题(包下的类和包下的包中的类名字相同),可以使用注解@Alias("")为某个类型指定新的别名。
不使用别名,使用类型的全类名,查找类时更方便。
typeHandles:类型处理器,架起java类型和数据库类型映射的桥梁。(互相转换,String<–>CHAR/VARCHAR)

plugins设置

插件,拦截对象方法。Executor、ParameterHandler、ResultSetHandler、StatementHandler。

environments设置

environments:环境,mybatis可以配置多种环境,开发时可以定义标签的default不同值快速切换环境。

databaseIdProvider设置

用来支持多数据库厂商,在全局配置文件中添加后为各数据库起别名,在mapper.xml中标签中添加databaseId属性,即可指定该sql语句适用的数据库。
然后修改的default值可以切换运行环境

mappers设置

mappers:将写好的sql映射文件(EmployeeMapper.xml)注册到全局配置文件中

标签编写顺序

在全局配置文件中的标签有严格顺序要求:
Content Model : (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,
objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)

映射文件Mapper.xml

映射文件是mybatis的重中之重。
The true power of MyBatis is in the Mapped Statements. This is where the magic happens.

Mybatis支持增删改返回Integer、Long、Boolean类型返回值,在接口中直接在方法上中定义即可,Mybatis会自动封装

Mybatis参数处理

单个参数

​ mybatis不会做特殊处理,只有一个参数,即使参数名与bean中属性不一致,运行效果也一样。
​ #{参数名}:取出参数值。

多个参数

​ mybatis会做特殊处理,返回的多个参数会被封装成一个map。key是param1…paramN/参数的索引(0,1…)
​ value才是传入的参数值
​ #{}就是从map中获取指定key的值
​ 取值:#{param1},#{param2}
​ 多个参数建议使用命名参数,即在封装参数为map时明确指定map的key。
​ public Employee getEmpByIdAndLastName(@Param(“id”)Integer id, @Param(“lastName”)String lastName);
​ 此时#{指定的key}即可取出对应的参数值

POJO

(简单java对象,简单JavaBean)
如果多个参数正好是业务逻辑的数据模型(传入的参数是Employee的属性值),我们可以直接传入pojo;
#{属性名}:取出传入的pojo的属性值

Map

​ 如果不是业务逻辑的数据模型,没有对应的pojo,不经常使用,为了方便也可以直接传入map
​ #{key}:取出map中对应的值

TO

(DTO,可以理解为写一个新的、继承原来model层实体类、添加新的业务处理方法、专注于数据传输的类)
如果不是业务逻辑的数据模型,但是该方法要经常使用,推荐来编写一个TO(Transfer Object)即数据传输对象
Page{
int index;
int size;
}

表现层与应用层之间是通过数据传输对象(DTO)进行交互的,数据传输对象是没有行为的POCO对象,它 的目的只是为了对领域对象进行数据封装,实现层与层之间的数据传递。为何不能直接将领域对象用于 数据传递?因为领域对象更注重领域,而DTO更注重数据。不仅如此,由于“富领域模型”的特点,这样 做会直接将领域对象的行为暴露给表现层。

需要了解的是,数据传输对象DTO本身并不是业务对象。数据传输对象是根据UI的需求进行设计的,而不 是根据领域对象进行设计的。比如,Customer领域对象可能会包含一些诸如FirstName, LastName, Email, Address等信息。但如果UI上不打算显示Address的信息,那么CustomerDTO中也无需包含这个 Address的数据。

参数处理扩展思考

一些应用场景

public Employee getEmp(@Param("id")Integer id, String lastName);

​ 取值:id==>#{id/param1} lastName==>#{param2}

public Employee getEmp(Integer id, @Param("e")Employee emp);

​ 取值:id==>#{param1} lastName==>#{param2.lastName/e.lastName}

特别注意

如果传入的是Collection(List、Set)类型或者是数组,也会特殊处理。

​ 也是把传入的list或者数组封装在map中;

​ key:Collection=>collection,List=>list,Array=>array

public Employee getEmpById(List<Integer> ids);

​ 取值:取出第一个id的值==>#{list[0]}

参数值的获取

#{}:可以获取map中的值或者pojo对象属性的值

${}:也可以获取map中的值或者pojo对象属性的值

#{}和${}的区别
select id, last_name lastName, email, gender from tbl_employee
运行后:
Preparing: select id, last_name lastName, email, gender from tbl_employee where id = 5 and last_name = ?
where id = ${id} and last_name = #{lastName}

​ #{}是以预编译形式将参数设置到sql语句中;PreparedStatement:防止sql注入

​ ${}是将取出的值直接封装在sql语句中;会有安全问题

​ 大多情况下使用#{}获取参数的值

​ 原生jdbc不支持占位符的地方就可以使用${}进行取值(即sql语句不支持?的地方)

​ 如:select * from ${year}_salary where xxx;

​ select * from tbl_employee order by ${f_name} ${order}

#{}更丰富的用法:

​ 取值的时候可以规定参数的一些规则

​ javaType、jdbcType、mode(存储过程)、numbericScale、resultMap、typeHandler、jdbcTypeName、expression(未来准备支持的功能)

​ jdbcType在某种特定场景下需要被设置,在有的数据为null的时候,有的数据库无法识别mybatis对null的默认处理。比如Oracle会报错,因为mybatis对所有的null都映射的是原生jdbc的OTHER类型,Oracle不兼容该类型。

​ 由于全局配置中,jdbcTypeForNull=OTHER,Oracle不支持。两种解决办法:

​ 1.修改为#{email, jdbcType=NULL},表示为空时设置为NULL类型,运行成功。

​ 2.修改全局配置中jdbcTypeForNull=NULL。

总结

参数多时会封装map,为了不混乱可以使用注解@Param(“xxx”)来指定封装时哪个属性是key

#{xxx}就可以取出map中指定的值

查询相关

1.查询返回List集合

public List<Employee> getEmpsByLastNameLike(String lastName);

resultType:如果返回的是一个集合,要写集合中元素的类型

 <select id="getEmpsByLastNameLike" resultType="com.bean.Employee">
 	select * from tbl_employee where last_name like #{
   lastName}
 </select>

2.查询返回Map集合

返回一条记录的Map

key就是列名,value就是对应的值

public Map<String, Object> getEmpByIdReturnMap(Integer id);

<select id="getEmpByIdReturnMap" resultType="map">
 	select * from tbl_employee where id = #{
   id}
 </select>
返回多条记录的Map

返回多条记录封装成一个map,key是这条记录的主键,value是记录封装后的JavaBean

@MapKey("id")//用注解告诉mybatis封装这个map的时候用哪个属性值作为主键
public Map<Integer, Employee> getEmpByLastNameLikeReturnMap(String lastName);
 <select id="getEmpByLastNameLikeReturnMap" resultType="com.bean.Employee">
 	select * from tbl_employee where last_name like #{
   lastName}
 </select>

3.resultMap自定义javaBean的封装规则

Mapper.xml文件中的select标签中resultType和resultMap只能二选一

<!-- 自定义某个javaBean的封装规则 
 		type:自定义规则的java类型
 		id:唯一id方便引用
 	-->
 	<resultMap type="com.bean.Employee" id="MyEmp">
 		<!-- 指定主键列的封装规则 
 			用id定义主键会有底层优化,也可以使用result
 			column:指定哪一列
 			property:指定对应的javaBean属性
 		-->
 		<id column="id" property="id"/>
 		<!--
  • 15
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值