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

Mybatis

1 什么是MyBatis

MyBatis是一个优秀的持久层框架,它对JDBC操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、 结果集检索等JDBC繁杂的过程代码 。

MyBatis通过 xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过 Java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由MyBatis框架执行sql并将结果 映射成Java对象并返回。

1.2 MyBatis的优点

  1. 简单易、 没有任何第三方依赖,最简单安装只要两个jar文件 + 配置几个sql映射文件,
  2. Mybatis不会对应用程序或者数据库的现有设计强加任何影响,sql写在xml里,便于统一管理和优 化。 通过sql语句可以满足操作数据库的所有需求。
  3. 解除sql与程序代码的耦合: 通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测 试。 sql和代码的分离,提高了可维护性 。
  4. 提供丰富且强大的标签 。

1.3 为什么要学Mybatis

当使用java代码操作数据库时,需要用到 JDBC编程 ,但JDBC在使用时存在问题:

  1. 数据库连接使用时就创建,不使用时便立即释放,从而对数据库进行频繁的操作,导致资源的浪
    费、影响性能
  2. sql都是硬编码到Java程序中,如果改变sql,那么得重新编译Java代码,不利于系统后期的维护。
  3. 向PreparedStatement设置参数,也是硬编码到Java程序中,不利于后期的维护。
  4. 从resultset遍历结果集数据时,也存在硬编码,不利于后期系统的维护。

1.4 MyBatis整体架构

  1. MyBatis配置: mybatis-config.xml(名称不固定),此文件作为MyBatis的全局(核心)配置文件,配置了 MyBatis的运行环境等信息。 mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。
  2. 通过MyBatis环境等配置信息构造SqlSessionFactory,即会话工厂。
  3. 由会话工厂创建SqlSession即会话,操作数据库需要通过SqlSession进行。
  4. MyBatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行 器、一个是缓存执行器。
  5. MappedStatement也是MyBatis一个底层封装对象,Mybatis将SQL的配置信息加载成为一个个 MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存 中。mapper.xml文件中一个sql对应一个MappedStatement对象,sql的id即是MappedStatement的 id。
  6. MappedStatement对sql执行输入参数进行定义,包括HashMap、基本类型、字符串类型、实体类 类型,Executor通过MappedStatement在执行sql前将输入的Java对象映射至sql中,输入参数映射就是 JDBC编程中对PreparedStatement设置参数。
  7. MappedStatement对sql执行输出结果进行定义,包括HashMap、基本类型、字符串类型、实体类 类型,Executor通过MappedStatement在执行sql后将输出结果映射至Java对象中,输出结果映射过程 相当于JDBC编程中对结果的解析处理过程。

1.5 vo、po、dto、bo、pojo、entity 等层的解释。

  • VO:值对象 ,由new创建,由GC回收,存放指定的数据,可以和表数据不一致。
  • PO:是 ORM 框架中Entity,PO属性和数据库中表的字段形成一一对应关系 加上get和set方法 ;
  • entity :和PO的功能类似,和数据表一 一对应,一个实体一张表 。
  • dto: 数据传输对象 ,存放页面需要的表的部分字段。
  • bo: BO是封装业务逻辑的Java对象,封装了多个po,vo,通过调用DAO方法,进行业务操作。
  • pojo:简单来说可以理解成不包含业务逻辑的单纯用来存储数据的Java类 , 可以转化为PO、DTO、VO。
    • 一个POJO持久化以后就是PO; 直接用它传递、传递过程中就是DTO; 直接用来对应表示层就是VO;

2 建立MyBatis项目

2.1新建一个java项目,导入maven包

<dependencies><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><!-- oracle:大家在引入oracle依赖的时候肯定出错 --><dependency><groupId>com.oracle</groupId><artifactId>ojdbc6</artifactId><version>11.2.0.1.0</version></dependency><!--  mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency><!-- log4j Mybatis的日志输出组件 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
</dependencies>

2.2 编写MyBatis中全局配置文件 mybatis-config.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 文件的根节点 -->
<!-- MyBatis配置文件报错:
在编写xml配置文件引入DTD约束时,可能会出现这个错误提示 URI is not registered(Settings | 
Languages & Frameworks | Schemas and DTDs),此时使用快捷键,选择Fetch external 
resource 或 Ignore external resource选项。或者直接在设置settings -> languages&frameworks -> schemas and dtds 中添加出问题的路径。 -->
<configuration><!--properties 用于引入外部的properties配置文件resource:引入类路径下的文件url:引入磁盘或网路--><properties/><!-- environments:多个配置环境;通过default属性可以对多个环境快速切换。environments default属性的值必须和某个environment的id值一致。--><!-- 和spring整合后 environments配置将废除,了解即可 --><environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/ssm?characterEncoding=utf8&amp;useSSL=false"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments></configuration>

