一款优秀持久层框架Mybatis详解!

Mybatis

ssm框架:配置文件的。最好的方式:看官方文档

1、简介

1.1、什么是Mybatis

在这里插入图片描述

  • MyBatis 是一款优秀的持久层框架.
  • 它支持定制化 SQL、存储过程以及高级映射。
  • MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
  • MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和JavaPOJO (Plain Old JavaObjects,普通老式Java对象)为数据库中的记录。
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并E改名为MyBatis.
  • 2013年11月迁移到Github。

如何获取MyBatis ?

1.2、持久化

数据持久化.

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  • 内存:断电即失.
  • 数据库(Jdbc), io文件持久化。
  • 生活:冷藏,罐头。

为什么需要需要持久化?.

  • 有一些对象,不能让他丢掉。
  • 内存太贵了

1.3、持久层

Dao层,Service层,Controller层…

  • 完成持久化工作的代码块.
  • 层界限十分明显。

1.4、为什么需要Mybatis?

  • 帮助程序猿将数据存入到数据库中。.
  • 方便.
  • 传统的JDBC代码太复杂了。简化。框架。自动化。.
  • 不用Mybatis也可以。更容易上手。技术没有高低之分
  • 有点:
    o 简单易学
    o 灵活
    o sql和代码的分离,提高了可维护性。
    o 提供映射标签,支持对象与数据库的orm字段关系映射
    o 提供对象关系映射标签,支持对象关系组建维护
    o 提供xml标签,支持编写动态sql.

最重要的一点:学习使用的人多

2、第一个Mybatis程序

思路:搭建环境–》导入Mybatis–>编写代码–》测试!

2.1、搭建环境

搭建数据库

