JavaWeb02-MyBatis

目录

一、MyBatis

1.概述

2.JavaEE三层架构简单介绍

(1)表现层

(2)业务层

(3)持久层

3.框架

4.优势

(1)JDBC的劣势

(2)MyBatis优化

5.使用

(1)快速上手

(2)框架使用部分

(3)编码部分

6.Mapper代理开发

(1)Mapper代理开发的好处

(2)Mapper代理使用步骤

7.Mybatis的配置文件说明

8.查询过程出现的问题

9.xml文件中编写SQL语句没有提示

10.查操作

(1)单条件查询

(2)多条件查询

11.动态查询

(1)多条件动态查询

(2)单条件动态查询(多选一)

12.增操作

(1)主键返回

13.删操作

14.改操作

(1)修改字段数据

(2)修改动态字段数据

15.删操作

(1)单个删除

(2)批量删除

16.Mybatis参数传递

(1)单个参数

(2)多个参数

17.注解方式完成增删改查


一、MyBatis

1.概述

  • MyBatis 是一款优秀的持久层框架,用于简化JDBC 开发

  • MyBatis 本是Apache 的一个开源项目iBatis,2010年这个项目由apache softwarefoundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github

  • 网址:mybatis – MyBatis 3 | 简介

辅助插件:MybatisX

2.JavaEE三层架构简单介绍

(1)表现层

页面展示

(2)业务层

逻辑处理

(3)持久层

负责将数据到保存到数据库的那一层代码

3.框架

  • 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型

  • 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展

4.优势

(1)JDBC的劣势
  • 硬编码

    • 注册驱动,获取连接

    • SQL语句

  • 操作较繁琐

    • 手动设置参数

    • 手动封装结果集

(2)MyBatis优化

MyBatis 免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作

5.使用

(1)快速上手

框架使用部分:

  • 创建模块,导入坐标

  • 编写核心配置文件

  • 编写SQL映射文件

编码部分:

  • 定义实体类(POJO类)

  • 加载核心配置文件,获取SqlSessionFactory对象

  • 获取SqlSession对象

  • 释放资源

(2)框架使用部分
  • 导入坐标

     
   <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency>
<!--        mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><!--单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency>
​<!-- 添加slf4j日志api --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.20</version></dependency><!-- 添加logback-classic依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!-- 添加logback-core依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency>

  • 核心配置文件,文件名通常:mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED">
