当前位置: 首页 > news >正文

阶段六-Day03-MyBatis

一、框架介绍

1. 框架的作用

将许多项目封装起来,形成了框架

2. 框架的优缺点

1. 优点
1.1 更好用

框架都是对Java原生内容进行的封装,对于企业级项目开发来说,使用框架比使用原生Java更好用,写起来更简单。

1.2 更强大

框架封装过程中会内置一些常见必要逻辑或功能,所以在使用框架时很多能够不需要再次编码,框架本身就带有这些功能了。

1.3 开发周期更短

由于框架使用起来更加简单,必定会在一定程度上缩短程序的开发周期。很多IT公司最大的成本都是人员成本,缩短了项目的开发周期,对于企业来说利润更高。这也是企业为什么都喜欢使用框架的最主要原因之一。

2. 缺点
2.1 更多的学习成本

不同的框架由不同的公司或组织开发与维护,不同公司或组织有着不同的习惯和规则,想要使用框架就需要学习框架如何使用,学习这些框架里面的要求。

2.2 初学者更容易出错

因为框架里面都封装了很多内容,想要使用框架就必须按照框架的规则进行使用。对于初学者如果不去记忆里面的规则,自己随意发挥,很容易出错。

所以想要错误更少,学习框架时必须严格按照老师讲的去做,严格按照框架规则去使用。

2.3 对于初学者,出了错误更难解决

因为框架都是深度封装,对于开发者来说可能只写了一行代码,但这一行代码里面可能是几百或几千行代码的封装。一旦报错了,如果不知道框架原理是不太好解决的。

所以想要更好的解决出现的问题,就必须要跟着老师学习框架的原理,同时要对每次出现的错误进行整理记忆,下次在出现这个错误的时候就可以快速解决了。

4. Java中的常见框架

Java项目无论是否使用框架,多采用MVC开发模型,一个项目被分为多层。一个Java框架可能只负责里面的一层。

一个Java项目并不是使用一个框架就可能完成的,通常需要很多框架配合使用,才能实现一个完整的项目。

常见Java框架分类(不仅仅就这些,列举一些常见的):

(1)持久层框架:MyBatis、Hibernate、Spring Data、iBatis。

(2)MVC框架:Spring MVC、Struts1、Struts2。

(3)项目管理框架:Spring Framework、Spring Boot。

(4)微服务框架:Spring Cloud。

(5)权限管理框架:Spring Security、Shiro。

并不是每个项目都需要把上面所有分类都使用上,不同的项目可能只会使用里面几个分类,但是只要使用了其中某个分类,只会选择其中一个。

常见的组合:

(1)SSM:Spring Framework + Spring MVC + MyBatis。最常见组合,属于Java程序员必须掌握的内容。

(2)SSMP:Spring Framework + Spring MVC + MyBatis+MyBatis Plus。对SSM的增强,减少SQL的编写。

(3)SSI:Spring Framework + Spring MVC/Struts1/Struts2 + iBatis。SSM的上代组合,目前很少出现。

(4)SSH:Spring Framework + Struts1/Struts2 + Hibernate。和SSI属于同时代产品,只有在老项目维护时可能出现的技术栈。

(5)Spring Boot + Spring Cloud。微服务架构项目常用组合。

(6)Spring Boot+Mybatis+MybatisPlus。新项目最先选择,比SSM组合使用起来更加方便。

(6)Spring Boot + Shiro/Spring Security。具有权限控制时的组合。

(7)SSM + Shiro/Spring Security。具有权限控制时的组合。

二、软件分层开发

1. Java EE 三层模型 和 MVC模型

Java EE 三层模型和MVC模型属于两种分层模型,一些同学可能认为这是同一个概念,其实并不然。

Java EE中最经典的是三层模型。包含表示层(Presentation)、业务逻辑层(Business Logic)、持久层(Persistence)

MVC 模型也是三层模型。包含模型层(Model)、视图层(View)、控制层(Controller)。

Java EE 三层模型和MVC模型最主要的区别是:

(1)Java EE三层模型中没有控制层,MVC中有控制层。

(2)Java EE三层模型中业务模型层是单独一部分,就是service层,MVC中模型层包含:业务模型(业务逻辑层)和数据模型(实体类,持久层)。

(3)Java EE三层模型中持久层就是dao层。MVC中虽然持久层在项目中是单独的包,但是在MVC概念中持久层属于模型层中。

2. 目前Java中最常见的六层模型

目前在软件开发过程中最常见的是六层模型,我们讲解的也是六层模型:

(1)视图层。简单点说就是页面,可以是客户端页面技术,也可以是服务端页面技术。例如:HTML、JSP。

(2)控制层。处于业务层和视图层之间,根据业务层结果,控制视图层显示。例如:Servlet。

(3)实体层。就是实体类,负责封装数据,在各个层之间进行数据传递的载体。常见包名:pojo、domain、entity等。

(4)业务逻辑层。专门编写业务逻辑代码。

(5)数据持久层/数据访问层。负责编写调用数据库的代码。具体技术:JDBC、MyBatis等。

(6)数据源层。一些持久化工具,负责存储数据的。例如:MySQL、Oracle等。

3. ORM