2.3 导入一个数据库SQL

CREATE TABLE `dept`  (`deptno` int PRIMARY KEY AUTO_INCREMENT,`dname` varchar(20),`loc` varchar(40)
);INSERT INTO `dept` VALUES (10, 'ACCOUNTING', 'NEW YORK');INSERT INTO `dept` VALUES (20, 'RESEARCH', 'DALLAS');INSERT INTO `dept` VALUES (30, 'SALES', 'CHICAGO');INSERT INTO `dept` VALUES (40, 'OPERATIONS', 'BOSTON');CREATE TABLE `emp`  (`empno` int PRIMARY KEY AUTO_INCREMENT,`ename` varchar(20),`job` varchar(20),`mgr` int,`hiredate` date,`sal` double,`comm` double,`deptno` int,CONSTRAINT `FK_EMP_DEPTNO` FOREIGN KEY (`deptno`) REFERENCES `dept` (`deptno`));INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 1300, NULL, 20);INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 2100, 300, 30);INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1750, 500, 30);INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 3475, NULL, 20);INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1750, 1400, 30);INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 3350, NULL, 30);INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2950, NULL, 10);INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3500, NULL, 20);INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5500, NULL, 10);INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 2000, 0, 30);INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1600, NULL, 20);INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '0198-12-31', 1450, NULL, 30);INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3500, NULL, 20);INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1800, NULL, 10);

2.4 编写实体类