<!--                数据库连接信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///test?useSSL=false&amp;useServerPrepStmts=true"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><mappers>
<!--        加载SQL的映射文件--><mapper resource="ProductMapper.xml"/></mappers>
</configuration>

  • 编写SQL映射文件,名称:要操作的表名+Mapper(ProductMapper.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:名称空间
​
-->
<mapper namespace="product">
<!--id:sql语句的唯一标识resultType:返回结果类型
--><select id="selectAll" resultType="pojo.Product">select * from Product;</select>
</mapper>

如果映射文件SQL语句中表名爆红,只是警告,并不影响实际操作

产生原因:ldea和数据库没有建立连接,不识别表信息

解决方法:用IDEA与数据库建立连接即可

(3)编码部分
  • 定义实体类

要与数据库中的数据类型对应

  • 使用

public class MybatisDemo {public static void main(String[] args) throws IOException {
//        1.加载核心配置文件,直接从官网粘过来就行了,获取SqlSessionFactory对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
​
//        2.获取sqlSession对象final SqlSession sqlSession = sqlSessionFactory.openSession();
​
//        3.执行SQLfinal List<Product> list = sqlSession.selectList("product.selectAll");
​System.out.println(list);
//        4.释放资源sqlSession.close();
​}
}

6.Mapper代理开发

(1)Mapper代理开发的好处
  • 解决原生方式中的硬编码(更安全)

  • 简化后期执行SQL

(2)Mapper代理使用步骤
  • 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下

检查方式:编译项目

在文件夹中打开

如下图即为成功

  • 设置SQL映射文件的namespace属性为Mapper接口全限定名

  • 在Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致

如果Mapper接口名称和SQL映射文件名称相同,并且在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载,如下图

  • 编码

    • 通过 SqlSession的 getMapper方法获取 Mapper接口的代理对象

    • 调用对应方法完成sql的执行

//        3.执行SQL
//        3-1.获取接口的代理对象final ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);final List<Product> products = mapper.selectAll();products.forEach(product -> System.out.println(product));

7.Mybatis的配置文件说明

可访问网址查看,后续再补

8.查询过程出现的问题

如以下情况

原因:实体类属性名称与数据库字段名称不一致,导致不能自动封装数据

解决方法一:

  • 为数据库字段起别名,让其和实体类属性名称一致(麻烦,不推荐)

方法一的优化方案:

  • 写一个SQL语句块,不灵活,还是不推荐~

解决方法二:

  • 结果映射,resultMap【有两个子标签,一个result,一个id,其中id子标签用来完成主键字段的映射,result用来映射普通字段的映射,使用方法与result一致】

  • type支持别名

再次运行

9.xml文件中编写SQL语句没有提示

在xml文件中按alt+enter

往下拉,根据安装的数据库选择合适的即可

10.查操作

(1)单条件查询
<!--参数占位符:1.#{}:将其替换为?,为了防止SQL注入。      使用场景:参数传递2.${}:拼SQL,存在SQL注入问题。           使用场景:表名或列名不固定的情况,但要注意SQL注入问题
​参数类型:parameterType,可以省略
​特殊字符处理:1.转义字符:适合少量2.CDATA区:适合大量,CD回车即可
--><select id="selectById"  resultMap="resultMap_Employee">select * from employees where emp_no = #{id}</select>
​<resultMap id="resultMap_Employee" type="employee">
<!--        将不一样的属性名写一下即可--><result column="emp_no" property="empNo"/><result column="birth_date" property="birthDate"/><result column="first_name" property="firstName"/><result column="last_name" property="lastName"/><result column="hire_date" property="hireDate"/>
​</resultMap>

(2)多条件查询

Mybatis提供了三种方式:

mapper.xml:

<select id="selectByCondition01" resultMap="resultMap_Employee">select *from employeeswhere emp_no > #{empNo}and gender = #{gender}
</select>
​
<select id="selectByCondition02" resultMap="resultMap_Employee">select *from employeeswhere emp_no > #{empNo}and gender = #{gender}
</select>
​
<select id="selectByCondition03" resultMap="resultMap_Employee">select *from employeeswhere emp_no > #{empNo}and gender = #{gender}
</select>
​<resultMap id="resultMap_Employee" type="employee">
<!--        将不一样的属性名写一下即可--><result column="emp_no" property="empNo"/><result column="birth_date" property="birthDate"/><result column="first_name" property="firstName"/><result column="last_name" property="lastName"/><result column="hire_date" property="hireDate"/>
​</resultMap>

pojo实体类:

public class Employee {private Integer empNo;private Date birthDate;private String firstName;private String lastName;private Character gender;private Date hireDate;
​public Employee() {}
​public Employee(Integer empNo, Character gender) {this.empNo = empNo;this.gender = gender;}
​public Employee(Integer empNo, Date birthDate, String firstName, String lastName, Character gender, Date hireDate) {this.empNo = empNo;this.birthDate = birthDate;this.firstName = firstName;this.lastName = lastName;this.gender = gender;this.hireDate = hireDate;}
​public Integer getEmpNo() {return empNo;}
​public void setEmpNo(Integer empNo) {this.empNo = empNo;}
​public Date getBirthDate() {return birthDate;}
​public void setBirthDate(Date birthDate) {this.birthDate = birthDate;}
​public String getFirstName() {return firstName;}
​public void setFirstName(String firstName) {this.firstName = firstName;}
​public String getLastName() {return lastName;}
​public void setLastName(String lastName) {this.lastName = lastName;}
​public Character getGender() {return gender;}
​public void setGender(Character gender) {this.gender = gender;}
​public Date getHireDate() {return hireDate;}
​public void setHireDate(Date hireDate) {this.hireDate = hireDate;}
​@Overridepublic String toString() {return "Employee{" +"empNo=" + empNo +", birthDate=" + birthDate +", firstName='" + firstName + '\'' +", lastName='" + lastName + '\'' +", gender=" + gender +", hireDate=" + hireDate +'}';}
}

mapper.EmployeeMapper

/*** 条件查询01* 查询员工工号>?且性别为?的所有员工信息* *参数接收方式* 1.散装参数:如果方法中有多个参数,需要使用@Param("SQL参数占位符名称”)* @param empNo 员工工号* @param character 性别* @return Employee对象集合*/
List<Employee> selectByCondition01(@Param("empNo")int empNo,@Param("gender")Character character);
​
/*** 条件查询02:实体类封装参数* @param employee 员工对象,注意对象的属性名称要和SQL参数占位符名称一致* @return 员工对象集合*/
List<Employee> selectByCondition02(Employee employee);
​
/*** 条件查询03:map集合* @param map map集合,要保证SQL中的参数占位符名称和map集合的键名称一致* @return 员工对象集合*/
List<Employee> selectByCondition03(Map map);

测试:

@Test
public void selectByCondition01() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
​final SqlSession sqlSession = sqlSessionFactory.openSession();
​final List<Employee> employees = sqlSession.getMapper(EmployeeMapper.class).selectByCondition01(10001, 'F');employees.forEach(employee -> System.out.println(employee));sqlSession.close();
}@Testpublic void selectByCondition022() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
​final SqlSession sqlSession = sqlSessionFactory.openSession();
​
//        final List<Employee> employees = sqlSession.getMapper(EmployeeMapper.class).selectByCondition02(new Employee(10001,'F'));Employee employee = new Employee();employee.setEmpNo(10001);employee.setGender('F');final List<Employee> employees = sqlSession.getMapper(EmployeeMapper.class).selectByCondition02(employee);employees.forEach(e -> System.out.println(e));sqlSession.close();}
@Test
public void selectByCondition03() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
​final SqlSession sqlSession = sqlSessionFactory.openSession();Map map = new HashMap();Integer empNo = 10001;Character gender = 'F';map.put("empNo",empNo);map.put("gender",gender);
​final List<Employee> employees = sqlSession.getMapper(EmployeeMapper.class).selectByCondition03(map);employees.forEach(e -> System.out.println(e));sqlSession.close();
}