ORM(Object/Relation Mapping),中文名称:对象/关系 映射。是一种解决数据库发展和面向对象编程语言发展不匹配问题而出现的技术。

 使用JDBC技术时,手动实现ORM映射:

 ORM框架封装了对象/关系的自动映射。

6.常见的ORM框架

对于Java程序员来说,整个职业生涯可能听说过或可能用上的ORM框架:

(1)MyBatis:目前使用最多的ORM框架。

(2)Hibernate:零SQL的ORM框架,N年前使用最多的ORM框架。目前只能在一些老的项目中看到。

(3)Spring Data JPA:目前个别公司中使用的ORM框架。是Spring Data家族中的一员。是对JPA(Java Persistence API,JDK5.0)的封装。

(4)Spring Data JDBC:Spring Data中的二级项目,类似Spring Data JPA,但框架的功能要比Spring Data JPA少一些。

三、MyBatis介绍

1. 介绍

MyBatis 是一款优秀的ORM框架,MVC分层开发中的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

四、第一个MyBatis项目

2. 创建Maven项目并添加依赖

创建一个Maven项目(示例中叫做:maven1),并配置pom.xml。

需要添加MyBatis的依赖和MySQL驱动的依赖。(文档制作时MyBatis最新版本为3.5.9,mysql驱动最新版本为8.0.29)因为MyBatis的底层也是MySQL,JDBC实现的

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.sh</groupId><artifactId>MyBatis01</artifactId><version>1.0-SNAPSHOT</version><dependencies><!-- MyBatis 框架依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency><!-- 数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency></dependencies></project>

3. 创建MyBatis全局配置文件

在项目的src/main/resources目录下新建mybatis.cfg.xml文件。并在配置文件中填写下面内容。

配置文件解释:

  1. XML文档头是XML文件必须有的。

  2. DOCTYPE声明文档类型,引入外部约束。

  3. <configuration>是根节点。

  4. <environments>的default属性取值必须是下面某个<environment>标签的id属性值。表示当前MyBatis框架到底使用哪个环境。

  5. <environment>的id值是自定义的。表示当前数据库环境的名称。在全局配置文件中<environment>标签可以有多个,里面分别配置上数据源相关参数。例如一个里面配置连接本地MySQL的参数,另一个配置连接服务器中MySQL的参数,还有一个配置连接Oracle数据库的相关参数。都准备好了以后可以通过修改<environments>中default的值来切换连接的数据库,这样要比修改里面具体的连接参数更加方便。

  6. <transactionManager>中type属性用于配置事务的类型。可取值:

    • JDBC:使用原生JDBC的事务管理进行提交和回滚。

    • MANAGED:MyBatis不参与事务管理。交给其他人管理事务。

  7. <dataSource>中type属性值用于配置数据源类型。可取值:

    • UNPOOLED:不使用数据库连接池。每次执行SQL都会打开数据库连接,执行SQL结束都会关闭连接。适用于简单小型应用。

    • POOLED:使用MyBatis内置数据库连接池。对于频繁访问数据库的应用程序来说,这个取值是很适合的。

    • JNDI:使用本地目录接口技术连接容器外部的数据源。这种方式很少使用,一般都是极其复杂的项目,对数据源要求极高的情况下才能使用。

  8. <properties>配置具体属性和值

    driver、url、username、password四个属性名称是固定的,但是没有顺序要求,添加到<properties>的name属性中即可。分别代表驱动类、连接字符串、用户名、密码。value属性的值为连接数据库的具体参数值。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 配置执行的数据库环境 default中是默认使用哪个数据库技术--><!-- default中的名字也可以叫别的--><environments default="mysql"><environment id="mysql"><!--事务控制器有两种1. JDBC : 使用原生的JDBC的事务管理2. MANAGED : MyBatis不参与事务管理,交给其他人管理--><transactionManager type="JDBC"></transactionManager><!--配置数据源有三种UPOOLED: 不使用数据库连接池POOLED : 使用数据库连接池JNDI : 使用本地目录接口技术,特殊情况使用--><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments>
</configuration>

4. 创建Mapper映射文件

在src/main/resources目录中新建mybatis目录。这个文件夹可以新建也可以不建立,名称也是随意的。以后mapper文件会比较多,建立一个文件夹项目结构比较好看,名称叫做mybatis也好记。

在mybatis文件夹下新建xml文件,文件名称随意。示例中就叫做mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--  配置SQL映射的文件 -->
<mapper namespace="a.b"><insert id="addUser">insert into people values(default ,'zs','123')</insert>
</mapper>

5. 配置加载mapper映射文件

映射文件是不能默认被加载的。需要在全局配置文件mybatis.cfg.xml中手动指定加载路径。

6. 编写测试类,启动项目

