欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

MyBatis框架

时间:2023-07-01

目录

1、什么是MyBatis?

1.1 如何获取MyBatis

1.2 持久化

1.3 持久层

1.4 为什么需要MyBatis?

2、第一个MyBatis程序

2.1 环境搭建

2.2 创建一个模块

2.3 编写代码

2.4 测试

3、CRUD

1、编写接口

2、写sql

3、测试

4、增删改查

5、Map使用

6、模糊查询

4、配置解析

1、核心配置文件

2、配置环境(environments)

3、属性(properties)

4、类型别名(typeAliases)

5、设置

6、注册映射器(mappers)

7、生命周期和作用域(Scope)

5、解决字段和属性不一致问题

6、日志

6.1 日志工厂

6.1 LOG4J

7、分页

7.1 Limit分页

7.2 RowBounds分页

8、注解开发

9、Lombok

10、测试多对一

环境搭建

按照查询嵌套处理

按照结果嵌套处理

11、一对多

环境搭建

按照查询嵌套处理

按照结果嵌套处理

映射小结

12、动态SQL

搭建环境

if

trim(where、set)

choose、when、otherwise

sql片段

forEach

13、缓存

一级缓存

二级缓存

缓存原理


1、什么是MyBatis?

MyBatis概念:

MyBatis 是一款优秀的持久层框架。

它支持自定义 SQL、存储过程以及高级映射。

MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

MyBatis 历史:

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了[google code](Google_百度百科 code/2346604),并且改名为MyBatis 。2013年11月迁移到Github。

1.1 如何获取MyBatis

下载链接:

GitHub - mybatis/mybatis-3: MyBatis SQL mapper framework for Java

maven:导入依赖

org.mybatis mybatis 3.5.9

1.2 持久化

数据持久化:

概念:持久化就是将程序的数据在持久状态和瞬时状态转化的过程。

内存:断电了就失去了。

出现过的持久化:数据库(JDBC),IO文件持久化。

持久化生活中的例子:冷藏的冰淇淋,密封猫罐头。

为什么需要持久化呢?

因为有一些对象,不能让它丢掉,其次就是内存比较昂贵。

1.3 持久层

出现过的层:Dao层,Service层,Controller层(控制)。

作用:

持久层一般指把数据保存到数据库里。完成持久化工作的代码块。层界限十分明显。

1.4 为什么需要MyBatis? MyBatis可以帮助程序员将数据存入到数据库中。方便。传统的JDBC代码太复杂。MyBatis简化,框架,自动化。不用MyBatis其实也可以。其次就是MyBatis也容易上手。

MyBatis优点:

简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。提供映射标签,支持对象与数据库的orm字段关系映射。提供对象关系映射标签,支持对象关系组建维护。提供xml标签,支持编写动态sql。使用的人多。

2、第一个MyBatis程序

2.1 环境搭建

1、搭建数据库

create database mybatis;use mybatis;create table user( id int primary key not null , name varchar(30) default null , pwd varchar(30) default null)engine=innodb charset=utf8;insert into user(id,name,pwd)values (1,'张三',123456),(2,'李四',123456),(3,'赵五',123456)

2、 新建项目

新建一个maven项目删除src目录(可选)导入maven依赖:

mysql mysql-connector-java 5.1.49 org.mybatis mybatis 3.5.9 junit junit 4.13 test

2.2 创建一个模块

1、编写mybatis核心的配置文件,连接数据库。

修改driver的值:com.mysql.jdbc.Driver

修改url的值:jdbc:mysql://localhost:3306/数据库名?useSSL=true&useUnicode=true&characterEncoding=UTF-8

修改username:root

修改password:123456

2、编写mybatis工具类。

// sqlSessionFactory(sql工厂模式) -->sqlSessionpublic class MyBatisUtils { private static SqlSessionFactory sqlSessionFactory; static { // 使用mybatis的第一步,获取sqlSessionFactory对象 try { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } // 既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。 // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。 public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); // 优化后的 }}

2.3 编写代码

编写实体类:

package com.lei.pojo;// 实体类public class User { private int id; private String name; private String pwd; } // 对应的有参无参构造、setter.getter方法、toString

Dao接口:

package com.lei.dao;import com.lei.pojo.User;import java.util.List;public interface UserDao { List getUserList();}

接口实现类:由原来的UserDaoImpl转换成现在的Dao/Mapper配置文件。

<?xml version="1.0" encoding="UTF-8" ?> select * from mybatis.user where id = #{id} insert into mybatis.user(id, name, pwd) values (#{id}, #{name}, #{pwd}) update mybatis.user set name=#{name}, pwd=${pwd} where id = ${id} delete from mybatis.user where id = #{id}

3、测试