11.动态查询

SQL语句会随着用户的输入或外部条件的变化而变化,我们称为 动态SQL

mybatis对动态SQL用很大的支撑

  • if:条件判断

    • test:逻辑判断

  • choose(when,otherwise)

  • trim(where,set)

  • foreach

更具体的可查阅官网,动态SQL

(1)多条件动态查询

修改一下:

<select id="selectByCondition03" resultMap="resultMap_Employee">select *from employeeswhere<if test="empNo != null and empNo != ''">emp_no > #{empNo}</if><if test="gender !=null ">and gender = #{gender}</if>
​
</select>

测试时会发现如果没有第一个参数后面会报错

解决方法:

  • 第一种方法:统一格式,第一个条件为一个恒等式

            where
#             恒等式<if test="empNo != null and empNo != ''">and emp_no > #{empNo}</if><if test="gender !=null ">and gender = #{gender}</if>
  • 第二种方法:使用< where >标签替换where关键字

<where><if test="empNo != null and empNo != ''">and emp_no > #{empNo}</if><if test="gender !=null ">and gender = #{gender}</if>
</where>

测试:

(2)单条件动态查询(多选一)
<select id="selectByConditionSingle" resultMap="resultMap_Employee">select * from employeeswhere<choose><when test="empNo != null">emp_no > #{empNo}</when><when test="gender !=null">gender = #{gender}</when><when test="lastName != null">last_name like #{lastName}</when><otherwise>
<!--                相当于java switch中的default,写个恒等式即可-->1 = 1</otherwise></choose></select>