package com.sh;import static org.junit.Assert.assertTrue;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 org.junit.Test;import java.io.IOException;
import java.io.InputStream;/*** Unit test for simple App.*/
public class AppTest {/*** Rigorous Test :-)*/@Testpublic void test1() throws IOException {// 1. 获取全局配置文件输入流InputStream is = Resources.getResourceAsStream("mybatis.cfg.xml");// 2. 加载全局配置文件后创建工厂类SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 3. 使用工厂创建SqlSession. 里面封装了所有增删改查的方法SqlSession session = factory.openSession();// 4. 执行sql方法,里面传递 namespace.id 通过语句的唯一标识找到sql语句int index = session.insert("a.b.addUser");System.out.println(index);// 5. mybatis是手动提交session.commit();// 6. 关闭连接,释放资源session.close();}
}

五、MyBatis属性加载

MyBatis支持加载属性文件(.properties文件),可以通过在属性文件中配置数据库连接属性然后加载。这种方式要比直接写稍微麻烦一点点,但是却把所有的数据库连接书写到了统一的文件中,以后查看或修改时更加方便。

1. 创建属性文件

在src/main/resources目录中创建jdbc.properties文件

注意:需要将$amp;转义字符变为&,否则运行报错

jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=root

2. 修改全局配置文件

修改mybatis.cfg.xml文件,设置加载属性。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 加载属性文件 ,再给属性赋值 --><properties resource="jdbc.properties"></properties><!-- 配置执行的数据库环境 default中是默认使用哪个数据库技术--><!-- default中的名字也可以叫别的--><environments default="mysql"><environment id="mysql"><!--事务控制器有两种1. JDBC : 使用原生的JDBC的事务管理2. MANAGED : MyBatis不参与事务管理,交给其他人管理--><transactionManager type="JDBC"></transactionManager><!--配置数据源有三种UPOOLED: 不使用数据库连接池POOLED : 使用数据库连接池JNDI : 使用本地目录接口技术,特殊情况使用--><!--<dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true"/><property name="username" value="root"/><property name="password" value="root"/></dataSource>--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><mapper resource="mybatis/mapper.xml"></mapper></mappers>
</configuration>

五、常见Java日志工具包

1. 日志介绍

日志是项目开发非常重要的一项。项目部署到服务器以后,并不能所有信息都通过控制台或命令窗口进行查看。把日志信息输入到文件中更有利于项目的维护。

Java项目的日志是可以输入到控制台、可以输入到文件中、甚至可以输入到某个数据源中。但是常用的还是控制台和文件。

在Java项目中常见的日志工具包:

  • Log4j:Apache推出的日志工具。于2012年5月发布1.2.17版本后停止更新。

  • Logback:属于Log4j的继承者。Spring Boot默认日志文件支持类型。

  • Log4j2:属于Log4j升级版,同时里面还包含了Logback的很多改进。

  • commons-logging:Apache早期基于门面(Facade)设计模式的日志包,提供了日志解构能力,按照顺序寻找当前项目日志接口实现,Log4j、JDK Log、SimpleLog。

  • Slf4j( Simple Logging Facade for Java ):目前使用非常多的门面日志。统一项目中日志。

  • JDK Logging:JDK自带的日志API。

2. JDK Logging

JDK Logging 是JDK自带的日志工具。存在于java.uti.logging包中。

日志的级别: OFF > SEVERE > WARNING > INFO > CONFIG > FINE > FINER > FINEST > ALL

注意:

1. 默认级别为INFO。

2. 只会显示该级别及该级别以上日志信息。

package com.sh;import java.io.IOException;
import java.util.logging.*;public class Demo {public static void main(String[] args) throws IOException {//参数通常设置为所在的类名Logger logger = Logger.getLogger("Demo");// 默认为INFO级别,同时设置当前和父处理器级别才能修改// OFF > SEVERE > WARNING > INFO > CONFIG > FINE > FINER > FINEST > ALLlogger.setLevel(Level.FINEST);Handler[] handlers = logger.getParent().getHandlers();// 获取输出控制台的处理器handlers[0].setLevel(Level.FINEST);// 设置控制台输出级别// 默认没有输出到文件,只输出到控制台,通过添加Handler增加输出目的地,输出到文件中FileHandler fh = new FileHandler("my.log");// 如果路径夹会不存在文件夹会报错fh.setFormatter(new SimpleFormatter());// 设置输出内容为普通格式logger.addHandler(fh);logger.severe("severe");// 严重logger.warning("warning");// 警告logger.info("info");// 信息logger.config("config");// 配置logger.fine("fine");// 详细logger.finer("finer");// 较详细logger.finest("finest");// 非常详细}
}

3. Log4j的使用

Log4j是Apache的开源日志工具。最新版本为2012年发布的1.2.17。

Log4j会自动寻找classpath下log4j.properties作为配置文件。

具体使用步骤:

3.1 配置pom.xml
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>
3.2 编写配置文件

在resources中新建log4j.properties,名称不要写错了。

log4j中定义的级别:fatal(致命错误) > error(错误) > warn(警告) > info(普通信息) > debug(调试信息) > trace(跟踪信息)

# log4j中定义的级别:fatal(致命错误) > error(错误) > warn(警告) > info(普通信息) > debug(调试信息) > trace(跟踪信息)
# 跟日志等级为debug 使用console和file两种方式输出
log4j.rootLogger = DEBUG , console , file### console ###(日志显示在控制台的配置)
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH\:mm\:ss}] %C.%M(%L) | %m%n### log file ###(日志输出在文件中的配置)
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
# 日志输出的路径
log4j.appender.file.File = log4j.log
# 是否给日志文件追加
log4j.appender.file.Append = true
# 级别只能比根日志界别高,比根日志级别低不生效
#log4j.appender.file.Threshold = info
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH\:mm\:ss}] %C.%M(%L) | %m%n
3.3 编写测试类

注意:千万不要倒错包。

