2024年Mybatis框架技术总结(二),阿里P8Java架构师谈

面试准备+复习分享:

为了应付面试也刷了很多的面试题与资料,现在就分享给有需要的读者朋友,资料我只截取出来一部分哦

秋招|美团java一面二面HR面面经,分享攒攒人品

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

//第二页:显示3条数据

PageHelper.startPage(3,3);

//6.处理结果

for(Student student:list){

System.out.println(student);

}

}

1.4、分页插件的参数获取


public void selectPaging() throws Exception{

//1.加载核心配置文件

InputStream is = Resources.getResourceAsStream(“MyBatisConfig.xml”);

//2.获取SqlSession工厂对象

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

//3.通过工厂对象获取SqlSession对象

SqlSession sqlSession = sqlSessionFactory.openSession(“true”);

//4.获取StudentMapper接口的实现类对象

StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

//5.调用实现类的方法,接受结果

List list = mapper.selectAll();

//其他分页的数据

PageInfo pageInfo = new PageInfo<>(list);

System.out.println(“总条数:”+pageInfo.getTotal());

System.out.println(“总页数:”+pageInfo.getPages());

System.out.println(“当前页:”+pageInfo.getPageNum());

System.out.println(“每页显示条数:”+pageInfo.getPageSize());

System.out.println(“上一页:”+pageInfo.getPrePage());

System.out.println(“下一页:”+pageInfo.getNextPage());

System.out.println(“是否第一页:”+pageInfo.isIsFirstPage());

System.out.println(“是否最后一页:”+pageInfo.isIsLastPage());

//6.处理结果

for(Student student:list){

System.out.println(student);

}

}

1.5、分页插件小结


分页:可以将很多条结果进行分页显示。

  • 分页插件 jar 包: pagehelper-5.1.10.jar jsqlparser-3.1.jar

  • <plugins>:集成插件标签。

  • 分页助手相关 API

​ 1.PageHelper:分页助手功能类。

  1. startPage():设置分页参数

  2. PageInfo:分页相关参数功能类。

  3. getTotal():获取总条数

  4. getPages():获取总页数

  5. getPageNum():获取当前页

  6. getPageSize():获取每页显示条数

  7. getPrePage():获取上一页

  8. getNextPage():获取下一页

  9. isIsFirstPage():获取是否是第一页

  10. isIsLastPage():获取是否是最后一页

2、Mybatis多表操作

===============================================================================

2.1、多表模型介绍


我们之前学习的都是基于单表操作的,而实际开发中,随着业务难度的加深,肯定需要多表操作的。

  • 多表模型分类

  • 一对一:在任意一方建立外键,关联对方的主键。

  • 一对多:在多的一方建立外键,关联一的一方的主键。

  • 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。

2.2、多表模型一对一操作


  1. 一对一模型: 人和身份证,一个人只有一个身份证

  2. 代码实现

  • 步骤一: sql语句准备

CREATE TABLE person(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(20),

age INT

);

INSERT INTO person VALUES (NULL,‘张三’,23);

INSERT INTO person VALUES (NULL,‘李四’,24);

INSERT INTO person VALUES (NULL,‘王五’,25);

CREATE TABLE card(

id INT PRIMARY KEY AUTO_INCREMENT,

number VARCHAR(30),

pid INT,

– 银行卡表的pid指向person表中的主键id

CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id)

);

INSERT INTO card VALUES (NULL,‘12345’,1);

INSERT INTO card VALUES (NULL,‘23456’,2);

INSERT INTO card VALUES (NULL,‘34567’,3);

  • 步骤二:实体类和接口

public class Person{

private Integer id; //主键id

private String name; //人的姓名

private Integer age; //人的年龄

//省略get/set,有参/无参方法

}

public class Card{

private Integer id; //主键id

private String number; //身份证号

private Person p; //所属人的对象

//省略get/set,有参/无参方法

}

public interface OneToOneMapper{

//查询全部

public abstract List selectAll();

}

  • 步骤三:配置文件
<?xml version="1.0" encoding="UTF-8" ?>