import java.util.Date;public class Emp {private Integer empno;private String ename;private String job;private Integer mgr;private Date hiredate;private Double sal;private Double comm;private Integer deptno;// 省略set,get方法}

2.5 编写映射文件

在src/main/resources下创建mapper目录,在该目录下创建sql映射文件Emp.xml。  
<?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">
<!--
namespace: 命名空间,作用是mapper文件进行分类管理,用于隔离sql语句。
注意:如果使用mapper代理的方式进行开发,namespace有特殊的作用。-->
<mapper namespace="emp"><!-- 通过员工编号查询员工信息 --><!--通过<select>标签编写查询语句id: 映射文件中SQL语句的唯一标识。mybatis会将SQL语句封装到MappedStatement对象中,所以此处的id也可以标识MappedStatement对象的id;注意:同一个mapper文件中id不能重复,而且id在mapper代理模式下有着重要作用;parameterType: 输入参数的类型。sql语句的占位符:#{};#{empno}:其中empno表示接收输入的参数值,参数名称为empno;但是如果参数的类型为简单类型(基本数据类型、包装类、字符串类型),参数名称可以任意指定;resultType: 输出参数的类型。需要指定输出数据为Java中的数据类型(实体类的全限定名);--><select id="selectById" parameterType="java.lang.Integer" resultType="com.gs.entity.Emp">select empno, ename, job, hiredate, mgr, sal, comm, deptno from emp where empno=#{empno}</select>
</mapper>

将这个mapper文件都丢到全局配置文件中。

<!-- 加载映射文件的位置 --><mappers><mapper resource="mapper/Emp.xml"/></mappers>

2.6 log4j配置 (在控制台可查看sql语句)

Mybatis日志输出:log4j.properties配置文件。

#井号表示注释,配置内容为键值对格式,每行只能有一个键值对,键值对之间以=连接
#指定logger#设定log4j的日志级别和输出的目的地
#INFO日志级别,Console和logfile输出的目的地
#等级 OFF,ERROR,WARN,INFO,DEBUG,TRACE,ALLlog4j.rootLogger=DEBUG,Console#指定appender#设定Logger的Console,其中Console为自定义名称,类型为控制台输出
log4j.appender.Console=org.apache.log4j.ConsoleAppender#设定Logger的logfile,其中logfile为自定义名称,类型为文件
#org.apache.log4j.FileAppender文件
#org.apache.log4j.RollingFileAppender文件大小到达指定尺寸后产生一个新的文件
#org.apache.log4j.DailyRollingFileAppender每天产生一个日志文件
log4j.appender.logfile=org.apache.log4j.RollingFileAppender#设定文件的输出路径
log4j.appender.logfile.File=d:/log/test.log#设定文件最大尺寸  单位可以使KB,MB,GBlog4j.appender.logfile.MaxFileSize=2048KB#输出格式
#设定appender布局Layout#   
%d 输出日志的日期和时间,指定格式:%d{yyyy-MM-dd HH:mm:ss SSS}#   
#   
#   
#   
#   
%p 输出的日志级别
%c 输出所属类的全类名
%M 方法名
%m 输出代码中指定消息
%n 一个换行符
log4j.appender.Console.layout=org.apache.log4j.PatternLayoutlog4j.appender.Console.layout.ConversionPattern=%d %p %c.%M() --%m%nlog4j.appender.logfile.layout=org.apache.log4j.PatternLayoutlog4j.appender.logfile.layout.ConversionPattern=%d %p %c.%M() --%m%n

2.7 编写测试程序 (在test路径下)

运行测试类;

/*** 测试程序*/
public class MybatisTest {@Testpublic void test() throws IOException {//1.创建读取全局配置文件的流InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//2.通过配置文件流创建会话工厂SqlSessionFactory factory = builder.build(in);//3.通过会话工厂创建会话对象(SqlSession)SqlSession session = factory.openSession();//4.通过会话对象操作数据/*** 查询单条记录* selectOne(String statementId, Object param)* 参数1:映射文件中的statementId,命名空间名.statementId* 参数2:向sql语句中传入的数据,注意:传入的数据类型必须与映射文件中配置的
parameterType保持一致* 返回值:就是映射文件中配置的resultType的类型* 查询多条记录* selectList()*/Emp emp = session.selectOne("emp.selectById", 7369);System.out.println(emp);//5.关闭资源session.close();}
}

3 增删改查的基本操作的实现

实现以下功能: 1. 查询所有员工信息; 2. 添加员工; 3. 更新员工; 4. 删除员工; 5. 根据员工名模糊查询。

3.1 查询所有员工信息

编写mapper文件

<!--
查询到数据返回多条记录,每一条封装在一个实体类对象中,所有的实体类对象封装在List集合中
resultType:指定的并不是集合的类型,而是单条数据所对应实体类类型
resultType="java.util.List" 错误的配置方式-->
<select id="select" resultType="com.gs.entity.Emp">select empno, ename, job, mgr, hiredate, sal, comm, deptno from emp order by empno desc
</select>

在测试类编写

public class CURDTest {@Testpublic void testSelect() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();}
}
/*** 查询多条记录
* selectList(statement-sql语句的id, parameter-参数)* 表示将单条记录都存储输出映射对象中,每条记录的映射对象存放在List集合中
*/
List<Emp> list = session.selectList("emp.select");
for (Emp emp : list) {System.out.println(emp);
}

3.2 添加员工

编写mapper文件

<!--
添加操作使用insert标签;
增删改操作没有resultType,只有查询有resultType;
因为增删改操作返回值都是int类型,所以我们不需要指明;
注意:给占位符赋值,#{}中编写的内容为实体类型参数中的成员变量名称;#{empno}    
Mybatis会从传递过来的参数对象里面得到emono字段的值--><insert id="insert" parameterType="com.gs.entity.Emp">insert into emp(ename,job,mgr,hiredate,sal,comm,deptno)values(#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})</insert>

在测试类编写

public class CURDTest {@Testpublic void testSelect() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();}
}Emp emp = new Emp();emp.setEname("TOM");emp.setJob("CLARK");emp.setMgr(1);emp.setHiredate(new Date());emp.setSal(6500.0);emp.setComm(1200.0);System.out.println("新增之前的主键值为:" + emp.getEmpno());int result = session.insert("emp.insert", emp);}System.out.println("影响数据库的条数为:" + result);/*** mybatis中的事务是jdbc的事务机制,mybatis里面默认是手动提交
*/session.commit();System.out.println("新增之后的主键值为:" + emp.getEmpno());session.close();

3.3 更新员工

编写mapper文件

<update id="update" parameterType="com.gs.entity.Emp">update emp set ename=#{ename},job=#{job},mgr=#{mgr},hiredate=#{hiredate},sal=#{sal},comm=#{comm},deptno=#{deptno} where empno=#{empno}</update>

在测试类编写

public class CURDTest {@Testpublic void testSelect() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();}
}Emp emp = new Emp();emp.setEmpno(7936);emp.setEname("JERRY");emp.setJob("MANAGER");emp.setMgr(7698);emp.setHiredate(new Date(new Date().getTime() + 1000*60*60*24));
emp.setSal(7800.0);emp.setComm(800.0);}int result = session.update("emp.update", emp);System.out.println("影响数据库的条数为:" + result);session.commit();session.close();
}

3.4 删除员工

编写mapper文件

