MyBatis 知识宝典,2024年最新面试开发人员都 问哪些问题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

4.3、属性(properties)


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

外部配置文件:db.properties

driver = com.mysql.cj.jdbc.Driver

url = jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT

username = root

password = 123456

由于mysql的驱动发生了更新,之前的链接方式需要改变,加入时区

之前:jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8

现在:jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone = GMT

引用:

4.4、类型别名(typeAliases)


类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写

  • 特定类起别名

当这样配置时,User 可以用在任何使用 com.ajun.pojo.User 的地方

可以对接口指定别名

  • 包下所有类起别名

每一个在包 com.ajun.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名,(大写User也可以,但不建议)。 比如 com.ajun.pojo.User 的别名为 user;若有注解,则别名为其注解值。

对包下的接口无效

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

| 别名 | 映射的类型 |

| — | — |

| _byte | byte |

| _long | long |

| _short | short |

| _int | int |

| _integer | int |

| _double | double |

| _float | float |

| _boolean | boolean |

| string | String |

| byte | Byte |

| long | Long |

| short | Short |

| int | Integer |

| integer | Integer |

| double | Double |

| float | Float |

| boolean | Boolean |

| date | Date |

| decimal | BigDecimal |

| bigdecimal | BigDecimal |

| object | Object |

| map | Map |

| hashmap | HashMap |

| list | List |

| arraylist | ArrayList |

| collection | Collection |

| iterator | Iterator |

4.5、设置(settings)


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

| 设置名 | 描述 | 有效值 | 默认值 |

| — | — | — | — |

| cacheEnabled | 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 | true | false | true |

| lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 | true | false | false |

| logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |

详细设置查看:mybatis – MyBatis 3 | 配置

4.6、其它配置


  • typeHandlers(类型处理器)

  • objectFactory(对象工厂)

  • plugins(插件)

5、映射器(mappers)

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

就是告诉 MyBatis 去哪里找映射文件(SQL语句)。

不支持通配符。推荐用package,可以指定包下的所有配置文件。

resource和class需要一个一个地配置

四种配置方法:

1、resource


2、url(不建议用)


3、class


4、package(推荐)


注意:用class 和 package时,接口名和配置文件名一致,且在同一个包下

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

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

  • SqlSessionFactoryBuilder

作用就是创建SqlSessionFactory。创建完之后就可以丢弃。

  • SqlSessionFactory

相当于数据源连接池,会伴随程序运行的全过程。可以生成多个SqlSession。应当设为单例模式,全局唯一。

  • SqlSession

相当于特定的一次请求,一个连接。请求完之后就关闭。不是线程安全的,不可以共享。

7、结果映射resultMap

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

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

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

7.1、实体属性名与数据库列名不一致


解决办法:

1、指定别名

把字段名 ps 指定为 属性名 psd,采用 as

select id,name,ps as psd from mybatis.user;

2、结果集映射resultMap

select * from mybatis.user;

8、日志

====

8.1、日志工厂


| 设置名 | 描述 | 有效值 | 默认值 |

| — | — | — | — |

| logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |

  • SLF4J

  • LOG4J [掌握]

  • LOG4J2

  • JDK_LOGGING

  • COMMONS_LOGGING

  • STDOUT_LOGGING [掌握] 控制台输出

  • NO_LOGGING

具体使用哪一个,在设置中设定

STDOUT_LOGGING 标准日志输出 (控制台输出)

mybatis-config中

注意格式:大小写敏感,不能有空格

8.2、Log4j


8.2.1、介绍

  • Log4j是Apache的一个开源项目,可以控制日志信息输送的目的地是控制台、文件、GUI组件

  • 可以控制每一条日志的输出格式;

  • 通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。

  • 可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

8.2.2、导入jar包

log4j

log4j

1.2.17

8.2.3、配置log4j.properties

set log levels

log4j.rootLogger = DEBUG,console,file

输出到控制台

log4j.appender.console = org.apache.log4j.ConsoleAppender

log4j.appender.console.Target = System.out

log4j.appender.console.Threshold = DEBUG

log4j.appender.console.layout = org.apache.log4j.PatternLayout

log4j.appender.console.layout.ConversionPattern = [%c]-%m%n

输出到日志文件