SELECT c.id cid,number,pid,NAME,age FROM card c,person p WHERE c.pid=p.id

  • 步骤四:在MyBatisConfig.xml中引入配置文件

  • 步骤五:测试类

@Test

public void selectAll() throws Exception{

//1.加载核心配置文件

InputStream is = Resources.getResourceAsStream(“MyBatisConfig.xml”);

//2.获取SqlSession工厂对象

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

//3.通过工厂对象获取SqlSession对象

SqlSession sqlSession = sqlSessionFactory.openSession(true);

//4.获取OneToOneMapper接口的实现类对象

OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);

//5.调用实现类的方法,接收结果

List list = mapper.selectAll();

//6.处理结果

for (Card c : list) {

System.out.println©;

}

//7.释放资源

sqlSession.close();

is.close();

}

2.2.1、ResultMap

  • 当涉及多表操作时,用resultMap

  • 当只是单表操作时,用resultType

  1. resultMap:用来自定义结果集和实体类的映射
  • id属性:相当于这个resultMap的唯一标识

  • type 属性:用来指定映射到哪个实体类

  1. id 标签:用来指定主键列的映射规则
  • column 属性::数据库表的列名

  • property 属性:: 对应实体类的属性名

  1. result 标签:用来指定普通列的映射规则
  • column 属性::数据库表的列名

  • property属性: : 对应实体类的属性名

  1. association标签:配置被包含对象的映射规则
  • property属性:被包含对象的变量名

  • javaType属性:被包含对象的数据类型

  1. collection标签:配置被包含集合对象的映射规则。
  • property属性:被包含集合对象的变量名

  • ofType属性:集合中保存的对象数据类型


结果集映射ResultMap

要解决的问题:属性名和字段名不一致

2.2.2、查询为null问题

  1. 例如数据库字段名

在这里插入图片描述

  1. Java中实体类设计

public class User {

private int id; //id

private String name; //姓名

private String password; //密码和数据库不一样!

//构造

//set/get

//toString()

}

  1. UserMapper接口

public interface UserMapper {

//根据id查询用户

User selectUserById(int id);

}

  1. mapper 映射文件

select * from user where id = #{id}

  1. 测试

@Test

public void testSelectUserById() {

SqlSession session = MybatisUtils.getSession(); //获取SqlSession连接

UserMapper mapper = session.getMapper(UserMapper.class);

User user = mapper.selectUserById(1);

System.out.println(user);

session.close();

}

结果

  • User{id=1,name='狂神',password='null'}

  • password 字段为空,因为实体类和数据库字段不一致,一个是pwd,一个是password

分析

  • select * from mybatis.user where id = #{id} 可以看作

  • select id,name,pwd from mybatisuser where id = #{}

  • mybatis 会根据这些查询的列名(会将列名转化为小写,数据库不区分大小写),去对应的实体类中查找相应列名的 set 方法设值,由于找不到 setPwd() ,所以password返回null

2.2.3、解决方案

方案一:为列名指定别名,别名和 java 实体类的属性名一致

select id , name , pwd as password from mybatis.user where id = #{id}

方案二:使用结果集映射 ➡ ResultMap (推荐)

select id , name , pwd from mybatis.user where id = #{id}

2.3、多表模型一对多操作


  1. 一对多模型: 一对多模型:班级和学生,一个班级可以有多个学生。

  2. sql语句准备

– 班级表

CREATE TABLE classes(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(20)

);

INSERT INTO classes VALUES (NULL,‘黑马一班’);

INSERT INTO classes VALUES (NULL,‘黑马二班’);

– 学生表的cid指向班级表的主键id

CREATE TABLE student(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(30),

age INT,

cid INT,

CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)

);

INSERT INTO student VALUES (NULL,‘张三’,23,1);

INSERT INTO student VALUES (NULL,‘李四’,24,1);

INSERT INTO student VALUES (NULL,‘王五’,25,2);

INSERT INTO student VALUES (NULL,‘赵六’,26,2);

在这里插入图片描述

  1. 实体类和接口

public class Student {

private Integer id; //主键id

private String name;//学生姓名

private Integer agel//学生年龄

//省略get/set,有参/无参方法

}