<delete id="delete" parameterType="java.lang.Integer">delete from emp where empno=#{empno}</delete>

在测试类编写

public class CURDTest {@Testpublic void testSelect() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();}
}int result = session.delete("emp.delete", 7935);System.out.println("影响数据库的条数为:" + result);session.commit();}session.close();
}

3.4 根据员工名模糊查询

编写mapper文件

<!--
条件查询:模糊查询
1、#{}占位符,防止sql注入
需要在Java中将传入数据的前后拼接%符号
where ename like #{ename}2、使用字符串拼接函数
where ename like concat('%',#{ename},'%')3、${}拼接符号,实现sql的拼接
where ename like '%${value}%'
注意:${}不是占位符,如果输入参数为简单类型,${}中的内容必须为value-->
<select id="selectByEname1" parameterType="java.lang.String" 
resultType="com.gs.entity.Emp">select empno,ename,job,mgr,hiredate,sal,comm,deptno from empwhere ename like #{ename}</select>

在测试类编写

public class CURDTest {@Testpublic void testSelect() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();}
}String ename = "S";List<Emp> list = session.selectList("emp.selectByEname1", "%"+ename+"%");for (Emp emp : list) {System.out.println(emp);}session.close();
}

4 总结

4.1 parameterType和resultType

  1. parameterType:指定输入参数类型,MyBatis通过OGNL从输入对象中获取参数值设置在Sql中。
  2. resultType:指定输出结果类型,MyBatis将Sql查询结果的一行记录数据映射为resultType指定类型的 对象。

4.2 #{} 和 ${}

  1. #{}:
    1. #{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型、实体类类型、HashMap;
    2. #{}接收简单类型,#{}中可以写成value或其它名称;
    3. #{}接收实体类对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性…的方式获取对象属 性值。
  2. ${}:
    1. 表示一个拼接符号,有 S q l 注入风险,所以不建议使用 {}表示一个拼接符号,有Sql注入风险,所以不建议使用 表示一个拼接符号,有Sql注入风险,所以不建议使用{};
    2. ${}接收输入参数,类型可以是简单类型、实体类类型、HashMap;
    3. 接收简单类型, {}接收简单类型, 接收简单类型,{}中只能写成value;
    4. ${}接收实体类对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性…的方式获取对象属 性值。

4.3 selectOne和selectList

  1. selectOne表示查询出一条记录进行映射; 如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。
  2. selectList表示查询出一个列表(多条记录)进行映射; 如果使用selectList查询多条记录,不能使用selectOne。
  3. 如果使用selectOne报错:org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4

4.4 MyBatis和Hibernate区别

  1. Hibernate:是一个标准ORM框架(对象关系映射)。 入门门槛较高的,不需要程序写Sql,Sql语句自动生成,对Sql语句进行优化、修改比较困难的; 应用场景:适用与需求变化不多的中小型项目,比如:后台管理系统,erp、crm、oa…;
  2. MyBatis:专注于Sql本身,需要程序员自己编写Sql语句,Sql修改、优化比较方便。 MyBatis是一个不完全的ORM框架,虽然程序员自己写Sql,MyBatis也可以实现映射(输入映射、 输出映射); 应用场景:适用与需求变化较多的项目,比如:互联网项目;

4.5 Mybatis解决JDBC编程的问题

    1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问 题。
    2. 解决:在mybatis-config.xml中配置数据链接池,使用连接池管理数据库链接。
  1. Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变Java代码。
    1. 解决:将 Sql语句配置在XXXXmapper.xml文件中与Java代码分离。
  2. 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一 一 对应
    1. 解决:Mybatis自动将Java对象映射至sql语句,通过statement中的parameterType定义输入参数 的类型。
  3. 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo对象解析比较方便。
    1. 解决:Mybatis自动将sql执行结果映射至Java对象,通过statement中的resultType定义输出结果 的类型

相关文章:

Mybatis

1 什么是MyBatis MyBatis是一个优秀的持久层框架&#xff0c;它对JDBC操作数据库的过程进行封装&#xff0c;使开发者只需要关注 SQL 本身&#xff0c;而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、 结果集检索等JDBC繁杂的过程代码 。…...

uniapp学习(010-3 实现H5和安卓打包上线)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第114p-116p的内容 文章目录 H5配置文件设置开始打包上传代码 安卓设置模拟器启动设置基础配置设置图标启动界面…...

IPGuard与Ping32结合,提供企业级数据加密与防泄密解决方案,全面保障敏感数据安全

