三天学完Mybatis
【MyBatis第一天】
一、 主要内容
1. MyBatis的简介
2. MyBatis的环境搭建
3. MyBatis的框架详解
4. MyBatis中的优化处理
二、 学习目标
|
节数 |
知识点 |
要求 |
|
第一节(MyBatis的简介) |
如何理解框架 |
|
|
MyBatis框架的简介 |
|
|
|
第二节(MyBatis的环境搭建) |
搭建MyBatis环境的步骤 |
|
|
MyBatis环境搭建的意义 |
|
|
|
第三节(MyBatis环境搭建详解) |
搭建环境内容具体意义 |
|
|
第四节(MyBatis框架搭建优化) |
其他搭建优化操作 |
|
第一节 MyBatis中的简介
[1]为什么使用MyBatis
目前使用开发遇到的问题
A、每一个操作对应的使用Dao中的方法,每一个方法中都需要连接数据库,这样我们连接数据库的代码就需要写好多次
B、如果我们做的是查询的操作,从rs中取值是一个比较麻烦,而且影响开发效率的问题
解决方案:
(1)提取DBUtil工具类即可
优点:不用在每一次书写连接数据库的操作
缺点:传统的JDBC连接数据库的效率非常慢
(2)使用数据库连接池连接数据库
优点:连接数据库的速度比较快
缺点:没有办法实现SQL语句和java代码之间的解耦
(3)使用MyBatis框架
作用:[1]解决了SQL语句和java代码之间的耦合
[2]连接数据库的效率也比较快
[3]取值问题就会变得非常的简单
[2]什么是框架?
框架就是使用别人封装好的代码即可 --框架体现的形式(jar包)
(Jar API 源码)
[3]什么是MyBatis框架
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github
MyBatis是一个半自动的ORM框架
ORM: Object Relational Mapping (作用解决数据库发展和面向对象发展不一致的问题)
O:面向对象
R:关系型数据库
M:映射
半自动:myBatis框架是需要我们自己手写sql语句
MyBatis框架不依赖于服务器
第二节 MyBatis框架的搭建
01第一步 导包
mysql驱动包+mybatis的核心包+mybatis的依赖
02 书写配置mybatis.xml
|
<?xml version="1.0" encoding="UTF-8" ?>
|
03 第三步 配置FlowerMapper.xml
|
<?xml version="1.0" encoding="UTF-8" ?> |
04书写测试代码
|
public static void main(String[] args) throws IOException { |
优点:
A、连接数据库速度快
B、实现了SQL语句和JAVA代码之间的解耦
C、数据库查询取值非常的方便
第三节 MyBatis框架搭建详解
01 Jar包目录介绍
|
可以用ant编译Java类,生成class文件,ant可以把相关层架构成包 java文件解析包.spring依赖这个包 动态代理包.mybatis不需编写实现类 日志包.spring依赖这个包 字节码解析助手,处理.class文件 日志包 mybatis核心包 数据库驱动 日志
|
02配置详解
2.全局配置文件mybatis.xml
2.1 <environments default="demo">
2.1.1 default配置当前所使用的环境.值必须是<environment>的id值
2.1.2 可以有多个<environment>标签.
2.2 <environment> 声明可能使用的环境,会被< environments>引用
2.3 <transactionManager type="JDBC">
2.3.1 事务管理器类型.
2.3.2 type属性可取值:
2.3.2.1 JDBC 底层事务与JDBC原有事务管理相同
2.3.2.2 MANAGED MyBatis不去管理事务,交给其他容器进行管理.
2.4 <dataSource type="POOLED">
2.4.1 POOLED : 使用连接池技术. 访问频率比较高时使用.连接池的使用可以降低服务器压力,提高连接对象重用性
2.4.2 UNPOOLED: 不使用连接池技术.每次对数据库访问时打开数据库连接,访问结束后关闭数据库连接.
2.4.3 JNDI : java命名目录接口.数据库的连接可以依赖于其他技术或应用.
2.5 <mapper> 常用属性
2.5.1 resource="com/bjsxt/xxx.xml" 加载项目中资源,目录寻找,中间是/
2.5.2 url="" 加载互联网或本机的配置文件.示例如下:
|
<mapper url="file:///E:/FlowerMapper.xml"/> |
03 mapper.xml 中标签解释
3.1 <mapper >中namespace=""值相当于接口名
3.2 id 属性: 相当于方法名
3.3 resultType属性:返回值类型,如果返回值是集合,写集合的泛型.
3.4 parameterType属性:参数类型.如果没有参数省略该属性.
|
<select id="selAll" resultType="com.bjsxt.pojo.Flower" parameterType=""> select * from flower </select> |
04引入本地DTD文件
第一步 下载对应的DTD
直接在网络下载即可
第二步 找到Setting文件
第三步 找到DTD
第四步 引入本地DTD文件
第四节 MyBatis框架搭建优化
01配置别名
|
<typeAliases> <!--单独的给某一个文件起别名 --> <typeAlias type="com.bjsxt.pojo.Flower" alias="a"/> <!--给整个包下面的文件起别名 这时候别名的名称就是类的名称 不区分大小写--> <package name="com.bjsxt.pojo"/> </typeAliases> |
02配置Mapper(本地文件)
|
<mapper url="file:///E:/FlowerMapper.xml"/> |
03属性的名称配置
|
<properties resource="jdbc.properties"></properties> |
引入properties配置文件
A、需要明白MyBatis也是支持属性文件的读取的
B、可以让代码的结构更加的清晰
04配置settings开启log4j支持
4.1日志的作用:
A、记录错误的信息到文件中
B、有日志级别方便查看
4.2 Log4J的五种级别:
4.1 FATAL 严重错误
4.2 ERROR 错误
4.3 WARN 警告
4.4 INFO 普通信息
4.5DEBUG调试信息
4.3 DEBUG 调试信息
|
<settings> <setting name="logImpl" value="LOG4J"/> </settings> |
4.4日志文件
|
log4j.rootCategory=error, CONSOLE,LOGFILE #必须知道com.bjsxt.mapper:是namespace含义是只要是用com.bjsxt.,mapper开始的命名空间日志的级别都是debug模式,不是包名 log4j.logger.com.bjsxt.mapper=debug log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n # LOGFILE is set to be a File appender using a PatternLayout. log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=d:/axis.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n |
4.5导入步骤
[1]导入属性文件
[2]在mybatis.xml中配置日志的操作
[3]修改需要打印的日志信息
【MyBatis第二天】
一、 主要内容
1. MyBatis中的三种查询方式
2. MyBatis中的三种参数传递
3. MyBatis中增删改操作
4. MyBatis中Mapper代理方式
5. MyBatis中多参传递
6. MyBatis中SQL语句动态拼接
二、 学习目标
|
节数 |
知识点 |
要求 |
|
第一节(MyBatis中三种查询方式) |
MyBatis中查询方式A |
掌握 |
|
MyBatis中查询方式B |
掌握 |
|
|
第二节(MyBatis中三种参数传递) |
MyBatis中三种参数传递 |
掌握 |
|
第三节 (MyBatis中增删改操作) |
MyBatis中增删改 |
掌握 |
|
第四节 (MyBatis中Mapper代理) |
MyBatis中Mapper代理意义 |
掌握 |
|
第五节 (MyBatis中多参数传递) |
MyBatis中多参数传递方式 |
掌握 |
|
第六节 (MyBatis中SQL语句动态拼接) |
MyBatis中SQL动态拼接标签A |
掌握 |
|
MyBatis中SQL动态拼接标签B |
掌握 |
|
|
MyBatis中SQL动态拼接标签C |
掌握 |
第一节 MyBatis中三种查询方式
01 Mapper文件代码
|
<mapper namespace="com.bjsxt.mapper.FlowerMapper"> //Spring已经把一些常见的类型起了别名,Map对应别名是map.所以不需写全路径 |
02 测试文件
|
public static void main(String[] args) throws IOException { 总结:即根据查询想要的结果选择三种方法的调用 |
第二节 MyBatis中三种参数传递
01Mapper层代码
|
<!--方式一 public Flower selectOne2(Integer id) --> //即把参数类型定为flower,因为它本身就有多个属性 |
02测试文件
|
//【A】参数传递一 fl.setId(1); fl.setName("玫瑰花"); Flower flower = session.selectOne("com.bjsxt.mapper.FlowerMapper.selectOne2", fl); |
[1]mybatis中parameterType 这个属性可以省略的 但是 resultType 是不可以省略的
[2]#{} 相当于占位符 ${} 相当于拼接
第三节 MyBatis中增删改操作
01Mapper层代码
|
<!-- 增加操作 public int insert (Flower fl) --> |
02测试文件
|
Flower fl =new Flower(6, "随便花123",50, "支付宝"); |
提交的两种方式
[1]session.commit();
[2]SqlSession session = factory.openSession(true);
总结:Mybatis中默认事务是不提交的,所以在做完增删改操作后,要手动提交事务
第四节 MyBatis中Mapper代理方式
01Mapper 的动态代理作用
目前使用sqlsession进行增删改查的缺点:
[1] 没有办法实现多参数的传递
Flower flower=sqlSession.slectOne("com.bjsxt.mapper.FlowerMapper.selectOne2", fl); 此语句只能进行单个参数的传递
[2]书写的时候没有接口,后期的维护就比较的低 ,sqlsesssion的方式无须写接口,但不方便后期维护。
解决的方案:
Mapper的代理方式实现增删改查
02代码实现
接口代码
|
public interface FlowerMapper { |
XML中文件
|
<!--namespace:必须是接口所在的全路径-->条件是使用mapper代理方式的话 |
|
FlowerMapper mapper = sqlSession.getMapper(FlowerMapper.class); |
第五节 MyBatis中多参数传递
01接口中代码
|
//查询信息 |
02Mapper文件
|
<select id="selectOne" resultType="flower"> |
注:<package name=com.bjsxt.mapper></package>
这是一种mapper文件自动扫描的写法,前提是接口名字要跟mapper中的xml名字一样才行。
第六节 MyBatis中动态SQL
01为什么使用sql语句的动态拼接
目前学习的内容sql语句都是直接写死的,但是在实际的开发过程中很多的sql语句都是根据不同的业务情况进行不同的改变的
02 解决的方案
sql语句的动态拼接
03学习的标签
if where when set trim foreach bind include sql
04 代码实现
4.1接口代码
|
public interface FlowerMapper { |
4.2 XML文件
|
<mapper namespace="com.bjsxt.mapper.FlowerMapper"> //功能跟上面是同样的效果 |
4.3测试代码
|
// 动态SQL语句 |
代码实现二
|
public interface FlowerMapper2 { |
|
<mapper namespace="com.bjsxt.mapper.FlowerMapper2"> </mapper> |
【MyBatis第三天】
一、 主要内容
1. MyBatis中的多表查询操作
2. MyBatis中缓存
3. ThreadLocal的实现
4. MyBatis中注解支持
5. MyBatis中底层实现
二、 学习目标
|
节数 |
知识点 |
要求 |
|
第一节(MyBatis中的多表查询) |
MyBatis中业务代码查询 |
了解 |
|
MyBatis中N+1方式 |
了解 |
|
|
MyBatis中多表查询SQL |
掌握 |
|
|
第二节(MyBatis中缓存) |
MyBatis中一级缓存 |
掌握 |
|
MyBatis中二级缓存 |
掌握 |
|
|
第三节(ThreadLocal的实现) |
ThreadLocal原理 |
掌握 |
|
ThreadLocal代码实现 |
掌握 |
|
|
第四节(MyBatis中注解的支持) |
注解的使用 |
掌握 |
|
第五节(MyBatis中底层实现) |
MyBatis中底层原理 |
掌握 |
第一节 MyBatis中多表查询
01多表查询的简介
[1]多表查询的操作
学习到目前为止操作的都是一个表的增加、删除、修改、查询。在实际的开发中操作多表的情况比较多。
02 如何进行多表的查询
1、业务代码的方式
(实现的方式,书写业务逻辑的java代码实现)
查询学生所在班级的信息 (一对一查询)
1、先把所有学生查询出来(clazzno)
select* from student
2、拿着clazzno去clazz表中查询班级的信息
select * from clazz where cno=?
查询班级中所有学生的信息(一对多查询)
1、查询所有班级的信息(clazzno)
Select * from clazz
2、查询指定班级中的所有学生---List
Select * from student where clazzno=?
特点:
班级和学生之间的关系全部是靠我们书写java业务逻辑代码的方式实现的
最后执行完成SQL语句都执行了N+1次数据的查询
代码实现:
clazzMapper
studentMapper
测试代码
2、N+1查询方式
[1]什么是N+1的查询方式
如果没有N+1的方式我们想要实现多表的查询,自己书写查询的业务逻辑代码(java)
mybatis希望通过自己标签配置的方式来解决这个问题
[2]执行的操作
查询学生所在班级的信息(一对一)
查询班级中所有学生的信息(一对多)
使用的时候书写标签需要注意:
查询出来返回的是一个对象:association
查询出来返回的是一个集合:collection
总结: 业务装配方式和N+1查询方式
共同点:执行SQL语句的条数上都是N+1条语句
不同点:
业务装配方式:是我们自己书写java代码的方式进行配置的
N+1方式:通过MyBatis标签配置的方式实现的
代码实现:
StudentMapper
ClazzMapper
3、多表查询语句实现(重点)
查询所有学生所在班级的信息(一对一)
班级查询学生的操作(一对多)
遇到的问题:
查询的SQL语句非常的简单,但是如何把查询的数据接受这个就是一个问题
[1]把每一个实体中的字段拿出来组建成一个新的实体 返回还是resultType
存在的问题:映射的内容会出现重复的字段
[2] resultMap:映射的操作
代码实现:
StudentMapper.xml
ClazzMapper.xml
4、Auto_Mapping
数据注入的方式
[1]自动注入方式 Auto_Mapping (自己封装的实体属性和数据库的字段是一样的情况Mybatis会自动的注入)
[2]手动注入的方式 resultMap
作用:解决自己做的实体的封装和数据库的字段不一致的问题
5、resultType和resultMap使用场景
[1]如果你做的是单表的查询并且封装的实体和数据库的字段一一对应 resultType
[2]如果实体封装的属性和数据库的字段不一致 resultMap
[3]使用的是多表的联合查询 resultMap
[4]使用N+1查询的时候 resultMap
第二节 MyBatis中的缓存
01 Mybatis中的缓存简介
缓存的好处:只是查询才有缓存 (增删改没有缓存的),可以增快访问的速度
sqlsession级缓存 (一级缓存) 默认开启的
所有的操作是公用同一个SQLsession对象并且执行的是同一条SQL语句的时候才会走缓存
02缓存的缺点
可能存在数据的脏读
执行修改、删除、添加 默认的把缓存中数据全部清空
03问题
不同的用户访问的时候创建了不同的sqlsession对象 ,这个时候我们缓存的数据没有办法实现共享
04sqlsession一级缓存,mybatis默认是打开的,二级缓存需要手动设置
使用SqlSession对象操作数据库资源时,SqlSession对象会先去其缓存区查找是否有现成的符合要求的数据,如果有则返回,没有则按照需求进行数据库操作获取符合要求的资源,并将资源返回给用户的同时在其缓存中缓存,当我们使用同一个SqlSession对象操作同一个Sql资源时,就可以从缓存中直接获取数据库资源数据了
05 factory的缓存(二级缓存)适用于同一个SqlSessionFactory对象,二级缓存为所有用户共享
使用的方法:
[1] 在Mybatis.xml中开始二级缓存 <setting name="cacheEnabled" value="true"/>
[2] 在对应的mapper.xml文件中<cache readOnly="true"></cache>
[3] 关闭获得提交指定的sqlsesson对象
注意 当用户查询时,会先在Factory对象自己的缓存中(即二级缓存)查看是否有现成的数据,有则直接返回,没有则继续查看sqlSession中(即一级缓存)是否有,有则返回,没有则去数据库中获取资源,将资源返回的同时在SqlSession的缓存中缓存一份儿,(即先保存到一级缓存中)当该SqlSession对象被commit或者close时将其缓存的数据刷入到Factory中。
查询数据顺序 二级-->一级--->数据库--->把数据保存到一级,当sqlsession关闭或者提交的时候,把数据刷入到二级缓存中
第三节 ThreadLocal
01 遇到的问题
即可能出现这样一个情况,即用户的一个请求可能会嵌套调用多个sqlsession对象,造成资源的浪费
如果我们做一个请求时候多次使用sqlsession对象这样就会造成sqlsession 浪费,也就是资源浪费,效率也会降低
我们需要达到的目的就是用户发出的一个请求中实现sqlsession的共享
即一个请求的过程中共用同一个sqlsession对象
请求没有改变,线程就不会改变
最终的目的就是在同一个线程中实现数据sqlsession的共享
02解决方案
ThreadLoacl: 作用 在同一个线程中实现数据(sqlsession)的共享
底层使用的map集合 map.put(key,value);
map.put(线程的ID,conn)
即把线程的ID以及sqlsession对象存到map集合里面,就实现了同一个线程,共用同一个sqlsession对象。即同一个请求共用同一个sqlsession对象。
03代码实现
|
1. public class DBUtil { 2. 3. private static SqlSessionFactory factory; 4. 5. private static ThreadLocal<SqlSession> tl=new ThreadLocal<>(); 6. 7. static { 8. InputStream inputStream = null; 9. try { 10. //[1]解析myBatis.xml文件 11. inputStream = Resources.getResourceAsStream("mybatis.xml"); 12. //[2]获得sqlsession工厂 13. factory=new SqlSessionFactoryBuilder().build(inputStream); 14. } catch (IOException e) { 15. e.printStackTrace(); 16. } 17. } 18. //获得sqlsession对象 19. public static SqlSession getSqlSession(){ 20. 21. //获得ThreadLoacl中的sqlsession对象 22. SqlSession sqlSession = tl.get(); 23. 24. if(sqlSession==null){ 25. 26. sqlSession = factory.openSession(true); 27. 28. //把创建好的对象放到ThreadLoacl 29. tl.set(sqlSession); 30. } 31. 32. return tl.get(); 33. } 34. 35. 36. //关闭sqlsession 37. 38. public static void closeAll(){ 39. 40. SqlSession sqlSession = tl.get(); 41. 42. if(sqlSession!=null){ 43. 44. sqlSession.close(); //sqlsession用完后要关闭 45. 46. } 47. tl.set(null); //关闭sqlsession后清空里面的对象。 48. } 49. 50. } |
第四节 MyBatis中的注解
01代码实现
|
1. @Select("select * from student") 2. List<Student> selectAll(); 3. 4. @Select("select * from student where sid=#{param1}") 5. Student selectOne(int id); 6. 7. @Insert("insert into student values(default,#{sname},#{clazzno})") 8. int insert(Student student); 9. 10. @Update("update student set sname=#{sname} where sid=#{sid}") 11. int update(Student student); 12. 13. @Delete("delete from student where sid=#{param1}") 14. int delte(int sid); |
直接在接口中的抽象方法上面写对应注解即注解sql语句,这样的话就不需要mapper.xml了。
02注解使用的优缺点
[1] 使用注解没有实现java代码和sql语句的解耦
[2] 进行多表的查询比较的麻烦
[3] 无法实现sql语句的动态拼接
第五节 MyBatis中的原理
01Mybatis的运行原理
1. 运行过程中涉及到的类
1.1 Resources MyBatis中IO流的工具类
1.1 加载配置文件
1.2 SqlSessionFactoryBuilder() 构建器
1.2.1 作用:创建SqlSessionFactory接口的实现类
1.3 XMLConfigBuilder MyBatis全局配置文件内容构建器类
1.3.1 作用负责读取流内容并转换为JAVA代码.
1.4 Configuration 封装了全局配置文件所有配置信息.
1.4.1 全局配置文件内容存放在Configuration中
1.5 DefaultSqlSessionFactory 是SqlSessionFactory接口的实现类
1.6 Transaction 事务类
16.1 每一个SqlSession会带有一个Transaction对象.
1.7 TransactionFactory 事务工厂
1.7.1 负责生产Transaction
1.8 Executor MyBatis执行器
1.8.1 作用:负责执行SQL命令
1.8.2 相当于JDBC中statement对象(或PreparedStatement或CallableStatement)
1.8.3 默认的执行器SimpleExcutor
1.8.4 批量操作BatchExcutor
1.8.5 通过openSession(参数控制)
1.9 DefaultSqlSession 是SqlSession接口的实现类
1.10 ExceptionFactory MyBatis中异常工厂
02流程图
03文字解释
在MyBatis运行开始时需要先通过Resources加载全局配置文件.下面需要实例化SqlSessionFactoryBuilder构建器.帮助SqlSessionFactory接口实现类DefaultSqlSessionFactory.
在实例化DefaultSqlSessionFactory之前需要先创建XmlConfigBuilder解析全局配置文件流,并把解析结果存放在Configuration中.之后把Configuratin传递给DefaultSqlSessionFactory.到此SqlSessionFactory工厂创建成功.
由SqlSessionFactory工厂创建SqlSession.
每次创建SqlSession时,都需要由TransactionFactory创建Transaction对象,同时还需要创建SqlSession的执行器Excutor,最后实例化DefaultSqlSession,传递给SqlSession接口.
根据项目需求使用SqlSession接口中的API完成具体的事务操作.
如果事务执行失败,需要进行rollback回滚事务.
如果事务执行成功提交给数据库.关闭SqlSession
----------------------------------------------------------------------
[1] MyBatis的基本的操作
A、mybatis框架的基本搭建
B、使用sqlSESSION对数据进行CRUD
C、使用Mapper代理方式操作CRUD
[2] myBatis中动态SQL拼接
Foreach where if bind set
[3] mybatis中多表查询
A、业务代码
B、N+1查询
C、多表查询的SQL
[4] 其他知识
A、myBatis中缓存机制
B、ThreadLoacl
C、注解的使用
D、MyBatis中运行原理

浙公网安备 33010602011771号