log4j.appender.file=org.apache.log4j.RollingFileAppender

log4j.appender.file.File=./log/ajun.log

log4j.appender.file.MaxFileSize=10mb

log4j.appender.file.Threshold=DEBUG

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

日志输出级别

log4j.logger.org.mybatis=DEBUG

log4j.logger.java.sql=DEBUG

log4j.logger.java.sql.Statement=DEBUG

log4j.logger.java.sql.ResultSet=DEBUG

log4j.logger.java.sql.PreparedStatement=DEBUG

8.2.4、mybatis中配置log4j

8.2.5、使用

  • 在要使用log4j的类中,导入包 org.apache.log4j.Logger

import org.apache.log4j.Logger;

  • 获取日志对象,参数为当前类的class

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

  • 日志级别

logger.info(“info信息”);

logger.debug(“debug信息”);

logger.error(“error信息”);

9、分页

====

9.1、limit分页【重点】


9.1.1、SQL

select * from 表名 limit startIndex , pageSize;

select * from 表名 limit pageSize; //startIndex默认为0

startIndex:起始位置

pageSize:一次查询的数量

startIndex省略时,默认从0开始

9.1.2、接口方法

//分页查询

List getUserByPage(Map<String,Integer> map);

9.1.3、Mapper.xml配置

select * from mybatis.user limit #{startIndex},#{pageSize};

9.1.4、测试类

@Test

public void getUserByPage(){

SqlSession sqlSession = MyBatisUtils.getSqlSession();

try{

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

Map<String,Integer> map = new HashMap<String,Integer>();

map.put(“startIndex”,2);

map.put(“pageSize”,2);

List users = mapper.getUserByPage(map);

for (User user : users) {

System.out.println(user);

}

}finally {

sqlSession.close();

}

}

9.2、RowBounds分页 (面向对象)


不建议使用

9.3、分页插件


Mybatis PageHelper

10、注解开发

=======

不建议使用。没有xml配置sql形式功能强大。

10.1、接口类 UserMapper.java


public interface UserMapper {

//查询全部

@Select(“select * from user”)

List getAllUser();

}

10.2、Mybatis-config.xml配置


使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 SQL 语句更加混乱不堪。 因此,如果需要做一些很复杂的操作,最好用 XML 来映射语句。

本质:反射机制

底层:动态代理!

10.3、自动提交事务


SqlSessionFactory的openSession()方法,默认不自动提交事务。可以接受参数:

//默认为false,不自动提交事务

openSession(boolean autoCommit);

//true时,就可以自动提交事务

openSession(true);

实际开发中不建议自动提交。

10.4、@Param()注解


  • 基本类型的参数或String类型的参数,需要加上

  • 对象参数不需要加

  • 如果只有一个基本类型参数,可以省略,建议加上

  • SQL语句中的参数#{uid},和@Param()中的参数"uid"是对应的

int addUser(@Param(“id”) int id,@Param(“name”) String name,@Param(“psd”) String ps);

int addUser(User user);//对象类型,不需要加

int deleteUser(int id);//只有一个基本类型参数,可以省略

//SQL语句中的参数#{uid},和@Param()中的参数"uid"是对应的