public class Classes {

private Integer id; //主键id

private String name;//班级名称

private List students; //班级中所有学生对象

}

public interface OneToManyMapper {

//查询全部

public abstract List selectAll();

}

  1. 配置文件

SELECT c.id cid,c.name cname,s.id sid,s.name sname,s.age sage FROM classes c,student s WHERE c.id=s.cid

  1. 在MyBatisConfig.xml中引入配置文件

  1. 测试类

@Test

public void selectAll() throws Exception{

//1.加载核心配置文件

InputStream is = Resources.getResourceAsStream(“MyBatisConfig.xml”);

//2.获取SqlSession工厂对象

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

//3.通过工厂对象获取SqlSession对象

SqlSession sqlSession = sqlSessionFactory.openSession(true);

//4.获取OneToManyMapper接口的实现类对象

OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);

//5.调用实现类的方法,接收结果

List classes = mapper.selectAll();

//6.处理结果

for (Classes cls : classes) {

System.out.println(cls.getId() + “,” + cls.getName());

List students = cls.getStudents();

for (Student student : students) {

System.out.println(“\t” + student);

}

}

//7.释放资源

sqlSession.close();

is.close();

}

  1. resultMap:用来自定义结果集和实体类的映射
  • id属性:相当于这个resultMap的唯一标识

  • type 属性:用来指定映射到哪个实体类

  1. id 标签:用来指定主键列的映射规则
  • column 属性::数据库表的列名

  • property 属性:: 对应实体类的属性名

  1. result 标签:用来指定普通列的映射规则
  • column 属性::数据库表的列名

  • property属性: : 对应实体类的属性名

  1. association标签:配置被包含对象的映射规则
  • property属性:被包含对象的变量名

  • javaType属性:被包含对象的数据类型

  1. collection标签:配置被包含集合对象的映射规则。
  • property属性:被包含集合对象的变量名

  • ofType属性:集合中保存的对象数据类型

2.4、多表模型多对多操作


  1. 多对多模型:学生和课程,一个学生可以选择多门课程、一个课程也可以被多个学生所选择。

  2. 代码实现

  • 步骤一:sql语句准备

CREATE TABLE course(

id INT PRIMARY KEY AUTO_INCREMENT,

NAME VARCHAR(20)

);

INSERT INTO course VALUES (NULL,‘语文’);

INSERT INTO course VALUES (NULL,‘数学’);

CREATE TABLE stu_cr(

id INT PRIMARY KEY AUTO_INCREMENT,

sid INT,

cid INT,

– sid指向学生表的主键id

– cid指向课程表的主键id

CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),

CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)

);

INSERT INTO stu_cr VALUES (NULL,1,1);

INSERT INTO stu_cr VALUES (NULL,1,2);

INSERT INTO stu_cr VALUES (NULL,2,1);

INSERT INTO stu_cr VALUES (NULL,2,2);

  • 步骤二:实体类和接口

public class Course {

private Integer id; //主键id

private String name; //课程名称

//省略get/set,有参/无参方法

}

//在学生Student实体类当中增添变量,表示当前学生选择了哪些课程

public class Student {

private Integer id; //主键id

private String name; //学生姓名

private Integer age; //学生年龄

private List courses;//学生所选择的课程集合

//省略get/set,有参/无参方法

}

public interface ManyToManyMapper {

//查询全部

public abstract List selectAll();

}

  • 步骤三:配置文件
<?xml version="1.0" encoding="UTF-8" ?>

SELECT sc.sid,s.name sname,s.age sage,sc.cid,c.name cname FROM student s,course c,stu_cr sc WHERE sc.sid=s.id AND sc.cid=c.id

  • 步骤四:在MyBatisConfig.xml中引入配置文件

  • 步骤五:测试

@Test

public void selectAll() throws Exception{

//1.加载核心配置文件

InputStream is = Resources.getResourceAsStream(“MyBatisConfig.xml”);

//2.获取SqlSession工厂对象

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

//3.通过工厂对象获取SqlSession对象

SqlSession sqlSession = sqlSessionFactory.openSession(true);

//4.获取ManyToManyMapper接口的实现类对象

ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);