package com.sh;
// 不要导错包
import org.apache.log4j.Logger;public class TestLog4j {public static void main(String[] args) {Logger logger = Logger.getLogger(TestLog4j.class);logger.trace("跟踪级别");logger.debug("调试信息");logger.info("普通信息");logger.warn("警告信息");logger.error("错误信息");logger.fatal("重大错误信息");}
}

4. Log4j2

4.1 配置pom.xml

虽然只导入了log4j-core,但是实际导入log4j-core和log4j-api。

<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version>
</dependency>
4.2 编写配置文件

Log4j2不再支持Log4j的.properties格式配置文件。而是支持.xml、.json、jsn。

Log4j2中定义的级别:fatal(致命错误) > error(错误) > warn(警告) > info(普通信息) > debug(调试信息) > trace(跟踪信息)

在resource目录新建log4j2.xml。

<?xml version="1.0" encoding="utf-8" ?>
<Configuration ><!-- 定义输出的目的地 --><Appenders><!-- Console 定义控制台输出 name:自定义名称 target:输出方式,支持SYSTEM_OUT SYSTEM_ERR --><!-- SYSTEM_OUT 正常输出内容SYSTEM_ERR 错误高亮输出内容--><Console name="console" target="SYSTEM_OUT"><!-- 输出信息表达式 --><PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/></Console><!-- File 定义文件输出 fileName 文件路径  append是否允许追加 --><File name="file" fileName="log4j2.log" append="true"><PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/></File></Appenders><Loggers><!-- 控制总体级别 --><!-- fatal > error > warn > info > debug > trace --><Root level="info"><!-- 引用输出位置的配置,Appenders中直接子标签的name属性值 --><!-- 映射哪种输出模式 --><AppenderRef ref="console"/><AppenderRef ref="file"/></Root></Loggers>
</Configuration>
4.3 编写测试类
package com.bjsxt;
// 千万别导错包了
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;public class TestLog4j {public static void main(String[] args) {Logger logger = LogManager.getLogger(TestLog4j.class);logger.trace("跟踪级别");logger.debug("调试信息");logger.info("普通信息");logger.warn("警告信息");logger.error("错误信息");logger.fatal("重大错误信息");}
}

5. SLF4j

SLF4j是日志的接口声明,不参与日志的具体实现,需要配合其它日志具体实现工具包才能进行使用。

每次添加其它日志工具包时,不要忘记SLF4j整合这个日志的依赖。

5.1 整合Log4j
5.1.1 导入依赖

导入3个依赖,分别代表slf4j依赖、整合依赖、log4j的依赖。

<!--slf4j整合log4j的依赖,版本要和slf4j的版本对应 -->
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.36</version>
</dependency>
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>
5.1.2 编写log4j的配置文件

使用写号的log4j.properties文件就行

5.1.3 编写测试类

小提示:

SLF4J作为门面设计模式的具体实现,无论使用哪种日志具体实现,都是下面的API。

public class TestSlf4j {public static void main(String[] args) {Logger logger = LoggerFactory.getLogger(TestSlf4j.class);logger.trace("trace");logger.debug("debug");logger.info("info");logger.warn("warn");logger.error("error");}
}
5.2 整合Log4j2
5.2.1 配置pom.xml

与SLF4J整合Log4j的整合包是不一样的。

<dependencies><!-- SLF4j整合Log4j2的依赖 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.17.2</version></dependency><!-- Log4j2工具的依赖--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version></dependency>
</dependencies>
5.2.2 添加Log4j2的配置文件

使用之前的log4j2.xml文件。

5.2.3 运行测试类

测试类的API和整合Log4j的API是完全相同的,直接运行即可。

5.3 即整合Log4j又整合Log4j2

SLF4J支持多种日志实现,但是在项目中整合依赖最好只有一个,否则会出现警告。

六、MyBatis启用日志功能

1. MyBatis支持的日志

MyBatis框架内置日志工厂。日志工厂负责自动加载项目中配置的日志。MyBatis支持以下日志,当存在多个日志工具时,严格按照从上往下顺序使用,且只会使用一个。

  • SLF4J

  • Apache Commons Logging

  • Log4j 2

  • Log4j (deprecated since 3.5.9)

  • JDK logging

2. MyBatis结合Log4j实现打印执行的SQL

3. MyBatis结合Log4j2实现打印执行SQL

同理演示Log4j2

3.1 编写pom.xml,引入依赖
<dependencies><!-- MyBatis 框架依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency><!-- 数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><!-- log4j2 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version></dependency>
</dependencies>
3.2 创建配置文件

在resources目录下新建log4j2.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<Configuration ><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/></Console></Appenders><Loggers><Root level="info"><AppenderRef ref="Console"/></Root><!-- namespace的值 --><logger name="a.b" level="debug"></logger></Loggers>
</Configuration>

4. 指定生效的日志

在MyBatis中默认按照顺序寻找,如果项目中存在多个日志。可以通过mybatis全局配置文件进行设置哪个日志生效。

