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

2023-10-28

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一款优秀持久层框架Mybatis详解! 的相关文章

  • 使用多个构造函数创建不可变类

    我正在阅读这一页 https docs oracle com javase tutorial essential concurrency imstrat html关于在 Java 中创建不可变类 并决定根据页面上概述的规范修改我正在编写的类
  • 使用 Java 编程式 HTML 文档生成

    有谁知道如何在 Java 中以编程方式生成 HTMLDocument 对象 而不需要在外部生成字符串 然后使用 HTMLEditorKit read 来解析它 我问的两个原因 首先 我的 HTML 生成例程需要非常快 并且我认为将字符串解析
  • 使用 jdbc 程序连接到 Open Office odb 文件

    我编写了以下代码来连接到 OpenOffice db String db C Documents and Settings hkonakanchi Desktop Test odb Class forName org hsqldb jdbc
  • Maven + Cobertura:无法找到[您的班级]。你指定了源目录吗?

    我有 MyMath 类 有两个简单的方法 multi 和 add 和测试类只会测试多种方法 public class MainTest Test public void testMultiply MyMath tester new MyMa
  • 如何在Spring的applicationContext.xml中指定默认范围来请求范围?

    我想让所有 bean 请求默认作用域 但是 Spring 文档说默认作用域是 Singleton 第 3 4 1 和 3 4 2 节http static springsource org spring docs 2 5 x referen
  • 从 eclipse 运行时 java.io.FileNotFoundException: (没有这样的文件或目录)

    我正在写入文件并想要控制台输出 TODO Create a game engine and call the runGame method public static void main String args throws Excepti
  • 方法不必要地被调用?

    我有一个 BaseActivity 它可以通过其他所有活动进行扩展 问题是 每当用户离开 暂停 活动时 我都会将音乐静音 我也不再接听电话 问题是 onPause每当用户在活动之间切换时就会被调用 这意味着应用程序不必要地静音和停止tele
  • 删除 servlet 中的 cookie 时出现问题

    我尝试使用以下代码删除 servlet 中的 cookie Cookie minIdCookie null for Cookie c req getCookies if c getName equals iPlanetDirectoryPr
  • 如何消除警告:使用“$”而不是“.”对于 Eclipse 中的内部类

    我是 Android 开发新手 当我将 eclipse 和 Android SDK 更新到最新版本后 我收到警告 Use instead of for inner classes or use only lowercase letters
  • 如何模拟一个方面

    我目前正在使用aspectj 开发一些监控工具 因为这个工具应该是技术独立的 尽可能 所以我没有使用 Spring 进行注入 但我希望我的方面能够经过单元测试 方面示例 Aspect public class ClassLoadAspect
  • 独占锁定ConcurrentHashMap

    我知道不可能锁定 ConcurrentHashMap 进行独占访问 但是 我找不到原因 是因为构成CHM的 Segment 没有被api公开吗 据推测 如果是的话 客户端代码可以执行 交接 锁定 Cheers 我知道不可能锁定 Concur
  • 会话 bean 中的 EntityManager 异常处理

    我有一个托管无状态会话 bean 其中注入了 EntityManager em 我想做的是拥有一个具有唯一列的数据库表 然后我运行一些尝试插入实体的算法 但是 如果实体存在 它将更新它或跳过它 我想要这样的东西 try em persist
  • Vertx HttpClient getNow 不工作

    我的 vertx HttpClient 有问题 下面的代码显示使用 vertx 和纯 java 测试 GET Vertx vertx Vertx vertx HttpClientOptions options new HttpClientO
  • Java G1 GC 处理引用对象运行缓慢

    我已经在 J ava 上运行了计数器 它24小时工作 每秒点击通过100次左右 白天 GC 处理时间从 20 60 毫秒缓慢上升到 10000 60000 毫秒 然后下降到 20 60 毫秒 这种模式不时地重复 从 GC 日志中我发现 GC
  • java 属性文件作为枚举

    是否可以将属性文件转换为枚举 我有一个包含很多设置的属性文件 例如 equipment height equipment widht equipment depth and many more like this and not all a
  • 嵌入式 tomcat 7 servlet 3.0 注释不起作用

    我有一个精简的测试项目 其中包含 Servlet 版本 3 0 用注释声明 如下所示 WebServlet test public class TestServlet extends HttpServlet private static f
  • java中的比较器链

    正在阅读Oracle 关于接口的 Java 教程 https docs oracle com javase tutorial java IandI createinterface html其中给出了一个例子Card 打牌 我试图理解接口中的
  • Android 中的字符串加密

    我正在使用代码进行加密和加密 它没有给出字符串结果 字节数组未转换为字符串 我几乎尝试了所有方法将字节数组转换为字符 但没有给出结果 public class EncryptionTest extends Activity EditText
  • MySQL REPLACE 在自动递增行中

    假设我有一个 MySQL 表 其中包含三列 id a and b和名为id is an AUTO INCREMENT场地 如果我将如下查询传递给 MySQL 它将正常工作 REPLACE INTO table id a b VALUES 1
  • 如何使用 Spring AOP 建议静态方法?

    在执行类的静态方法之前和之后需要完成一些日志记录 我尝试使用 Spring AOP 来实现这一点 但它不起作用 而对于正常方法来说它起作用 请帮助我理解如何实现这一点 如果可以使用注释来完成 那就太好了 也许您应该在使用 Spring AO

随机推荐