随着数字化转型的深入推进&#xff0c;企业面临着日益复杂的安全挑战。如何在确保数据流通的同时&#xff0c;保障企业的核心资产不被泄露&#xff0c;是每个企业必须面对的难题。为此&#xff0c;Ping32与IPGuard联合推出了一套全面的企业级数据加密与防泄密解决方案&#xff…...

爬虫与反爬-旋转验证码突破方案(知名短视频、TK海外版 及 某东等等)

概述&#xff1a;文本对旋转验证码进行了突破及讲述了实现原理&#xff0c;代码使用纯算法 OpenCV&#xff0c;使用代价较小同时不用安装一大堆AI训练相关的模组&#xff0c;方便且能够快速上手 当前亲自验证了能够支持的网站&#xff1a;国内知名短视频平台、海外版 以及 某东…...

霍夫变换:原理剖析与 OpenCV 应用实例

简介&#xff1a;本文围绕霍夫变换相关内容展开&#xff0c;先是讲解霍夫变换基本原理&#xff0c;包含从 xy 坐标系到 kb 坐标系及极坐标系的映射等。接着介绍了 cv2.HoughLines、cv2.HoughLinesP 概率霍夫变换、cv2.HoughCircles 霍夫圆变换的函数用法、参数含义、与常规霍夫…...

虚拟机之间复制文件

在防火墙关闭的前提下&#xff0c;您可以通过几种不同的方法将文件从一个虚拟机复制到另一个虚拟机。这里&#xff0c;我们假设您想要从 IP 地址为 192.168.4.5 的虚拟机上的 /tmp 文件夹复制文件到当前虚拟机&#xff08;192.168.4.6&#xff09;的 /tmp 文件夹下。以下是几种…...

漏洞管理与补丁管理详解:系统安全的基石

文章目录 漏洞管理与补丁管理详解&#xff1a;系统安全的基石什么是漏洞管理&#xff1f;什么是补丁管理&#xff1f;漏洞管理与补丁管理的联系与区别实施漏洞管理与补丁管理的最佳实践 漏洞管理与补丁管理详解&#xff1a;系统安全的基石 在网络安全的防护体系中&#xff0c;…...

ArrayList与LinkedList的区别是什么?

ArrayList与LinkedList是Java集合框架中实现List接口的两种常见类&#xff0c;它们各自具有独特的数据结构和特点&#xff0c;适用于不同的应用场景。 一、底层数据结构 ArrayList和LinkedList的底层数据结构是它们之间最本质的区别。 ArrayList&#xff1a; ArrayList是基于…...

《Java-数组》

《Java-数组》 1.数组介绍 概念&#xff1a;数组是一种容器&#xff0c;用来存储同种数据类型的多个值。注意&#xff1a;数组容器在存储数据的时候&#xff0c;需要结合隐式转换考虑&#xff1b; 2.数组的定义和初始化 2.1数组定义 定义格式1&#xff08;常用&#xff09…...

Docker 实战:搭建本地 Registry 私有镜像仓库及批量导入脚本

前言&#xff1a;在我之前的博客中&#xff0c;我分享了 Harbor 仓库搭建的详细操作步骤。然而&#xff0c;在实际的生产环境中&#xff0c;并非每个 Docker 环境都需要部署一个规模庞大的 Harbor 仓库。有时&#xff0c;一个轻量级的本地 Registry 私有镜像仓库会更为便捷。本…...

MySQL 启动失败问题分析与解决方案:`mysqld.service failed to run ‘start-pre‘ task`

目录 前言1. 问题背景2. 错误分析2.1 错误信息详解2.2 可能原因 3. 问题排查与解决方案3.1 检查 MySQL 错误日志3.2 验证 MySQL 配置文件3.3 检查文件和目录权限3.4 手动启动 MySQL 服务3.5 修复 systemd 配置文件3.6 验证依赖环境 4. 进一步优化与自动化处理结语 前言 在日常…...

java-分而治之算法

分而治之&#xff08;Divide and Conquer&#xff09;算法是一种解决问题的策略&#xff0c;它将一个复杂的问题分解成若干个相同或相似的子问题&#xff0c;递归地解决这些子问题&#xff0c;然后将它们的解合并以解决原始问题。这种算法通常用于排序、搜索、数学计算等领域。…...

透明化教育管理:看板如何提升班级整体效率

随着教育信息化的不断推进&#xff0c;传统的教学和班级管理方式逐渐暴露出时间紧、任务繁、多任务并行等问题。看板管理&#xff0c;作为一种高效的可视化工具&#xff0c;正在成为教师管理教学、提升班级协作与互动的重要利器。通过透明化、系统化的管理方式&#xff0c;看板…...