在mybatis.cfg.xml中配置<settings>的标签

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><properties resource="jdbc.properties"></properties><!-- 配置哪个日志生效 , 多个日志的时候设置 --><!--<settings><setting name="log4j2" value="LOG4J2"/></settings>--><!-- 配置执行的数据库环境 default中是默认使用哪个数据库技术--><!-- default中的名字也可以叫别的--><environments default="mysql"><environment id="mysql"><!--事务控制器有两种1. JDBC : 使用原生的JDBC的事务管理2. MANAGED : MyBatis不参与事务管理,交给其他人管理--><transactionManager type="JDBC"></transactionManager><!--配置数据源有三种UPOOLED: 不使用数据库连接池POOLED : 使用数据库连接池JNDI : 使用本地目录接口技术,特殊情况使用--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url"value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><mapper resource="mapper.xml"></mapper></mappers>
</configuration>

5. 测试

package com.sh;import static org.junit.Assert.assertTrue;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 org.junit.Test;import java.io.IOException;
import java.io.InputStream;/*** Unit test for simple App.*/
public class AppTest {/*** Rigorous Test :-)*/@Testpublic void test1() throws IOException {//1.通过流读取全局配置文件InputStream is = Resources.getResourceAsStream("mybatis_config.xml");//2.创建工厂SqlSessionFactory构建器然后创建工厂SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);//3.通过工厂创建SqlSessionSqlSession session = factory.openSession();//4.session中封装了所有的增删改查的方法int i = session.insert("a.b.add1");//验证结果System.out.println(i);//5. 增删改手动提交事务session.commit();//6. 释放资源session.close();}
}

七、SQL参数

1. MyBatis中的占位符

MyBatis中最常用的占位符为 #{},在MyBatis的mapper文件的SQL中使用#{}作为占位符。最终解析时会解析成JDBC的占位符?。

2. 当参数为简单数据类型

当参数为一个简答数据类型时。例如:八大基本数据类型、String类型等。可以通过#{任意内容}获取到。

小提示:

1. 任意内容代表着,随意写,只要不是特殊字符即可。

2. 但是要注意不能不写。

2.1 修改Test类

SqlSession的insert()方法有两种。

想要传递参数就需要使用insert(String,Object)的方法。