CREATE DATABASE mybatis;
USE ‘mybatis;
CREATE TABLE user’ (
id’ INT(20) NOT NULL PRIMARY KEY,
name VARCHAR (30) DEFAULT NULL,
pwd’ VARCHAR (30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO user (id’, name, pwd) VALUES(1,'王五,‘123456’),(2.‘张三’,‘123456’),(3,‘李四’,‘123890’)

新建项目
1.新建一个maven普通项目
2.删除src目录
3.导入maven依赖

   <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

2.2、创建一个模块

  • 编写mybatis的核心配置文件
<!-- 环境:配置mybatis的环境 -->
    <environments default="development">
        <!-- 环境变量:可以配置多个环境变量,比如使用多数据源时,就需要配置多个环境变量 -->
        <environment id="development">
            <!-- 事务管理器 -->
            <transactionManager type="JDBC"/>
            <!-- 数据源 -->
            <dataSource type="">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="111111"/>
            </dataSource>
        </environment>
    </environments>
  • 编写mybatis工具类
package com.syj.utils;
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 java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {
    
    

    private static  SqlSessionFactory sqlSessionFactory;

    static {
    
    
        try {
    
    
            String resource = "org/mybatis/example/mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
    
    
        return sqlSessionFactory.openSession();
    }

}

2.3、编写代码

  • 实体类
package com.syj.entily;

import lombok.*;

@Data
@ToString
public class User {
    
    
    private int id;
    private String name;
    private String pwd;

}

  • Dao接口
package com.syj.dao;

import com.syj.entily.User;

import java.util.List;

public interface UserDao {
    
    
    List<User> getUserList();
}

  • 接口实现类由原来的UserDaoImpl转换为一个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="com.syj.dao.UserDao">
    <select id="getUserList" resultType="com.syj.entily.User">
        select * from user
    </select>
</mapper>

2.4、测试

junit测试
在这里插入图片描述
遇到的问题
1.配置文件没有注册
2.绑定接口错误
3.方法名不对
4.返回类型不对
5.Maven导出资源问题

3、CRUD

1、 namespace

namespace中的包名要和Dao/Mapper接口的包名一致!

2、 select

选择,查询语句;

  • .id:就是对应的namespace中的方法名;
  • .resultType: Sql语句执行的返回值!.
  • parameterType : 参数类型!

1.编写接口

//根据Id查询用户
User getUser(User user)

2.编写对应的Mapper中的Sql语句

<select id="getuserById" parameterType="int" resultType="com. kuang. pojo.user">
	select * from mybatis.user where id = #{id}
</select>

3.测试

@Test
public void getuserById( 
Sqlsession sqlsession = Mybatisutils.getsqlsession ();
usermapper mapper = sqlSession. getMapper (userMapper.class);
User user = mapper. getuserById (1);
system.out.println (user);
sqlSession.close();
}

3、Insert

在这里插入图片描述

4、Update

在这里插入图片描述

5、Delete

在这里插入图片描述
注意:

  • 增删改需要提交事务!

6、分析错误

  • .标签不要匹配错resource 定mapper,需要使用路径!
  • .程序配置文件必须符合规范!
  • NullPointerException,没有注册到资源!
  • 输出的xml文件中存在中文乱码问题!.
  • maven资源没有导出问题!

7、万能Map

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

8、思考题

模糊查询怎么写?
在这里插入图片描述

4、配置解析

1、核心配置文件

在这里插入图片描述

2、环境配置(environments)

在这里插入图片描述

3、属性(Properties)

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

4、类型别名typeAilases

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

5、设置

在这里插入图片描述

6、其他配置

在这里插入图片描述

7、映射器Mappers

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

8、生命周期和作用域

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里面每一个mapper,就代表一个具体业务!

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

5.1、问题

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

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

5.1、ResultMap

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

6、日志

6.1、日志工厂

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

在这里插入图片描述

6.2、Log4j

在这里插入图片描述
1.导入log4j的包

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2.log4j.properties

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.Threshold = DEBUG org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{
    
    yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{
    
    yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{
    
    yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

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

7、分页

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

在这里插入图片描述

7.2、RowBounds分页

不再使用SQL实现分页

在这里插入图片描述

在这里插入图片描述

7.3、分页插件

在这里插入图片描述

8、使用注解开发

81、面向接口编程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Mybatis详细执行流程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

8.3、CRUD

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

9、Lombok

Project Lombok是一个java库,它可以自动插入您的编辑器和构建工具,为您的java增添趣味。永远不要再编写另一个getter或equals方法,只要有一个注释,你的类就有了一个功能齐全的构建器。自动化日志变量等等。

使用步骤
1.在idea中安装Lombok插件
2.在项目中导入Lombokjar包

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>

3.在实体类加上注解即可

@NonNull
@Cleanup
@Getter/@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor
@Data
@Value
@SneakyThrows
@Synchronized
@Log

@Data:无参构造, get, set, tostring, hashcode, equals
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter  @Setter

10、多对一处理(关联查询)

多对一:
在这里插入图片描述

  • 多个学生,对应一个老师
  • 对于学生这边而言,关联…多个学生,关联一个老师 【多对一】
  • 对于老师而言,集合,一个老师,有很多学生【一对多】
    在这里插入图片描述

测试环境搭建

1.导入Lombok
2.新建实体类Teacher,Studnet
3.建立mapper接口
4.建立mapper.xml文件
5.在核心配注册我们的Mapper接口或者文件【方式很 随心选择】
6.测试查询是否成功

按照查询嵌套处理(子查询)

实体类

@Data
public class Teacher{
    
    
	private int id;
	privite String name;
}
@Data
public class Student{
    
    
	private int id;
	privite String name;
	//学生需要关联一个老师
	privite Teacher teacher;
}

在这里插入图片描述

在这里插入图片描述

按照结果嵌套处理(联表查询)

在这里插入图片描述
回顾Mysql多对一查询方式

  • 子查询
  • 联表查询

11、一对多处理

比如:一个老师拥有很多学生
对于老师而言,就是一对多
实体类

@Data
public class Student{
    
    
	private int id;
	privite String name;
	private int tid;
}
@Data
public class Teacher{
    
    
	private int id;
	privite String name;
	//一个老师拥有多个学生
	privite List<Student> Students
}

在这里插入图片描述

按照结果嵌套处理
在这里插入图片描述

按照查询嵌套处理
在这里插入图片描述

小结

1.关联:association 多对一
2.集合:collection 一对多
3.javaType & ofType

  1. JavaType用来指定实体类中属性的类型
  2. ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!

注意点
.保证SQL的可读性,尽量保证通俗易懂
.注意一对多和多对一中,属性名和字段的问题!
.如果问题不好排查错误,可以使用日志,建议使用Log4j

面试高频.
Mysql引擎
.InnoDB底层原理
索引
.索引优化!

12、动态SQL

什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句
利用动态SQL这一特性可以彻底摆脱这种痛苦。
在这里插入图片描述

搭建环境

在这里插入图片描述

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

IF

在这里插入图片描述

Choose(when,otherwise)

在这里插入图片描述

trim(where,set)

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

所谓的动态SQL, 本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码
if
where, set, choose , when

Foreach

SQL片段

有的时候,我们可能会将一些功能的部分抽取出来,方便复用!
1.使用SQL标签抽取公共的部分
在这里插入图片描述

2.在需要使用的地方使用Include标签引用即可
在这里插入图片描述
注意事项:

  • .最好基于单表来定义SQL片段!
  • .不要存在where标签
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了
    建议:.
    现在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可!

13、缓存

13.1、简介

在这里插入图片描述
1.什么是缓存[Cache ]?
০存在内存中的临时数据。
০将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。

2.为什么使用缓存?
০减少和数据库的交互次数,减少系统开销,提高系统效率。

3.什么样的数据能使用缓存?
০经常查询并且不经常改变的数据。

13.2、Mybatis缓存

  • MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。.
  • MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存。
    o 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)。
    o 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。。
    o 为了提高扩展性, MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

13.3、一级缓存

  • 一级缓存也叫本地缓存:。
    o 与数据库同一次会话期间查询到的数据会放在本地缓存中。。
    o 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;加粗样式

测试步骤:
1.开启日志!
2.测试在一个Sesion中查询两次相同记录
3.查看日志输出
在这里插入图片描述

缓存失效的情况:
1.查询不同的东西
2.增删改操作,可能会改变原来的数据,所以必定会刷新缓存!
在这里插入图片描述
3.查询不同的Mapper.xml
4.手动清理缓存!
在这里插入图片描述

小结:

  • 一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!
  • 一级缓存就是一个Map.

13.4、二级缓存

  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存.
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;.
  • 工作机制。
    o 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;。
    o 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;。
    o 新的会话查询信息,就可以从二级缓存中获取内容;。
    o 不同的mapper查出的数据会放在自己对应的缓存(map)中;

在这里插入图片描述
小结:.

  • 只要开启了二级缓存,在同一个Mapper下就有效.
  • 所有的数据都会先放在一级缓存中;.
  • 只有当会话提交,或者关闭的时候,才会提交到二级缓冲中!

缓存原理

在这里插入图片描述

13.6、自定义缓存ehcache

在这里插入图片描述
要在程序中使用ehcache,先要导包!

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.0</version>
</dependency>

ehcache.xml

在这里插入代码片

已Redis数据库来做缓存! K-V

猜你喜欢

转载自blog.csdn.net/m0_55400356/article/details/125717545