UDP客户端服务器通信

在这篇博客中&#xff0c;我们将探索 UDP&#xff08;用户数据报协议&#xff09; 通信&#xff0c;简要地说&#xff0c;UDP 是一种无连接、快速但不可靠的通信协议&#xff0c;适用于需要快速数据传输但对丢包容忍的场景&#xff0c;比如视频流和在线游戏。就像《我是如此相信…...

helm手动部署Kafka集群

1、到指定node节点创建pv需挂载的目录&#xff0c;若有分布式存储可忽略 mkdir -p /data/kafka-data-0 mkdir -p /data/kafka-data-1 mkdir -p /data/kafka-data-2 mkdir -p /data/kafka-zookeeper-data-0 2、创建pvc ---apiVersion: v1kind: PersistentVolumemetadata:n…...

vue3 ajax获取json数组排序举例

使用axios获取接口数据 可以在代码中安装axios包&#xff0c;并写入到package.json文件&#xff1a; npm install axios -S接口调用代码举例如下&#xff1a; const fetchScore async () > {try {const res await axios.get(http://127.0.0.1:8000/score/${userInput.v…...

c/c++ 用easyx图形库写一个射击游戏

#include <graphics.h> #include <conio.h> #include <stdlib.h> #include <time.h>// 定义游戏窗口的大小 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600// 定义玩家和目标的尺寸 #define PLAYER_SIZE 50 #define TARGET_SIZE 20// 玩家的结构…...