 @Testpublic void test2(){SqlSessionFactory factory = getFactory();//3.通过工厂创建SqlSessionSqlSession session = factory.openSession();int i = session.insert("a.b.add2","456");System.out.println(i);session.commit();session.close();}
 <insert id="add2">insert into user values (default ,'ls',#{pwd})</insert>

通过使用,使用#{} 给占位赋值  先将#{}变成? 再进行解析 只有一个值需要赋值时

#{}括号中写什么都行

3. 当参数为多个值时 

3.1 修改Test类

由于insert(String,Object)方法只有一个Object类型方法能作为SQL参数,如果希望传递多个值,有两种选择:

1.可以创建一个对应类,通过对象进行传递。

参数是对象通过${属性名}获取

 @Testpublic void test3(){SqlSessionFactory factory = getFactory();//3.通过工厂创建SqlSessionSqlSession session = factory.openSession();User user = new User();user.setUsername("zw");user.setPassword("789");int i = session.insert("a.b.add3",user);System.out.println(i);session.commit();session.close();}

2.也可以把所有SQL参数放入到一个Map中。

参数是Map,通过${key}获取

@Testpublic void test3(){SqlSessionFactory factory = getFactory();//3.通过工厂创建SqlSessionSqlSession session = factory.openSession();/* User user = new User();user.setUsername("zw");user.setPassword("789");*/HashMap<String, String> map = new HashMap<>();map.put("username","zw");map.put("password","147");int i = session.insert("a.b.add3",map);System.out.println(i);session.commit();session.close();}
3.2 mapper文件
 <insert id="add3">insert into user values (default ,#{username},#{password})</insert>

4. ${} 的使用

在MyBatis中还有一种占位符写法:${}。

${}在被MyBatis进行解析时,不会解析为占位符?,而是直接解析成对应的,类似字符串拼接

学习JDBC时我们知道SQL中存在字符串拼接时,会有SQL注入问题。

那是不是意味着${}没有使用场景了?答案是否定的。JDBC中占位符?是不允许代替列名和表名的,也就意味着MyBatis的#{}不允许代替表名和列名但是使用${}可以动态设置列名或表名。

${}和#{}获取参数的写法完全相同。如果参数是对象通过${属性名}获取。如果参数是Map,通过${key}获取。如果参数是简单数据类型,通过${任意不为空的内容}进行获取。

4.1 修改映射文件

${}和#{}可以混合使用。实例中使用${}代替表名。

<insert id="add4">insert into ${table} values (default ,#{username},#{password})</insert>
4.2 修改Test类
 @Testpublic void test4(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();HashMap<String, String> map = new HashMap<>();map.put("table","user");map.put("username","zw");map.put("password","258");int i = session.insert("a.b.add4", map);System.out.println(i);session.commit();session.close();}

通过日志可以看到

${}直接解析为值  ,  而#{}则被解析为?

八、MyBatis中修改和删除实现

1. 修改和删除功能总体说明

MyBatis实现修改和删除功能与实现新增时是非常类型的,SQL参数传递的几种方式也是相同的。

主要区别:

就是mapper文件中标签名不同。

SqlSession的方法名不同。

操作mapper标签SqlSession方法名
新增<insert>insert(String)、insert(String,Object)
修改<update>update(String)、update(String,Object)
删除<delete>delete(String)、delete(String,Object)

2. 修改实现

2.1 修改映射文件

修改suiyi.xml文件.在里面添加上<update>标签。设定使用Map进行传递参数了,所以直接使用#{key}获取到参数。

 <update id="update1">update user set username=#{username} where id=#{id}</update>
2.2 修改测试类
 @Testpublic void test5(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();HashMap<String, String> map = new HashMap<>();map.put("username","hhh");map.put("id","1");int i = session.update("a.b.update1", map);System.out.println(i);session.commit();session.close();}

3. 删除实现

3.1 修改映射文件

修改suiyi.xml文件.在里面添加上<delete>标签。设定使用Map进行传递参数了,所以直接使用#{key}获取到参数。

 <delete id="delete1">delete from user where id=#{id}</delete>
3.2 修改测试类
/* 删除实现 */@Testpublic void test6(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();int i = session.delete("a.b.delete1", 10);System.out.println(i);session.commit();session.close();}

九、MyBatis中DQL操作

MyBatis的DQL操作在映射文件都是通过<select>标签实现的。

SqlSession根据根据查询结果类型不同,提供了五种查询方法:

方法名解释说明
selectOne()查询一行数据时,返回值为Object。如果没有查询到,但是不能查询到多行。
selectMap()查询多行数据时,把其中某列结果当做key,每行结果为Value
selectList()当查询多行数据时,返回值为List。如果没有查询到返回长度为零的List对象。
selectCursor()使用游标查询时使用,在大量数据时可以代替分页
select()万能方法,需要自己定义结果处理器

2. selectOne()方法使用

selectOne()方法要求查询结果是一行或没有查询到。如果查询结果是多行会报异常。

如果这行数据有多个值,可以放在实体类对象中。如果这行数据只有一列,可以使用简单数据类型接收

2.1 查询到一行或没有查询到结果时
2.1.1 修改映射文件

在映射中添加<select>标签,resultType属性是<select>标签必须有的属性,表示查询结果最终类型。取值为类型的全限定路径。就是查询结果对应的类是哪个要指定,而且要使用包名+类名

<!--DQL:selectOne必须保证列名和resultType中类型的属性名相同才能保证把查询到的结果自动放入对象当中
--><select id="one" resultType="com.sh.util.User">select * from user where id = #{id}</select>
2.1.2 修改Test类

selectOne()方法返回值是泛型类型,所以可以直接写对应的类型。

@Testpublic void test7(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();Map<String,Object> map = new HashMap<>();map.put("id",1);// 使用selectOne方法进行查询// 返回值可以直接写映射文件中select的resultType对应类型//知道是user类型直接转换成user类型User user = session.selectOne("a.b.select1", map);System.out.println(user);//查询不需要事务的提交/*session.commit();*///释放资源session.close();}
2.1.3 当没有写resultType属性时

resultType是<select>必须写的属性。如果不写resultType属性执行时会报错。在示例中删除掉了resultType属性。

2.1.4 查询到多行数据时

如果使用selectOne()方法,对应的SQL查询到多行数据会报错。

例如:修改映射文件的SQL为查询全部,且保证数据库people表有2行以上数据

3. selectList()方法使用

selectList()方法主要用在多行查询时,查询时把每行结果按照resultType类型进行封装,最终放入到List中。

3.1 修改映射文件

注意:resultType的类型为每行结果的类型,也就是List的泛型的类型。

<select id="select2" resultType="com.sh.util.User">select * from user</select>
3.2 修改Test类
//查询多个@Testpublic void test8(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();// 使用selectList方法进行查询// 返回值可以直接写映射文件中select的resultType对应类型List<User> list = session.selectList("a.b.select2");System.out.println(list);//查询不需要事务的提交/*session.commit();*///释放资源session.close();}

4. selectMap()方法使用

selectMap(String statement,Object param,String key);比上面多了String key参数。

String key:指定查询结果中哪列的值作为map的key。map的value是整行数据,类型和resultType类型一致。

4.1 修改映射文件
<select id="select3" resultType="com.sh.util.User">select * from user</select>
4.2 修改测试类

修改后运行效果,查看key和value的值

 // 使用 selectMap()@Testpublic void test9(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();// 使用selectList方法进行查询// 返回值可以直接写映射文件中select的resultType对应类型Map<String, Object> map = session.selectMap("a.b.select3", "id");System.out.println(map);//查询不需要事务的提交/*session.commit();*///释放资源session.close();}

5. selectCursor()方法使用

cursor 表示游标。属于对查询结果集的一种遍历方式。MyBatis底层使用JDBC,在MyBatis封装的Cursor中只有遍历功能。其实就是一个一个的查询出来

5.1 修改映射文件
 <select id="select4" resultType="com.sh.util.User">select * from user</select>
5.2 修改Test类

selectCursor()返回值为Cursor,提供了forEach()遍历和iterator()两种遍历方式,下面使用forEach()遍历方式。

@Testpublic void test10(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();// 使用selectList方法进行查询// 返回值可以直接写映射文件中select的resultType对应类型//泛型知道是userCursor<User> cursor = session.selectCursor("a.b.select4");cursor.forEach(System.out::println);//查询不需要事务的提交/*session.commit();*///释放资源session.close();}

6. select()方法使用

select(String statement,Object param,ResultHandler resultHandler);方法中第三个参数表示结果处理。

在ResultHandler接口中只有一个方法,表示如何处理

//使用select//自定义查询@Testpublic void test11(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();// 使用selectList方法进行查询// 返回值可以直接写映射文件中select的resultType对应类型//该方法是自定义查询,需要重写handleResult方法,可以创建一个类继承ResultHandle来实现//也可以使用匿名内部类,这里使用内部类MyResultHandler myResultHandler = new MyResultHandler();session.select("a.b.select5",myResultHandler);//查询不需要事务的提交/*session.commit();*/System.out.println("-------------------");System.out.println(myResultHandler.getResult());//释放资源session.close();}public class MyResultHandler implements ResultHandler {HashSet<Object> set = new HashSet<>();@Overridepublic void handleResult(ResultContext resultContext) {// System.out.println(resultContext.getResultObject());set.add(resultContext.getResultObject());}public Set<Object> getResult(){return set;}}

十、分页查询

1. MyBatis实现分页查询的几种方式

在MyBatis中实现查询有两种方式:

  1. 根据对应的数据库,编写SQL。这种方式与数据库耦合度较高,移植性差。但是确实我们平时使用的方式,因为大部分项目是没有修改数据库类型的场景。

  2. 使用MyBatis提供的RowBounds实现分页

2. 根据对应数据库编写SQL

2.1 修改映射文件
<select id="select6" resultType="com.sh.util.User">select * from user limit #{index},#{size}</select>
2.2 修改测试类
@Testpublic void test12(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();HashMap<String, Object> map = new HashMap<>();map.put("index",0);map.put("size",3);session.selectList("a.b.select6",map);System.out.println(map);//释放资源session.close();}

这是类似JDBC的方法

3. RowBounds方式进行分页

RowBounds是MyBatis中提供的一种"假分页"实现方式。对从数据库中查询到的结果进行截取。所以如果数据库中数据量特别大的时候可能会出现OOM等问题。就是当查询第二页时会把第一页的数据也查询出来,但是最终只截取第二页的内容

但是由于RowBounds不需要考虑底层数据库是什么,且使用简单,所以对于一些数据量不是特别大的应用还是有人选择使用的。

在SqlSession中select、selectMap、selectList中通过方法重载都提供了一个带有RowBounds。

3.1 修改映射文件
<!-- 使用RowBounds --><select id="select7" resultType="com.sh.util.User">select * from user</select>
3.2 修改Test类
/* 使用RowBounds */@Testpublic void test13(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();//创建偏移量对象RowBounds rowBounds = new RowBounds(0, 3);//因为偏移量必须是第三个参数,再不需要给占位符赋值的时候,第二个参数也必须要写,写为nullList<User> list = session.selectList("a.b.select7", null, rowBounds);System.out.println(list);//释放资源session.close();}

十一、模糊查询

1. 使用#{}实现模糊查询

1.1 修改映射文件
<select id="select8" resultType="com.sh.util.User">select * from user where username like #{username}</select>
1.2 修改测试类
// 模糊查询@Testpublic void test14(){SqlSessionFactory factory = getFactory();SqlSession session = factory.openSession();List<User> list = session.selectList("a.b.select8","%s%");System.out.println(list);//释放资源session.close();}

相关文章:

阶段六-Day03-MyBatis

一、框架介绍 1. 框架的作用 将许多项目封装起来,形成了框架 2. 框架的优缺点 1. 优点 1.1 更好用 框架都是对Java原生内容进行的封装&#xff0c;对于企业级项目开发来说&#xff0c;使用框架比使用原生Java更好用&#xff0c;写起来更简单。 1.2 更强大 框架封装过程…...

探索RPA流程自动化在不同行业的应用案例

随着数字化的推进&#xff0c;企业建设了大量的业务系统&#xff0c;跨系统的业务流程越发复杂&#xff0c;业务孤岛、 流程孤岛、数据孤岛也随之出现&#xff0c;产生了大量需要人工执行的重复性系统操作流程。而使用RPA能将员工从大量的、重复的、高耗时的工作中解放出来&…...

解决gpedit.msc命令无法打开的问题

【win11家庭版】解决gpedit.msc命令无法打开的问题 本地组策略编辑器 echo offpushd "%~dp0"dir /b %systemroot%\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >gp.txtdir /b %systemroot%\servicing\Packages\…...

一大突破!清华大学研制出首颗忆阻器存算一体芯片

这几天清华大学又火出圈了。但这次并不是因为招生抢人和饭堂&#xff0c;而是清华大学的芯片研发团队研制出全球首颗全系统集成的存算一体芯片。这是我国、乃至全世界对半导体行业的又一重大突破。 这个芯片由清华大学集成电路学院教授吴华强副教授高滨团队基于存算一体计算范…...

JUC的线程池架构

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…...

PostgreSQL limit 语法

PostgreSQL limit 语法 LIMIT 是 PostgreSQL 中用于限制查询结果数量的关键字。其语法如下&#xff1a; SELECT column1, column2, ... FROM table_name LIMIT number_of_rows;其中&#xff0c;SELECT 语句用于指定要查询的列和数据表&#xff0c;LIMIT 用于指定查询结果的行…...

CUDA C编程权威指南:2.1-CUDA编程模型

本文主要通过例子介绍了CUDA异构编程模型&#xff0c;需要说明的是Grid、Block和Thread都是逻辑结构&#xff0c;不是物理结构。实现例子代码参考文献[2]&#xff0c;只需要把相应章节对应的CMakeLists.txt文件拷贝到CMake项目根目录下面即可运行。 1.Grid、Block和Thread间的…...

两条记录合并成一条记录

两条记录合并成一条记录 两条记录 val4,type_idlevel 和 val6,type_idtypeId 合并成一条记录 level4,typeId6 可以使用 条件聚合语句 CASE WHEN … 和 MAX 函数来实现。假设有以下 my_table 表&#xff1a; --------------------- | id | val | type_id | --------------…...

vue3 + typescript + vite + naive ui + tailwindcss + jsx 仿苹果桌面系统

基于 vue3.x typescript vite naive ui tailwindcss jsx vue-router pinia&#xff0c;项目使用 tsx 作为模版输出&#xff0c;全程没有使用vue提供的SFC&#xff0c; 仿macos桌面前端项目&#xff0c;开源免费模版&#xff0c;希望减少工作量和学习新技术&#xff0c;希…...

揭秘,用软件一秒识别纸质表格数字,找到你想要的一串数字

要将纸质表格的数字快速用软件识别并找出特定的一串数字&#xff0c;以下是三种常用的方案&#xff1a; 方案一&#xff1a;使用OCR软件识别和搜索功能 1. 扫描纸质表格并保存为图像或PDF格式。 2. 使用OCR&#xff08;光学字符识别&#xff09;软件&#xff0c;如金鸣表格文字…...

解析图片文件格式

图片文件幻数 关于JPEG格式 二进制形式打开文件&#xff0c;文件开始字节为FF D8&#xff0c;文件结束两字节为FF D9 JPEG 文件有两种不同的元数据格式&#xff1a;JFIF 和 EXIF。 JFIF 以 ff d8 ff e0 开头&#xff0c;EXIF 以 ff d8 ff e1 开头。 代码示例 private static…...

新的“HTTP/2 快速重置”零日攻击打破了 DDoS 记录

自 8 月份以来&#xff0c;一种名为“HTTP/2 快速重置”的新 DDoS&#xff08;分布式拒绝服务&#xff09;技术已被作为零日漏洞积极利用&#xff0c;其规模打破了之前的所有记录。 Amazon Web Services、Cloudflare 和 Google 今天联合发布了有关零日技术的消息&#xff0c;他…...

现代化战机之路:美国空军U-2侦察机基于Jenkins和k8s的CI/CD架构演进

▲ 点击上方"DevOps和k8s全栈技术"关注公众 华为北京研究所Q27大楼 随着技术的不断进步&#xff0c;军事领域也在积极采纳现代化工具来提高战备水平和效率。美国空军的U-2侦察机项目是一个鲜明的例子&#xff0c;它成功地借助Jenkins和Kubernetes&#xff08;k8s&…...

Linux中常用的软件:Squid

在Linux系统中&#xff0c;有许多不同的代理软件可供选择。本文将比较两个常用的代理软件&#xff1a; Squid。我们将介绍它们的特点、使用场景和优缺点&#xff0c;帮助您选择适合自己需求的代理软件。 - 支持多种加密协议&#xff0c;包括AES、ChaCha20和RC4等&#xff0c;可…...

Ali MaxCompute SDK

ALI MC 文件读写 public abstract BufferedInputStream readResourceFileAsStream(String var1) throws IOException;LocalExecutionContext.java Overridepublic BufferedInputStream readResourceFileAsStream(String resourceName) throws IOException {try {return wareHou…...

解决element中table在页面切换时候表格底部出现空白

activated(){ this.$refs.table.doLayout() } activated()是Vue中一个很重要的生命周期函数&#xff0c;它是在组件大概率会被复用时调用的。当组件被复用时&#xff0c;原来的组件的数据和状态必须得到保留。activated()函数能够保持组件在别处被活化时的状态数据。 activat…...

Vue中对路由的进阶学习

路由进阶 文章目录 路由进阶1、路由的封装抽离2、声明式导航2.1、导航链接2.2、高亮类名2.3、跳转传参2.4、动态路由参数可选符 3、Vue路由--重定向4、Vue路由--4045、Vue路由–模式设置6、编程式导航6.1、基本跳转6.2、跳转传参 路由基础入门 1、路由的封装抽离 问题&#x…...

Vuex的同步存值与取值及异步请求

前言 1.概念 Vuex是一个用于管理Vue.js应用程序中状态的状态管理模式和库。Vue.js是一个流行的JavaScript框架&#xff0c;用于构建用户界面&#xff0c;而Vuex则专门用于管理应用程序的状态&#xff0c;以确保状态在整个应用程序中保持一致和可维护。 2.Vuex的特点&#xf…...

【Python爬虫 js渲染思路一】

Python爬虫 破解js渲染思路一 当我们在谈论网页js渲染的时候&#xff0c;我们在谈论什么 js渲染网页&#xff0c;从某种程度来说&#xff0c;是指单纯的http请求&#xff0c;返回的文本数据&#xff0c;与我们在浏览器看到的内容&#xff0c;相距甚远.其可包括为以下几点&…...

智慧安防AI视频智能分析云平台EasyCVR加密机授权小tips

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...