//5.调用实现类的方法,接收结果

List students = mapper.selectAll();

//6.处理结果

for (Student student : students) {

System.out.println(student.getId() + “,” + student.getName() + “,” + student.getAge());

List courses = student.getCourses();

for (Course cours : courses) {

System.out.println(“\t” + cours);

}

}

//7.释放资源

sqlSession.close();

is.close();

}

2.5、总结


  • 当涉及多表操作时,用resultMap

  • 当只是单表操作时,用resultType

  1. resultMap:用来自定义结果集和实体类的映射
  • id属性:相当于这个resultMap的唯一标识

  • type 属性:用来指定映射到哪个实体类

  1. id 标签:用来指定主键列的映射规则
  • column 属性::数据库表的列名

  • property 属性:: 对应实体类的属性名

  1. result 标签:用来指定普通列的映射规则
  • column 属性::数据库表的列名

  • property属性: : 对应实体类的属性名

  1. association标签:配置被包含对象的映射规则
  • property属性:被包含对象的变量名

  • javaType属性:被包含对象的数据类型

  1. collection标签:配置被包含集合对象的映射规则。
  • property属性:被包含集合对象的变量名

  • ofType属性:集合中保存的对象数据类型

3、Mybatis缓存

=============================================================================

​ Mybatis的缓存其实就是把之前查到的数据存入内存(map),下次如果还是查相同的东西,就可以直接从缓存中取,从而提高效率。

​ Mybatis有一级缓存和二级缓存之分,一级缓存(默认开启)是sqlsession级别的缓存。二级缓存相当于mapper级别的缓存。

  • 默认情况下,只有一级缓存开启(SqlSession级别的缓存,也称为本地缓存)

  • 二级缓存需要手动开启和配置,它是基于 namespace 级别的缓存

3.1、一级缓存


  • 测试在一个Session中查询两次相同记录

@Test

public void test(){

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UerMapper.class);

User user1 = mapper.queryUserById(1);

User user2 = mapper.queryUserById(1);

System.out.println(user1==user2);

// true

sqlSession.close();

}

几种不会使用一级缓存的情况

  1. 调用相同方法但是传入的参数不同

  2. 调用相同方法参数也相同,但是使用的是另外一个SqlSession

  3. 如果查询完后,对同一个表进行了增,删改的操作,都会清空这sqlSession上的缓存

  4. 如果手动调用SqlSession.clearCache方法清除缓存了,后面也使用不了缓存

@Test

public void test(){

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UerMapper.class);

User user1 = mapper.queryUserById(1);

sqlSession.close();

// 不走缓存,一个SqlSession是一个连接

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UerMapper.class);

User user1 = mapper.queryUserById(1);

sqlSession.close();

}

3.2、二级缓存


注意:只在sqlsession调用了close或者commit后的数据才会进入二级缓存。

3.2.1、开启二级缓存

  1. 全局开启:在Mybatis核心配置文件中配置
  1. 局部开启:在要开启二级缓存的mapper映射文件中设置 cache标签
<?xml version="1.0" encoding="UTF-8" ?>

@Test

public void test(){

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UerMapper.class);

User user1 = mapper.queryUserById(1);

sqlSession.close();

// 走缓存,只要是同一个mapper

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UerMapper.class);

User user1 = mapper.queryUserById(1);

sqlSession.close();

}

3.2.2、实际开发

二级缓存在实际开发中基本不会使用。在一些笔试题会出现。

4、Mybatis注解实现单表操作

===================================================================================

这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。

注意:利用注解开发就不需要 mapper.xml 映射文件了

4.1、常用注解


| 注解 | 说明 |

| — | — |

| @Select(“查询的SQL语句”) | 执行查询操作注解 |

| @Insert(“新增的SQL语句”) | 执行新增操作注解 |

| @Update(“修改的SQL语句”) | 执行修改操作注解 |

| @Delete(“删除的SQL语句”) | 执行删除操作注解 |

4.2、Mybatis增删改查


我们完成简单的student表的增删改查的操作

  • 步骤一:在接口中添加注解