大数据新视界 -- 大数据大厂之 Hive 数据安全:权限管理体系的深度解读(上)(15/ 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

gitee:创建仓库,存入本地文件至仓库

一、git下载 git:下载与安装-CSDN博客https://blog.csdn.net/weixin_46001736/article/details/144107485?sharetypeblogdetail&sharerId144107485&sharereferPC&sharesourceweixin_46001736&spm1011.2480.3001.8118 二、创建仓库 1、主页面->右上角新增…...

联想品牌的电脑 Bios 快捷键是什么?如何进入 Bios 设置?

在某些情况下&#xff0c;您可能需要通过U盘来安装操作系统或进行系统修复。对于联想电脑用户来说&#xff0c;了解如何设置U盘作为启动设备是非常有用的技能之一。本文简鹿办公将指导您如何使用联想电脑的 U 盘启动快捷键来实现这一目标。 联想笔记本 对于大多数联想笔记本电…...

微信小程序用户登录页面制作教程

微信小程序用户登录页面制作教程 前言 在微信小程序的开发过程中,用户登录是一个至关重要的功能。通过用户登录,我们可以为用户提供个性化的体验,保护用户数据,并实现更复杂的业务逻辑。本文将为您详细讲解如何制作一个用户登录页面,包括设计思路、代码示例以及实现细节…...

Flink细粒度的资源管理

Apache Flink致力于为所有应用程序自动导出合理的默认资源需求。对于希望根据其特定场景微调其资源消耗的用户,Flink提供了细粒度的资源管理。这里我们就来看下细粒度的资源管理如何使用。(注意该功能目前仅对DataStream API有用) 1. 适用场景 使用细粒度的资源管理的可能…...

Jenkins环境搭建及简单介绍

一、jenkins介绍 1、持续集成&#xff08;CI&#xff09; Continuous integration 持续集成 团队开发成员每天都有集成他们的工作&#xff0c;通过每个成员每天至少集成一次&#xff0c;也就意味着一天有可 能多次集成。在工作中我们引入持续集成&#xff0c;通过持续集成自动…...

如何还原 HTTP 请求日志中的 URL 编码参数?详解 %40 到 @

在记录HTTP请求的日志中出现了这样的情况&#xff1a; 2024-11-20 11:12:49 INFO network_request gz_login 96 Body: countryAbbrCN&countryCode86&email1222405567%40qq.com&password12354e50456db124f9f34e2789308733&type1 出现这种情况的原因是&#x…...

box-im学习

box-im gitee代码 box-im 语雀文档 box-im 在线体验 部署说明 需要启动下列服务 ## ## 1、启动minio ## MINIO_ROOT_USERminioadmin MINIO_ROOT_PASSWORDxxx nohup /boxim/minio/minio server /boxim/minio/data --console-address ":9001" --address "…...

faiss库中ivf-sq(ScalarQuantizer,标量量化)代码解读-6

调试 经过gdb调试获取的调用栈内容如下&#xff0c;链接&#xff1a; 步骤函数名称文件位置说明1faiss::IndexFlatCodes::add/faiss/IndexFlatCodes.cpp:24在 add 方法中&#xff0c;检查是否已经训练完成&#xff0c;准备添加向量到索引中。2std::vector<unsigned char&g…...

flutter开发环境—Windows

一、简介 我们使用最新版的flutter版本安装。 参考链接 名称地址官方网站https://flutter.dev/官方中文网站文档 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter软件下载路径https://docs.flutter.dev/release/archive?tabwindows 二、操作流程 2.1 下载软件 点…...

【计网】自定义序列化反序列化(二) —— 实现网络版计算器【上】

&#x1f30e; 实现网络版计算器【上】 文章目录&#xff1a; 实现网络版计算器【上】 自定义协议       制定自定义协议 Jsoncpp序列化反序列化       Json::Value类       Jsoncpp序列化       Jsoncpp反序列化 自定义协议序列化反序列化      …...

Harbor安装、HTTPS配置、修改端口后不可访问?

Harbor安装、HTTPS配置、修改端口后不可访问&#xff1f; 大家好&#xff0c;我是秋意零。今天分享Harbor相关内容&#xff0c;安装部分可完全参考官方文档&#xff0c;写的也比较详细。 安装Harbor 官方文档&#xff1a;https://goharbor.io/docs/2.12.0/install-config/ …...

React中高阶组件HOC详解

高阶组件&#xff08;Higher-Order Component&#xff0c;简称 HOC&#xff09;是 React 中的一种设计模式&#xff0c;用于复用组件逻辑。它本质上是一个函数&#xff0c;接收一个组件作为参数&#xff0c;并返回一个新的组件。 1. HOC 的定义 HOC 是一个函数&#xff0c;类…...

网络原理(一)—— http

什么是 http http 是一个应用层协议&#xff0c;全称为“超文本传输协议”。 http 自 1991 年诞生&#xff0c;目前已经发展为最主流使用的一种应用层协议。 HTTP 往往基于传输层的 TCP 协议实现的&#xff0c;例如 http1.0&#xff0c;http1.0&#xff0c;http2.0 http3 是…...

redis学习面试

1、数据类型 string 增删改查 set key valueget keydel kstrlen k 加减 incr articleincrby article 3decr articledecyby article 取v中特定位置数据 getrange name 0 -1getrange name 0 1setrange name 0 x 设置过期时间 setex pro 10 华为 等价于 set pro 华为expire pro…...

前端工程化18-邂逅Promise(待更新)

6、邂逅Promise 6.1、函数对象与实例对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>准备_函数对象与实例对象</title> </head> <body><script>/* 函数对象、实例对象…...

Linux(ubuntu)系统的一些基本操作和命令(持续更新)

操作&#xff1a; Ctrl Alt T&#xff08;打开命令终端&#xff09; Ctrl Shift &#xff08;放大命令终端窗口&#xff09; Ctrl c&#xff08;退出当前在终端运行的程序&#xff09; 在命令终端窗口按Tab键可以补全要写的命令 命令&#xff1a; pwd&#xff08;查…...

IDEA Mac快捷键(自查询使用)

Editing&#xff08;编辑&#xff09; Control Space 基本的代码补全&#xff08;补全任何类、方法、变量&#xff09;Control Shift Space 智能代码补全&#xff08;过滤器方法列表和变量的预期类型&#xff09;Command Shift Enter 自动结束代码&#xff0c;行末自动添…...

认识redis 及 Ubuntu安装redis

文章目录 一. redis概念二. redis应用场景二. redis的特性四. 使用Ubuntu安装redis 一. redis概念 redis 是在内存中存储数据的中间件, 用在分布式系统 redis是客户端服务器结构的程序, 客户端服务器之间通过网络来通信 二. redis应用场景 redis可用作数据库 类似MySQL, 但…...

6.结果处理组件之ResponseHandler

前言 feign发送完请求后, 拿到返回结果, 那么这个返回结果肯定是需要经过框架进一步处理然后再返回到调用者的, 其中ResponseHandler就是用来处理这个返回结果的, 这也是符合正常思维的处理方式, 例如springmvc部分在调用在controller端点前后都会增加扩展点。 从图中可以看得…...

【C#】调用外部应用

以WINFORM应用程序为例&#xff0c;在C#应用程序中调用PYTHON程序&#xff08;Matplotlib绘制图形程序&#xff09;&#xff0c;将调用PYTHON程序生成的窗口程序嵌入在WINFORM窗口中 窗口程序类 using System; using System.Collections.Generic; using System.Data; using S…...

JavaWeb--JDBC

JDBC&#xff08;Java Database Connectivity&#xff0c;Java数据库连接&#xff09;是一种Java API&#xff0c;可以让Java程序连接到数据库并进行数据的操作。它是Java平台的一部分&#xff0c;由Sun Microsystems&#xff08;现为Oracle Corporation的一部分&#xff09;开…...

神经网络归一化方法总结

在深度学习中&#xff0c;归一化 是提高训练效率和稳定性的关键技术。以下是几种常见的神经网络归一化方法的总结&#xff0c;包括其核心思想、适用场景及优缺点。 四种归一化 特性Batch NormalizationGroup NormalizationLayer NormalizationInstance Normalization计算维度…...

Debian/Ubuntu 、Fedora 、Arch Linux, 在Linux上,对文本文件进行多线程压缩 xz、pxz、zstd、7z、lrzip

Debian/Ubuntu 、Fedora 、Arch Linux&#xff0c; 在Linux上&#xff0c;对文本文件进行多线程压缩 xz、pxz、zstd、7z、lrzip 前言对比多线程压缩1. 使用 pxz安装 pxz使用 pxz 2. 使用 xz 的 -T 选项使用 xz -T 3. 其他压缩命令1. 使用 gzip2. 使用 bzip23. 使用 xz4. 使用 7…...

前端使用fontfaceobserver库实现字体设置

要使用FontFaceObserver来加载设置项目本地的字体&#xff0c;先确保字体文件位于项目中或者可以从服务端获取到&#xff0c;这样就可以使用FontFaceObserver来检测并加载这些字体 主要有以下几步&#xff1a; npm或者yarn安装引入fontfaceobserver字体资源引入和font-face配置…...

SSM--SpringMVC复习(二)

请求 URL匹配&#xff1a; RequestMapping RequestMapping 负责将请求映射到对应的控制器方法上。 RequestMapping 注解可用于类或方法上。用于类上&#xff0c;表示类中的所有响应请求的方法都以该地址作为父路径。 在整个 Web 项目中&#xff0c;RequestMapping 映射的请求…...

Oracle 11gR2 坏块修复实例一则

背景 前段时间在 Oracle 11gR2 数据库中发现了坏块问题。环境是 64 位 Linux 平台。本文将详细介绍如何使用 DBMS_REPAIR 进行在线修复&#xff0c;当然也可以基于备份和 RMAN 的修复方法这里暂时不做介绍。 发现坏块 1. 从 alert.log 中发现错误 在 alert.log 文件中发现了…...

使用 Docker Compose 来编排部署LMTNR项目

使用 Docker Compose 来部署一个包含 Linux、MySQL、Tomcat、Nginx 和 Redis 的完整项目的例子。假设我们要部署一个简单的 Java Web 应用&#xff0c;并且使用 Nginx 作为反向代理服务器。 项目目录结构 首先需要确保 Docker 和docker-compose已经安装并正在运行。docker --v…...

el-table 根据屏幕大小 动态调整max-height 的值

<template><div><p>窗口高度&#xff1a;{{ windowHeight }} px</p></div> </template><script> export default {data() {return {// 下面的 -250 表示减去一些表单元素高度 这个值需要自己手动调整windowHeight: document.docume…...

el-cascader 使用笔记

1.效果 2.官网 https://element.eleme.cn/#/zh-CN/component/cascader 3.动态加载&#xff08;官网&#xff09; <el-cascader :props"props"></el-cascader><script>let id 0;export default {data() {return {props: {lazy: true,lazyLoad (…...

Cookie概念和API

Cookie概念 Cookie在HTTP中它表示服务器送给客户端浏览器的小甜点。其实Cookie就是一个键和一个值构成的&#xff0c;随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来&#xff0c;当下一次再访问服务器时把Cookie再发送给服务器。 Cookie是由服务器…...

Linux服务器安装mongodb

因为项目需要做评论功能&#xff0c;领导要求使用mongodb&#xff0c;所以趁机多学习一下。 在服务器我们使用docker安装mongodb 1、拉取mongodb镜像 docker pull mongo &#xff08;默认拉取最新的镜像&#xff09; 如果你想指定版本可以这样 docker pull mongo:4.4&#…...

32.4 prometheus存储磁盘数据结构和存储参数

本节重点介绍 : prometheus存储磁盘数据结构介绍 indexchunkshead chunksTombstoneswal prometheus对block进行定时压实 compactprometheus 查看支持的存储参数 prometheus存储示意图 内存和disk之间的纽带 wal WAL目录中包含了多个连续编号的且大小为128M的文件&#xff0c…...