或者

<where><choose><when test="empNo != null">emp_no > #{empNo}</when><when test="gender !=null">gender = #{gender}</when><when test="lastName != null">last_name like #{lastName}</when></choose>
</where>

12.增操作

<insert id="add">insert into employees(first_name,last_name,gender,birth_date,hire_date)VALUES(#{firstName},#{lastName},#{gender},#{birthDate},#{hireDate})
</insert>

测试的时候会发现代码运行成功但并没有数据!

打开日志,会发现roll back了

观察日志就会发现 -Setting autocommit to false on JDBC Connection

所以在增操作后,需要使用commit()手动提交一次事务!

再次运行,数据添加成功

如果不想手动提交,可在openSession()传递布尔值以开启是否自动提交

  • mybatis默认是开启事务的

(1)主键返回

目的:添加完数据后,获取该数据的id值

<insert id="add" useGeneratedKeys="true" keyProperty="empNo">insert into employees(first_name,last_name,gender,birth_date,hire_date)VALUES(#{firstName},#{lastName},#{gender},#{birthDate},#{hireDate})
</insert>

13.删操作

同增

14.改操作

(1)修改字段数据
void update(Employee employee);
<update id="update">update employeessetfirst_name = #{firstName},last_name = #{lastName},gender = #{gender}where emp_no = #{empNo}
</update>

(2)修改动态字段数据
<update id="update02">update employees<set><if test="firstName != null and firstName != ''">first_name = #{firstName},</if><if test="lastName != null and lastName != ''">last_name = #{lastName}</if></set>where emp_no = #{empNo}
​
</update>

15.删操作

(1)单个删除
void deleteById(Integer empNo);
<delete id="deleteById">deletefrom employeeswhere emp_no = #{empNo}
</delete>
(2)批量删除
/*** 批量删除* @param empNos id数组*/
void deleteByIds(@Param("empNos") Integer[] empNos);
<!--    mybatis会将数组参数封装为一个map集合默认 key = arrayvalue = 对应数组可以使用@Param改变map集合的默认key名称foreach属性:separator分隔符-->
<delete id="deleteByIds">delete from employeeswhere emp_no in<foreach collection="empNos" item="empNo" separator="," open="(" close=")">#{empNo}</foreach>;
</delete>

/*** 批量删除02* @param empNos id数组*/
void deleteByIds02(Integer[] empNos);
<delete id="deleteByIds02">delete from employeeswhere emp_no in (<foreach collection="array" item="empNo" separator=",">#{empNo}</foreach>);
​
</delete>

测试

Integer[] integers = {10023,10024,10025,10026,10027,10018,10019,10020,10021,10022};
try {sqlSession.getMapper(EmployeeMapper.class).deleteByIds(integers);sqlSession.commit();
} catch (Exception e) {System.out.println("删除失败");e.printStackTrace();
}

16.Mybatis参数传递

(1)单个参数
  • pojo实体类:直接使用,属性名和参数占位符名称一致即可

  • Map集合:直接使用,键名和参数占位符名称一致即可

  • Collection:封装为map

  • List:封装为map

  • Array:封装为map

  • 其他:直接使用

(2)多个参数
  • 会将参数列表封装为map集合,由于默认可读性太差,可以使用@Param替换Map集合中默认的arg键名

  • map.put(”arg0“,参数值1)

  • map.put(”param1“ ,参数值1)

  • map.put(”param2“,参数值2)

  • map.put(”arg1“,参数值2)

MyBatis提供了 ParamNameResolver 类来进行参数封装

封装方法为getNamedParams

  1. 在IDEA中,按住ctrl+shift+a打开action

  2. 将 ParamNameResolver粘进搜索框,选择Classes

  3. 搜索出来第一个就是,点进去

  4. 之后ctrl f。在搜索框输入getNamedParams

17.注解方式完成增删改查

使用注解方式会比配置文件开发更加高效

  • 查询:@Select

  • 添加;@Insert

  • 修改:@Update

  • 删除:@Delete

/*** 根据id查询* @param empNo id* @return Employee对象*/
@Select("select * from employees where emp_no = #{empNo}")
Employee selectById(int empNo);

注意:

  • 注解完成简单功能

  • 配置文件完成复杂功能,(动态SQL)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2777180.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

第六章:纹理贴图

本文是《从0开始图形学》笔记的第六章,介绍模型纹理的实现,涉及到重心坐标的计算方式和作用,本章之后,我们的模型将从单色变成更为丰富的彩色。 纹理贴图数据格式 前面几章我们已经可以将复杂的模型渲染出来了,但是模型还是单色的,这显然是不够的,模型还需要各种各样的…

除夕快乐(前端小烟花)

家人们&#xff0c;新的一年好运常在&#xff0c;愿大家在新的一年里得偿所愿&#xff0c;发财暴富&#xff0c;愿大家找到属于自己的那个公主&#xff0c;下面就给大家展示一下给公主的烟花 前端烟花 新的一年&#xff0c;新的挑战&#xff0c;愿我们不忘初心&#xff0c;砥砺…

【C生万物】数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

教你如何生成自己的专属动态龙新年图像 - Python实现摘要

引言 新年将至&#xff0c;为了给大家带来一丝喜庆和神秘的气氛&#xff0c;我决定用Python编写一个生成专属动态龙图像的小程序。通过这个程序&#xff0c;你可以生成一个独一无二的龙图像&#xff0c;并为它添加动态效果&#xff0c;让它在新年的时刻为你带来好运和祝福。 正…

生成式人工智能攻击的一年:2024

趋势科技最近公布了其关于预期最危险威胁的年度研究数据。生成人工智能的广泛可用性和质量将是网络钓鱼攻击和策略发生巨大变化的主要原因。 趋势科技宣布推出“关键可扩展性”&#xff0c;这是著名年度研究的新版本&#xff0c;该研究分析了安全形势并提出了全年将肆虐的网络…

学习Android的第七天

目录 Android EditText 输入框 设置默认提示文本 范例 获得焦点后全选组件内所有文本内容 范例 限制EditText输入类型 android:inputType 值列表 范例 设置最小行&#xff0c;最多行&#xff0c;单行&#xff0c;多行&#xff0c;自动换行 范例 设置文字间隔 范例 …

力扣231. 2 的幂(数学,二分查找,位运算)

Problem: 231. 2 的幂 文章目录 题目描述思路即解法复杂度Code 题目描述 思路即解法 思路1&#xff1a;位运算 1.易验证2的幂为正数&#xff1b; 2.易得2的幂用二进制表示只能有一个位为数字1 3.即将其转换为二进制统计其二进制1的个数 思路2&#xff1a;数学 当给定数n大于1时…

MATLAB实现LSTM时间序列预测

LSTM模型可以在一定程度上学习和预测非平稳的时间序列&#xff0c;其具有强大的记忆和非线性建模能力&#xff0c;可以捕捉到时间序列中的复杂模式和趋势[4]。在这种情况下&#xff0c;LSTM模型可能会自动学习到时间序列的非平稳性&#xff0c;并在预测中进行适当的调整。其作为…

Maui blazor ios 按设备类型设置是否启用safeArea

需求&#xff0c;新做了个app&#xff0c; 使用的是maui blazor技术&#xff0c;里面用了渐变背景&#xff0c;在默认启用SafeArea情况下&#xff0c;底部背景很突兀 由于现版本maui在SafeArea有点bug&#xff0c;官方教程的<ContentPage SafeAreafalse不生效&#xff0c;于…

攻防世界 CTF Web方向 引导模式-难度1 —— 11-20题 wp精讲

PHP2 题目描述: 暂无 根据dirsearch的结果&#xff0c;只有index.php存在&#xff0c;里面也什么都没有 index.phps存在源码泄露&#xff0c;访问index.phps 由获取的代码可知&#xff0c;需要url解码(urldecode )后验证id为admin则通过 网页工具不能直接对字母进行url编码 …

物联网数据隐私保护技术

在物联网&#xff08;IoT&#xff09;的世界中&#xff0c;无数的设备通过互联网连接在一起&#xff0c;不断地收集、传输和处理数据。这些数据有助于提高生产效率、优化用户体验并创造新的服务模式。然而&#xff0c;随着数据量的剧增&#xff0c;数据隐私保护成为了一个不能忽…

centos中docker操作

一、安装docker 确保系统是CentOS 7并且内核版本高于3.10,可以通过uname -r命令查看内核版本。 更新系统软件包到最新版本,可以使用命令yum update -y。 安装必要的软件包,包括yum-utils、device-mapper-persistent-data和lvm2。使用命令yum install -y yum-utils devic…

科研绘图-半小提琴图-

文章目录 前言1.软件安装-Origin 20222.绘制半小提琴图3.绘制径向条形图 前言 本文叙述记录的是一些科研绘图的实现方法&#xff0c;具体介绍从软件安装到实现图表绘制的详细过程。 1.软件安装-Origin 2022 Origin是一款具有丰富绘图功能的科研绘图软件&#xff0c;安装过程…

《MySQL 简易速速上手小册》第8章:事务管理和锁定策略(2024 最新版)

文章目录 8.1 理解 MySQL 中的事务8.1.1 基础知识8.1.2 重点案例&#xff1a;使用 Python 实现银行转账事务8.1.3 拓展案例 1&#xff1a;处理并发事务8.1.4 拓展案例 2&#xff1a;使用 Python 监控事务状态 8.2 锁定机制和事务隔离级别8.2.1 基础知识讲解8.2.2 重点案例&…

?你咋知道我的电脑密码的?---> Mimikatz!

还记得昨天在内网中提到了mimikatz这个工具&#xff0c;那么今天就来和大家讲一下这一款牛逼的工具 但是在这里先祝自己和各位看官新年快乐&#xff0c;万事顺遂 &#x1f409;&#x1f432;&#x1f432;&#x1f432;&#x1f432; 1.Mimikatz的介绍 传说呢&#xff0c;是…

IOS破解软件安装教程

对于很多iOS用户而言&#xff0c;获取软件的途径显得较为单一&#xff0c;必须通过App Store进行下载安装。 这样的限制&#xff0c;时常让人羡慕安卓系统那些自由下载各类版本软件的便捷。 心中不禁生出疑问&#xff1a;难道iOS世界里&#xff0c;就不存在所谓的“破解版”软件…

Linux 软件管理(YUM RPM)

1 YUM yum&#xff08;全称为 Yellow dog Updater, Modified&#xff09;是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理&#xff0c;能够从指定的服务器自动处理依赖性关系&#xff0c;并且一次安装所有依赖的软件包&#xff0c;无须繁琐地一次次…

91 xxl-job executor 还存在 并且 job 正在执行, 但是 job 被标记为 “任务结果丢失,标记失败“

前言 最近出现了一个这样的问题 我们生产环境中的一个 xxl-job 任务, 很大一部分执行记录被标记为 "任务结果丢失&#xff0c;标记失败", 几乎是 98% 吧 然后 调试的时候 存在几个令人疑惑的地方 1. 通过 xxl-job 点击查看任务的执行记录的日志, 日志为空, …

深度学习(13)--PyTorch搭建神经网络进行气温预测

一.搭建神经网络进行气温预测流程详解 1.1.导入所需的工具包 import numpy as np # 矩阵计算 import pandas as pd # 数据读取 import matplotlib.pyplot as plt # 画图处理 import torch # 构建神经网络 import torch.optim as optim # 设置优化器 1.2.读取并处理数据…

秒杀相关问题解决

秒杀 超卖问题 如下,我们先来复现问题,抢购秒杀券的代码逻辑也是很简单, 先判断优惠券是否开始了,是的化,判断库存是否充足,如果是的化,扣减库存,最后创建订单 如下是代码 Override Transactional public Result seckillVoucher(Long voucherId) {//1.查询优惠券SeckillVo…