@Select(“select * from user where id = #{uid}”)

User getUserById(@Param(“uid”) int id);

10.5、#{} 和 ${}


MyBatis中使用parameterType向SQL语句传参,parameterType后的类型可以是基本类型int,String,HashMap和java自定义类型。

在SQL中引用这些参数的时候,可以使用两种方式#{parameterName}或者${parameterName}。

  • #{} 将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

例如:order by #{parameterName} //或取Map中的value#{Key}也是一样操作。

假设传入参数是“Smith”

会解析成:order by “Smith”

  • ${} 将传入的数据直接显示生成在sql中。

例如:order by p a r a m e t e r N a m e / / 或取 M a p 中的 v a l u e {parameterName} //或取Map中的value parameterName//或取Map中的value{Key}也是一样操作。

假设传入参数是“Smith”

会解析成:order by Smith

区别:

  • # 方式能够很大程度防止sql注入,$ 方式无法防止Sql注入
  • $ 方式一般用于传入数据库对象,例如传入表名。从安全性上考虑,能使用#尽量使用#来传参,因为这样可以有效防止SQL注入的问题。

注意:

MyBatis排序时使用order by 动态参数时需要注意,用$而不是#

例如:ORDER BY ${columnName} //这里MyBatis不会修改或转义字符串,可实现动态传入排序。

建议:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

传入表名称用${}

时间比较,需要为#{},参数尽量用#{},${}容易导致需要有引号的参数失效

11、Mybatis详细执行流程

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

  1. Resource获取全局配置文件

  2. 实例化SqlsessionFactoryBuilder

  3. 解析配置文件流XMLConfigBuilder

  4. Configuration所有的配置信息

  5. SqlSessionFactory实例化

  6. transactional事务管理

  7. 创建executor执行器

  8. 创建SqlSession

  9. 实现CRUD

  10. 查看是否执行成功

  11. 提交事务

  12. 关闭

12、Lombok

=========

12.1、在IDEA中安装lombok插件


12.2、导入jar包


org.projectlombok

lombok

1.18.20

provided

12.3、注解命令

@Getter and @Setter

@FieldNameConstants

@ToString

@EqualsAndHashCode

@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor //构造器

@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog

@Data //重点

@Builder

@SuperBuilder

@Singular

@Delegate

@Value

@Accessors

@Wither

@With

@SneakyThrows

@val

@var

experimental @var

@UtilityClass

Lombok config system

12.3、IDEA中查看类结构


在IDEA中 Alt+F7 可以实时查看类方法

13、多对一

======

  • 多个学生关联一个老师(多对一)

  • 一个老师教多个学生 集合(一对多)

13.1、建库


CREATE TABLE teacher (

id INT(10) NOT NULL PRIMARY KEY,

name VARCHAR(30) DEFAULT NULL

)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher (id,name) VALUES (1,‘阿军’);

CREATE TABLE student (

id INT(10) NOT NULL,

name VARCHAR(30) DEFAULT NULL,

tid INT(10) DEFAULT NULL,

PRIMARY KEY (id),

KEY fktid (tid),

CONSTRAINT fktid FOREIGN KEY (tid) REFERENCES teacher (id)

)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO student (id, name, tid) VALUES (1, ‘xiao1’, 1);

INSERT INTO student (id, name, tid) VALUES (2, ‘xiao2’, 1);

INSERT INTO student (id, name, tid) VALUES (3, ‘xiao3’, 1);

INSERT INTO student (id, name, tid) VALUES (4, ‘xiao4’, 1);

INSERT INTO student (id, name, tid) VALUES (5, ‘xiao5’, 1);

13.2、环境搭建


1、实体类

  • Teacher.java

@Data

public class Teacher {

private int id;

private String name;

}

  • Student.java

@Data

public class Student {

private int id;

private String name;

private Teacher teacher;

}

2、接口类

  • TeacherMapper.java

public interface TeacherMapper {

@Select(“select * from teacher where id = #{uid}”)

Teacher getTeacher(@Param(“uid”) int id);

}

  • StudentMapper.java

public interface StudentMapper {

}

3、接口配置xml

接口配置文件 TeacherMapper.xml 和 StudentMapper.xml 放入资源resources目录中。在资源目录中创建和接口类一样的目录结构。创建目录时用斜杠 / 分开,如com/ajun/mapper,或者一层一层地创建。如果用com.ajun.mapper创建是不会分层的。和src中的创建方式不一样。src中是包,resources中是文件目录。

把mapper.xml配置文件放入资源目录下后,maven中就不需要静态资源过滤了

  • TeacherMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
  • StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>

注:mybatis-config.xml 与 mapper.xml结构模版相同,关键词不同。详见2.8

4、mybatis-config.xml 中添加mapper

就是告诉 MyBatis 去哪里找映射文件(SQL语句)。

不支持通配符。推荐用package,可以指定包下的所有配置文件。

resource和class需要一个一个地配置

四种配置方法。见5

5、工具类

和2.4中一样

6、测试

public class MyTest {

@Test

public void test(){

SqlSession sqlSession = MyBatisUtils.getSession();

try{

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

Teacher teacher = mapper.getTeacher(1);

System.out.println(teacher);

}finally {

sqlSession.close();

}

}

}

13.3、子查询:查询嵌套处理


  • 接口类

public interface StudentMapper {

List getStudent();

//方式二使用

List getStudent2();

}

  • mapper.xml

select * from mybatis.student;

select * from mybatis.teacher where id = #{tid};

  • 测试

@Test

public void test2(){

SqlSession sqlSession = MyBatisUtils.getSession();

try{

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

List studentList = mapper.getStudent();

for (Student student : studentList) {

System.out.println(student);

}

}finally {

sqlSession.close();

}

}

13.4、联表查询:结果嵌套处理(推荐)


  • mapper.xml

select s.id sid,s.name sname,t.id tid,t.name tname

from mybatis.student s,mybatis.teacher t

where s.tid = t.id;

  • 测试

14、一对多

======

14.1、联表查询


1、实体类

学生类:Student.java

@Data

public class Student {

private int id;

private String name;

private int tid;

}

老师类:Teacher.java

@Data

public class Teacher {

private int id;

private String name;

private List students;

}

2、接口类

public interface TeacherMapper {

//获取所有老师

List getTeacher();

//获取特定老师及学生

Teacher getTeacherById(@Param(“tid”) int id);

}

3、接口配置TeacherMapper.xml

select * from mybatis.teacher;

select t.id tid,t.name tname,s.id sid,s.name sname

from mybatis.teacher t,mybatis.student s

where t.id = #{tid} and t.id = s.tid

4、mybatis-config.xml 中添加mapper

就是告诉 MyBatis 去哪里找映射文件(SQL语句)。

不支持通配符。推荐用package,可以指定包下的所有配置文件。

resource和class需要一个一个地配置

四种配置方法。见5

5、工具类

同上

6、测试

@Test

public void test2() {

SqlSession sqlSession = MyBatisUtils.getSession();

try {

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

Teacher teacher = mapper.getTeacherById(1);

System.out.println(“=老师=”);

System.out.println("id: "+teacher.getId());

System.out.println("姓名: "+teacher.getName());

List students = teacher.getStudents();

for (Student student : students) {

System.out.println(student);

}

} finally {

sqlSession.close();

}

}

14.2、子查询


与14.1联表查询环境基本一致。主要改动为TeacherMapper.xml:

select * from mybatis.teacher where id = #{tid};

<collection property=“students” javaType=“ArrayList”

ofType=“student” select=“getStudentByTeacherId”

column=“id”/>

select * from mybatis.student where tid = #{tid};

14.4、多对一 和 一对多 比较


  • 都推荐用联表查询

  • 多对一:结果集映射用 association 表示一个实体,指向 一 的一方。类型为:javaType

  • 一对多:结果集映射用 collection 表示集合,指向 多 的一方。

子查询中用javaType表示结果集(ArrayList),用ofType表示结果集中的对象student

<collection property=“students” javaType=“ArrayList”

ofType=“student” select=“getStudentByTeacherId”

column=“id”/>

15、动态SQL

========

动态 SQL 是 MyBatis 的强大特性之一。可以根据条件动态地生成SQL

15.1、环境搭建


1、建表

CREATE TABLE blog(

id VARCHAR(50) NOT NULL COMMENT ‘博客ID’,

title VARCHAR(100) NOT NULL COMMENT ‘博客标题’,

author VARCHAR(30) NOT NULL COMMENT ‘博客作者’,

create_time DATETIME NOT NULL COMMENT ‘创建时间’,

views INT(30) NOT NULL COMMENT ‘浏览量’,

PRIMARY KEY (id)

)ENGINE=INNODB DEFAULT CHARSET=utf8

2、工具类

  • IDUtils.java

生成随机id,并去掉 - (把 - 换成空)

public class IDUtils {

//随机生成随机id,把-换成空

public static String getId(){

return UUID.randomUUID().toString().replaceAll(“-”,“”);

}

}

  • MyBatisUtils.java

和之前相同

3、实体类 Blog.java

@Data

public class Blog {

private String id;

private String title;

private String author;

private Date createTime;

private int views;

}

4、Mapper接口类

//BlogMapper.java

public interface BlogMapper {

//添加

int addBlog(Blog blog);

}

5、配置文件

  • mybatis-config.xml
  • BlogMapper.xml

放在resources下的对应目录中,maven不用做静态资源过滤

insert into mybatis.blog(id, title, author, create_time, views)

values (#{id},#{title},#{author},#{createTime},#{views});

6、测试

@Test

public void test1(){

SqlSession sqlSession = MyBatisUtils.getSession();

try{

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

Blog blog = new Blog();

blog.setId(IDUtils.getId());

blog.setAuthor(“ajun”);

blog.setCreateTime(new Date());

blog.setViews(999);

blog.setTitle(“红楼梦”);

mapper.addBlog(blog);

blog.setId(IDUtils.getId());

blog.setTitle(“水浒传”);

mapper.addBlog(blog);

blog.setId(IDUtils.getId());

blog.setTitle(“西游记”);

mapper.addBlog(blog);

blog.setId(IDUtils.getId());

blog.setTitle(“三国演义”);

mapper.addBlog(blog);

sqlSession.commit();//提交事务

}finally {

sqlSession.close();

}

}

15.2、if标签


  • 接口类增加方法:

//查询

List getBlogByMap(Map map);

  • BlogMapper.xml

select * from mybatis.blog where views > 500

AND title like #{title}

AND author like #{author}

根据title和author是否为空,可以动态生成SQL

默认SQL:

select * from mybatis.blog where views > 500

title不为空时:

select * from mybatis.blog where views > 500 and title like #{title}

author不为空时:

select * from mybatis.blog where views > 500 and author like #{author}

  • 测试

@Test

public void test2(){

SqlSession sqlSession = MyBatisUtils.getSession();

try{

BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);

Map<String,Object> map = new HashMap<String,Object>();

map.put(“title”,“西游记”);

//map.put(“author”,“aaa”);

List blogs = blogMapper.getBlogByMap(map);

for (Blog blog : blogs) {

System.out.println(blog);

}

}finally {

sqlSession.close();

}

}

15.3、where标签


select * from mybatis.blog

views > 500

AND title like #{title}

AND author like #{author}

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

15.3、choose(when、otherwise)标签


按顺序只选择其中的一个条件

where和choose配合使用

select * from mybatis.blog

title like #{title}

and author like #{author}

and views > 500

15.4、set标签


update Author

username=#{username},

password=#{password},

email=#{email},

bio=#{bio}

where id=#{id}

set元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

set元素中间的判断条件要有至少一个成立

15.5、trim标签


trim为自定义标签,可以替换where和set

prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

15.6、SQL片段


有些时候我们有一些公共部分

  1. 使用sql便签抽取公共部分

  2. 在使用的地方使用include标签

title = #{title}

and author = #{author}

select * from mybatis.blog

注意:

  • 最好基于单表

  • sql里不要存在where标签

  • 了解即可

15.7、foreach


动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

select * from blog where id in

<foreach item=“item” index=“index” collection=“ids”

open=“(” separator=“,” close=“)”>

#{item}

select * from blog

<foreach item=“item” index=“index” collection=“ids”

open=“(” separator=“or” close=“)”>

#{item}

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

16、缓存

=====

最后

我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习

已经将知识体系整理好(源码,笔记,PPT,学习视频)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

date Author

username=#{username},

password=#{password},

email=#{email},

bio=#{bio}

where id=#{id}

set元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

set元素中间的判断条件要有至少一个成立

15.5、trim标签


trim为自定义标签,可以替换where和set

prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

15.6、SQL片段


有些时候我们有一些公共部分

  1. 使用sql便签抽取公共部分

  2. 在使用的地方使用include标签

title = #{title}

and author = #{author}

select * from mybatis.blog

注意:

  • 最好基于单表

  • sql里不要存在where标签

  • 了解即可

15.7、foreach


动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

select * from blog where id in

<foreach item=“item” index=“index” collection=“ids”

open=“(” separator=“,” close=“)”>

#{item}

select * from blog

<foreach item=“item” index=“index” collection=“ids”

open=“(” separator=“or” close=“)”>

#{item}

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

16、缓存

=====

最后

我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习

已经将知识体系整理好(源码,笔记,PPT,学习视频)

[外链图片转存中…(img-odcQJwxR-1713639379309)]

[外链图片转存中…(img-v7a6RFAM-1713639379310)]

[外链图片转存中…(img-wrAGGmUy-1713639379310)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-OXKOddcX-1713639379311)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值