@Testpublic void getUserById() { // 1、获取SqlSession对象 SqlSession sqlSession = MyBatisUtils.getSqlSession(); // getMapper 获取UserDao类, UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 通过接口来调用getUserById方法。 User userById = mapper.getUserById(1); System.out.println(userById); // 关闭资源 sqlSession.close();}@Test// CRUD的时候需要提交事务public void addUser() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.addUser(new User(4, "赵五", "123444")); // 提交事务 sqlSession.commit(); sqlSession.close();}@Testpublic void updateUser() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.upDataUser(new User(4, "依依", "123666")); sqlSession.commit(); sqlSession.close();}@Testpublic void deleteUser(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.deleteUser(3); sqlSession.commit(); sqlSession.close();}

4、增删改查

不变的三条代码:

SqlSession sqlSession = MyBatisUtils.getSqlSession(); // 获取SqlSession 对象UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 获取UserDao类sqlSession.close();// 关闭资源

4.1增删改

增删改都需要提交事务:

5、Map使用

首先:

Map在获取参数类型的时候传递一个map=parameterType="map" 直接取出key即可。

对象传递参数类型,直接在sql中取出对象的属性即可:parameterType="com.lei.pojo.User"

多个参数可以用map。

1、注册接口

// 万能的Mapint addUser2(Map map);

2、编写sql

insert into mybatis.user(id, name, pwd) values (#{idUser}, #{nameUser}, #{pwdUser})

3、测试

@Testpublic void addUser2() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map map = new HashMap();// map使用核心 map.put("idUser", 6); // 可以直接put--map的key map.put("nameUser", "nameUser"); map.put("pwdUser", "pwdUser"); mapper.addUser2(map); sqlSession.commit(); sqlSession.close();}

注意:数据库字段名和实体类的属性名要一致,如果不一致,则写相对应的名字。

6、模糊查询

测试类:

Java代码执行的时候,传递通配符%%。

List userList2 = mapper.getUserList2("%李%");

sql语句内:在sql拼接中使用通配符。

4、配置解析

解析mybatis.xml核心配置文件:

1、核心配置文件

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。

配置文档的顶层结构如下:

2、配置环境(environments)

3、属性(properties)

我们可以通过properties属性来实现引用配置文件。

概念:这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【properties】

注意点:

properties不能在xml中随便放,它是有顺序的,顺序错了就报错。

 外部配置文件dp.properties。

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
username=root
password=123456
 

 

resources中写配置文件的名称,因为通常都把外部配置文件放到与config同一个包下。在外部配置文件中也可以通过property来写配置文件。在使用配置文件的时候优先使用的是外部配置文件。

4、类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。

它仅用于 XML 配置,意在降低冗余的全限定类名书写。

第一种取别名方式:

 

第二种取别名方式:

通过包来取别名,它默认的别名就是这个包下的类的名称,首字母小写。

它会扫描pojo包下的所有类。

如果实体类较多,则使用第二种方式好。

第三种:

5、设置

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

具体的mybatis设置请参考官方文档:

配置_MyBatis中文网

cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。truefalselazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。truefalsemapUnderscoreToCamelCase是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。truefalselogImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4JLOG4J

6、注册映射器(mappers)

我们MyBatis的配置完成后,我们就可以开始定义SQL映射语句了。

首先:我们需要告诉MyBatis到哪里找到这些语句。

推荐使用以下两个映射:

1.接口和配置文件必须在同一个包下。

2.接口和配置文件必须同名。

这两个映射是写在配置文件中的:

这些配置会告诉 MyBatis 去哪里找映射文件。

写完配置文件后需要在mappers中注册绑定我们配置的Mapper文件。

这个是在核心配置文件中注册:

7、生命周期和作用域(Scope)

作用域和生命周期,是至关重要的,因为错误的使用会导致非常严重的并发问题。

mybatis流程图:

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。

它的最佳作用域:局部作用域

SqlSessionFactory

我们可以把SqlSessionFactory想象成一个:数据库连接池

SqlSessionFactory一旦被创建,那就一个在应用的运行期间一直存在,没有理由丢弃或重新创建另一个实例。

它的最佳作用域:应用作用域

最简单的就是使用单例模式或者静态单例模式。

SqlSession

SqlSession 的实例不是线程安全的,因此是不能被共享的。

所以它的最佳的作用域是:请求或方法作用域。

SqlSession用完及关,否则资源被占用。

列如:每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要。

 这里的每一个Mapper,就代表一个具体的业务!

 SqlSession可以创建多个mapper!

5、解决字段和属性不一致问题

resultMap (结果映射)

resultMap 元素是 MyBatis 中最重要最强大的元素。

ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

作用在解决字段和属性不一致问题:

起因:我们的实体类User属性名与数据库的字段名不一样。

导致查询结果:null

解决方法一:

起别名:as

select * from mybatis.user where id = #{id}

对应的:

数据库字段名实体类属性名ididnamenamepwdpassword

6、日志

6.1 日志工厂

设置(settings)

这是 MyBatis 中极位重要的调整设置,它们会改变 MyBatis 的运行时行为。

设置名描述有效值logImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J

STDOUT_LOGGING:标准日志输出

在mybatis核心配置文件中配置日志:

日志打印结果:

6.1 LOG4J

LOG4J概念:

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件。我们也可以控制每一条日志的输出格式。通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

1、导入包。

log4j log4j 1.2.17

2、log4j.properties(配置文件属性)与核心配置文件同一个包。

log4j的详细配置(最省心完美配置)_菜鸟先飞-CSDN博客_log4j配置文件

3、配置LOG4J为日志的实现。

4、log4j的使用,直接运行。

LOG4J简单使用

1、在使用LOG4J之前,导入import org.apache.log4j.Logger;包,写入配置文件。

2、日志对象,参数为当前类。

Logger logger = Logger.getLogger(UserDaoTest.class);

3、日志级别。

logger.info("info:进入了testLog4j");logger.debug("debug:进入了testLog4j");logger.error("error:进入了testLog4j");

7、分页

7.1 Limit分页

作用:减少数据的处理量。

语法:

select * from student select s.id sid ,s.name sname ,t.name tname from student as s ,teacher as t where s.tid=t.id

11、一对多 环境搭建

1、导入核心配置文件。

2、创建实体类。

@Datapublic class Teacher { private int id; private String name; private List students;}

3、创捷dao接口。

4、创建Mapper.xml对应dao接口,写好sql语法。

5、在核心配置文件中注册。

6、测试。

按照查询嵌套处理

select * from student where tid = #{tid}

按照结果嵌套处理

select * from blog where 1 = 1 and title = #{title} and author=#{author}

trim(where、set)

where 元素只会在子元素返回任何内容的情况下才插入 “WHERe” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

where:

select * from blog title = #{title} and author = #{author} and views =#{ views}

sql片段

有时候,我们可能会将一些功能的部分抽取处理,方便复用。

1、使用sql标签抽取公共的部分:

title = #{title}, author = #{author}

2、在需要使用的地方使用include标签引用即可:

select * from blog id = #{id}

测试代码

通过xml映射,在测试类里,写好三步骤,和HashMap。

然后创建一个数组,把id取值(1,2,3)存到ids中,最后把ids存到HashMap中,通过查询map,来便利的查到的数据。

ids是foreach标签中的collection。

@Testpublic void test4(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); HashMap map = new HashMap(); ArrayList ids = new ArrayList(); // 把ids存到ArrayList数组中 ids.add(1); ids.add(2); ids.add(3); map.put("ids",ids); // 把ids存放到HashMap中 List blogs = mapper.queryBlogForEach(map); for (Blog blog : blogs) { System.out.println(blog); } sqlSession.close();}

13、缓存

什么是缓存呢?

缓存就是用户存入的数据,那数据就存放到一个地方,那个地方就是缓存。缓存解决了高并发系统的性能问题。还提升了查询效率。

为什么使用缓存?

目的:减少和数据库的交互次数,减少系统开销,提高系统效率。

什么样的数据库使用缓存?

数据经常查询,且不经常改变的数据,就使用缓存。

缓存还分为两级:

一级缓存

一级缓存是默认开启的。

相当于测试类里面的一个测试结果,从sqlSession中查询结果,最后关闭sqlSession,就是一级缓存,因为数据只在这个测试期间使用,用完就关闭了。

二级缓存

二级缓存也叫全局缓存,因为一级缓存作用域太低了,所以诞生的二级缓存。

只有将会话关闭后,或提交,才会到二级缓存中。

二级缓存也可以看成基于xml配置文件中的namespace 一个名称空间,对应一个二级缓存 ,因为这个缓存存在于,整个xml的使用中。

工作机制:

一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中。如果当前会话关闭了,这个会话对应的一级缓存就没了,但是我们想要的是,会话关闭后,一级缓存中的数据被保存到二级缓存中。新的会话查询信息,就可以从二级缓存中获取内容。不同的mapper查出的数据就会放在自己对应的缓存(map)中。

二级缓存表现形式:

我们使用一级缓存查询两遍同样的数据。那么会查到两遍同样的数据,当我们把二级缓存打开时,我们再进行查询,这时候我们的一级缓存不是被提交了吗,或关闭了,这时候查出来的数据就只有一遍。

1.开启全局缓存

在核心配置文件中设置开启二级缓存:

2.在配置文件中设置二级缓存:

也可以自定义二级缓存

这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

缓存原理

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。