public interface StudentMapper {

//查询全部

@Select(“SELECT * FROM student”)

public abstract List selectAll();

//新增操作

@Insert(“INSERT INTO student VALUES (#{id},#{name},#{age})”)

public abstract Integer insert(Student stu);

//修改操作

@Update(“UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}”)

public abstract Integer update(Student stu);

//删除操作

@Delete(“DELETE FROM student WHERE id=#{id}”)

最后

既已说到spring cloud alibaba,那对于整个微服务架构,如果想要进一步地向上提升自己,到底应该掌握哪些核心技能呢?

就个人而言,对于整个微服务架构,像RPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service Mesh等这些都是最最核心的知识,架构师必经之路!下图,是自绘的微服务架构路线体系大纲,如果有还不知道自己该掌握些啥技术的朋友,可根据小编手绘的大纲进行一个参考。

image

如果觉得图片不够清晰,也可来找小编分享原件的xmind文档!

且除此份微服务体系大纲外,我也有整理与其每个专题核心知识点对应的最强学习笔记:

  • 出神入化——SpringCloudAlibaba.pdf

  • SpringCloud微服务架构笔记(一).pdf

  • SpringCloud微服务架构笔记(二).pdf

  • SpringCloud微服务架构笔记(三).pdf

  • SpringCloud微服务架构笔记(四).pdf

  • Dubbo框架RPC实现原理.pdf

  • Dubbo最新全面深度解读.pdf

  • Spring Boot学习教程.pdf

  • SpringBoo核心宝典.pdf

  • 第一本Docker书-完整版.pdf

  • 使用SpringCloud和Docker实战微服务.pdf

  • K8S(kubernetes)学习指南.pdf

image

另外,如果不知道从何下手开始学习呢,小编这边也有对每个微服务的核心知识点手绘了其对应的知识架构体系大纲,不过全是导出的xmind文件,全部的源文件也都在此!

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取


我们完成简单的student表的增删改查的操作

  • 步骤一:在接口中添加注解

public interface StudentMapper {

//查询全部

@Select(“SELECT * FROM student”)

public abstract List selectAll();

//新增操作

@Insert(“INSERT INTO student VALUES (#{id},#{name},#{age})”)

public abstract Integer insert(Student stu);

//修改操作

@Update(“UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}”)

public abstract Integer update(Student stu);

//删除操作

@Delete(“DELETE FROM student WHERE id=#{id}”)

最后

既已说到spring cloud alibaba,那对于整个微服务架构,如果想要进一步地向上提升自己,到底应该掌握哪些核心技能呢?

就个人而言,对于整个微服务架构,像RPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service Mesh等这些都是最最核心的知识,架构师必经之路!下图,是自绘的微服务架构路线体系大纲,如果有还不知道自己该掌握些啥技术的朋友,可根据小编手绘的大纲进行一个参考。

[外链图片转存中…(img-PvD7BeNu-1715002992097)]

如果觉得图片不够清晰,也可来找小编分享原件的xmind文档!

且除此份微服务体系大纲外,我也有整理与其每个专题核心知识点对应的最强学习笔记:

  • 出神入化——SpringCloudAlibaba.pdf

  • SpringCloud微服务架构笔记(一).pdf

  • SpringCloud微服务架构笔记(二).pdf

  • SpringCloud微服务架构笔记(三).pdf

  • SpringCloud微服务架构笔记(四).pdf

  • Dubbo框架RPC实现原理.pdf

  • Dubbo最新全面深度解读.pdf

  • Spring Boot学习教程.pdf

  • SpringBoo核心宝典.pdf

  • 第一本Docker书-完整版.pdf

  • 使用SpringCloud和Docker实战微服务.pdf

  • K8S(kubernetes)学习指南.pdf

[外链图片转存中…(img-8UE1Q423-1715002992097)]

另外,如果不知道从何下手开始学习呢,小编这边也有对每个微服务的核心知识点手绘了其对应的知识架构体系大纲,不过全是导出的xmind文件,全部的源文件也都在此!

[外链图片转存中…(img-TZq86xQK-1715002992098)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值