Mybatis——Javaweb进阶学习(五)

news2024/12/23 14:55:05

目录

  • 一、Mybatis快速入门
    • 1.创建Springboot工程,数据库表user,实体类User
    • 2.引入Mybaties相关依赖
    • 3.编写Sql语句
  • 二、lombok
    • 1.基本概念
    • 2.使用方法
  • 三、基础操作
    • 1.环境准备
      • a.数据库准备
      • b.创建员工实体类Emp
        • 数据类型对比
        • 命名对比
      • c.Mapper接口创建
    • 2.删除操作
      • 代码
      • 测试
      • 有返回值的删除
      • 日志输出
      • 参数占位符
    • 3.添加操作
      • 3.1 插入的sql语句
      • 3.2 定义接口方法
      • 3.3 测试
      • 3.4 主键返回
    • 4.修改操作
      • 4.1 sql语句
      • 4.2 接口实现
      • 4.3测试
    • 5.查询操作(根据id查询)
      • 5.1 sql语句
      • 5.2 接口文档
      • 5.3 测试
      • 5.4 数据封装解决命名不一致
    • 6. 查询操作(条件查询)
      • 6.1 sql语句
      • 6.2 接口
      • 6.3测试
      • 6.4优化
  • 四、动态sql
    • 1.if

一、Mybatis快速入门

1.创建Springboot工程,数据库表user,实体类User

首先我们要先创建springboot工程,选择mysql和mybatis驱动
在这里插入图片描述

然后创建sql表,插入数据

create database spring;  
use spring;  
create table student(  
    id int auto_increment primary key ,  
    name char(20),  
    age int,  
    gender int,  
    phone char(20)  
);  
insert into student(name, age, gender, phone) value ('rosen',19,0,'10086');
insert into student(name, age, gender, phone) value ('rose',18,0,'10087');

实体类的创建,pojo包

package com.rosen.pojo;  
  
public class User {  
    private Integer id;  
    private String name;  
    private Short age;  
    private Short gender;  
    private String phone;  
    public User() {  
    }  
    public User(Integer id, String name, Short age, Short gender, String phone) {  
        this.id = id;  
        this.name = name;  
        this.age = age;  
        this.gender = gender;  
        this.phone = phone;  
    }  
  
    public Integer getId() {  
        return id;  
    }  
  
    public void setId(Integer id) {  
        this.id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public Short getAge() {  
        return age;  
    }  
  
    public void setAge(Short age) {  
        this.age = age;  
    }  
  
    public Short getGender() {  
        return gender;  
    }  
  
    public void setGender(Short gender) {  
        this.gender = gender;  
    }  
  
    public String getPhone() {  
        return phone;  
    }  
  
    public void setPhone(String phone) {  
        this.phone = phone;  
    }  
}

2.引入Mybaties相关依赖

在这里插入图片描述

#驱动类名  
spring.datasource.driver-class-name=com.mysql.jdbc.Driver  
#连接数据库的url  
spring.datasource.url=jdbc:mysql://localhost:3306/spring  
#连接数据库的用户名  
spring.datasource.username=root  
#连接数据库的密码  
spring.datasource.password=123456

3.编写Sql语句

在mapper文件夹,相当于dao层,编写,UserMapper接口
在这里插入图片描述

@Mapper会自动进入容器,注释@Select来进行编写

package com.rosen.mapper;  
  
import com.rosen.pojo.User;  
import org.apache.ibatis.annotations.Mapper;  
import org.apache.ibatis.annotations.Select;  
  
import java.util.List;  
  
@Mapper  
public interface UserMapper {  
    @Select("select * from student")  
    public List<User> list();  
}

在测试类中进行单元测试:

@SpringBootTest  
class SpringMybatisApplicationTests {  
    @Autowired  
    private UserMapper userMapper;  
    @Test  
    public void testUser()  
    {  
        List<User> userList=userMapper.list();  
        userList.stream().forEach(user -> {  
            System.out.println(user.toString());  
        });  
    }  
  
}

在这里插入图片描述

二、lombok

我们看见User类,是不是除了属性,还要写get,set方法,tostring方法等,是不是很麻烦,也显得类很臃肿,我们只需要lombok给的注解,就可以简化

1.基本概念

Lombok是一个实用的Java类库,能够通过注解的形成自动生成构造器,并且自动化生成日志变量,简化开发

2.使用方法

因此一般直接在类上面加上@Data就可以
在这里插入图片描述

首先要maven导包
不用指定版本,springboot会自动选择

<dependency>  
    <groupId>org.projectlombok</groupId>  
    <artifactId>lombok</artifactId>  
</dependency>

原有代码

package com.rosen.pojo;  
  
public class User {  
    private Integer id;  
    private String name;  
    private Short age;  
    private Short gender;  
    private String phone;  
    public User() {  
    }  
    public User(Integer id, String name, Short age, Short gender, String phone) {  
        this.id = id;  
        this.name = name;  
        this.age = age;  
        this.gender = gender;  
        this.phone = phone;  
    }  
  
    public Integer getId() {  
        return id;  
    }  
  
    public void setId(Integer id) {  
        this.id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public Short getAge() {  
        return age;  
    }  
  
    public void setAge(Short age) {  
        this.age = age;  
    }  
  
    public Short getGender() {  
        return gender;  
    }  
  
    public void setGender(Short gender) {  
        this.gender = gender;  
    }  
  
    public String getPhone() {  
        return phone;  
    }  
  
    public void setPhone(String phone) {  
        this.phone = phone;  
    }  
  
    @Override  
    public String toString() {  
        return "User{" +  
                "id=" + id +  
                ", name='" + name + '\'' +  
                ", age=" + age +  
                ", gender=" + gender +  
                ", phone='" + phone + '\'' +  
                '}';  
    }  
}

注解修改,可以看到代码量减少非常多

@Data  
@NoArgsConstructor  
@AllArgsConstructor  
public class User {  
    private Integer id;  
    private String name;  
    private Short age;  
    private Short gender;  
    private String phone;  
}

lombok会在编译的时候,自动生成对应java代码

三、基础操作

1.环境准备

a.数据库准备

-- 部门管理

create table dept(

    id int unsigned primary key auto_increment comment '主键ID',

    name varchar(10) not null unique comment '部门名称',

    create_time datetime not null comment '创建时间',

    update_time datetime not null comment '修改时间'

) comment '部门表';

insert into dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()), (4,'就业部',now(),now()),(5,'人事部',now(),now());

-- 员工管理

create table emp (

  id int unsigned primary key auto_increment comment 'ID',

  username varchar(20) not null unique comment '用户名',

  password varchar(32) default '123456' comment '密码',

  name varchar(10) not null comment '姓名',

  gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',

  image varchar(300) comment '图像',

  job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',

  entrydate date comment '入职时间',

  dept_id int unsigned comment '部门ID',

  create_time datetime not null comment '创建时间',

  update_time datetime not null comment '修改时间'

) comment '员工表';

  

INSERT INTO emp

    (id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES

    (1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),

    (2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),

    (3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),

    (4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),

    (5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),

    (6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),

    (7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),

    (8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),

    (9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),

    (10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),

    (11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),

    (12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),

    (13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),

    (14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),

    (15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),

    (16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),

    (17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());

dept(部门)表:
在这里插入图片描述

emp(员工)表:
在这里插入图片描述

b.创建员工实体类Emp

@Data
@NoArgsConstructor  
@AllArgsConstructor
public class Emp {  
    private Integer id;  
    private String username;  
    private String password;  
    private String name;  
    private Short gender;  
    private String image;  
    private Short job;  
  
    private LocalDate entrydate;  
    private Integer deptId;  
    private LocalDateTime createTime;  
    private LocalDateTime updateTime;  
}
数据类型对比

LocalDate对应date
LocalDateTime对应datetime
sql中:

  • date:日期:YYYY-MM-DD

  • datetime:日期+时间:YYYY-MM-DD HH:MM:SS
    Java中:

  • LocalDate:年月日

  • LocalTime:时分秒

  • LocalDateTime:年月日时分秒

命名对比
  • sql中无下划线:username-username
  • sql中由下划线:create_time-createTime:下划线的下一个字母大写就好

c.Mapper接口创建

@Mapper
public interface EmpMapper {  
}

2.删除操作

代码

我们为了动态的删除,不可能只删除一个数据比如id=2,可以用#{id},变成动态的参数了

@Mapper  
public interface EmpMapper {  
    @Delete("delete from emp where id=#{id}")  
    public void delete(Integer id);  
}

测试

在测试单元测试,可以通过

@SpringBootTest  
class SpringMybatisApplicationTests {  
    
    @Autowired  
    private EmpMapper empMapper;  
    @Test  
    public void test()  
    {  
        empMapper.delete(17);  
    }  
}

有返回值的删除

@Mapper  
public interface EmpMapper {  
    @Delete("delete from emp where id=#{id}")  
    public int delete(Integer id);  
}

测试之后发现输出0,因为已经删除过了,所以再次删除失败返回0,反之返回1

@SpringBootTest  
class SpringMybatisApplicationTests {  
 
    @Autowired  
    private EmpMapper empMapper;  
    @Test  
    public void test()  
    {  
        int delete=empMapper.delete(17);  
        System.out.println(delete);  
    }  
}

日志输出

打开配置文件
在这里插入图片描述

配置日志,这样就可以在控制台上看到到底执行了哪些sql

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

可以看到,已经可以看到日志了,0代表没有真正删除
底下的带有?的sql语句代表预编译sql,执行的时候,参数和预编译sql一同发送给数据库
在这里插入图片描述

为什么不直接代替问号呢?
预编译sql优势

  • 性能更高
  • 更加安全(防止sql注入:通过操作输入的数据来修改事先定义好的sql语句,达到执行代码对服务器进行攻击的方法)
    比如:```
输入账户:rosen 密码: 123456
select count(*) from emp where username='rosen' and password='123456'
成功则进入
但是如果账户:rosen,密码为:'or'1'='1这个,会发现
select count(*) from emp where username='rosen' and password=''or'1'='1'
这个表达式不管怎么样都是成立的因为1=1一直成立,所以sql注入

执行流程
因为缓存区如果有sql语句,那么就会直接拿取缓存,而每次如果id=不同的数字,那么缓存会一直没有,那么编译次数增加,那很慢,如果预编译sql,不会看id=多少,会在缓存找到,那么拼接后就会找到,那么不久加快了!
在这里插入图片描述

参数占位符

可以看出$,会产生sql注入,而#则不会,一般使用#
在这里插入图片描述

3.添加操作

3.1 插入的sql语句

id:自增长,不需要插入
密码又默认:不需要插入
create time和uodate_tima需要当前时间
在这里插入图片描述

insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)  
values('Tom','汤姆',1,'1.jpg',1,'2005-01-01',1,now(),now());

3.2 定义接口方法

我们还利用删除时候创建的接口
我们会发现,如果还是像delete参数是自己设置的变量的话,那么要设置很多变量,所有我们传入一个对应类,占位符里面是这个类的属性名

@Mapper  
public interface EmpMapper {  
    @Delete("delete from emp where id=#{id}")  
    public int delete(Integer id);  
  
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +  "values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});")  
    public void insert(Emp emp);  
}

3.3 测试

@SpringBootTest  
class SpringMybatisApplicationTests {  
 
    @Autowired  
    private EmpMapper empMapper;  
  @Test  
	public void testInsert()  
	{  
    //构造员工对象  
    Emp emp=new Emp();  
    emp.setUsername("Tom");  
    emp.setName("汤姆");  
    emp.setImage("1.jpg");  
    emp.setGender((short)1);  
    emp.setJob((short)1);  
    emp.setEntrydate(LocalDate.of(2000,1,1));  
    emp.setCreateTime(LocalDateTime.now());  
    emp.setUpdateTime(LocalDateTime.now());  
    emp.setDeptId(1);  
  
    //新增操作  
    empMapper.insert(emp);  
	}
}

测试成功
在这里插入图片描述
在这里插入图片描述

3.4 主键返回

在添加成功的时候,需要获取插入数据库的主键
如:添加套餐数据的时候,需要添加套餐,还有一个表是菜品,套餐对应菜品,需要知道套餐是说明才能选择菜品,因此需要返回主键
代码实现
在插入方法上面加上注解@Options

  • KeyProperty:代表插入到这个类的哪一个属性
  • useGeneratedKeys = true:是否返回主键
public interface EmpMapper {  
    @Delete("delete from emp where id=#{id}")  
    public int delete(Integer id);  
  
//获取主键,会封装到对象的id属性中,true是获取主键  
@Options(keyProperty = "id",useGeneratedKeys = true)  
@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +  
        "values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});")  
public void insert(Emp emp);
}

测试

@Test  
public void testInsert()  
{  
    //构造员工对象  
    Emp emp=new Emp();  
    emp.setUsername("Tom1");  
    emp.setName("汤姆3");  
    emp.setImage("1.jpg");  
    emp.setGender((short)1);  
    emp.setJob((short)1);  
    emp.setEntrydate(LocalDate.of(2000,1,1));  
    emp.setCreateTime(LocalDateTime.now());  
    emp.setUpdateTime(LocalDateTime.now());  
    emp.setDeptId(1);  
  
    //新增操作  
    empMapper.insert(emp);  
    System.out.println(emp.getId());  
}

在这里插入图片描述

4.修改操作

4.1 sql语句

update emp set username = '',name='',gender='',image='',job='',entrydate='',dept_id='',update_time='' where id=1;

4.2 接口实现

@Update("update emp set username =#{username},name=#{name},gender=#{gender},image=#{image},job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id};")  
public void update(Emp emp);

4.3测试

@Test  
public void testUpdate()  
{  
    //构造员工对象  
    Emp emp=new Emp();  
    emp.setId(18);  
    emp.setUsername("Tom6");  
    emp.setName("汤姆6");  
    emp.setImage("1.jpg");  
    emp.setGender((short)1);  
    emp.setJob((short)1);  
    emp.setEntrydate(LocalDate.of(2000,2,2));  
    emp.setUpdateTime(LocalDateTime.now());  
    emp.setDeptId(1);  
  
    //新增操作  
    empMapper.update(emp);  
    System.out.println(emp.getId());  
}

在这里插入图片描述

5.查询操作(根据id查询)

5.1 sql语句

select * from emp where id=20;

5.2 接口文档

查询是由返回值的,返回对象就行

@Select("select * from emp where id=#{id};")  
public Emp getById(Integer id);

5.3 测试

@Test  
public void select(){  
    Emp emp = empMapper.getById(20);  
    System.out.println(emp);  
}

在这里插入图片描述

但是发现:有三个值没有进行封装?为什么呢
在这里插入图片描述

如果数据库和实体类的字段名一致因此mybatis会自动封装
如何解决问题——数据封装

5.4 数据封装解决命名不一致

方案1
sql起别名
在这里插入图片描述

方案2
注解起别名
在这里插入图片描述

方案3
配置文件设置驼峰命名

mybatis.configuration.map-underscore-to-camel-case=true

成功展示
在这里插入图片描述

6. 查询操作(条件查询)

6.1 sql语句

包括模糊查询,时间排序,范围查询

select  *from emp where name like '%张%' and
gender =1 and entrydate between '2010-01-01' and '2020-01-02' order by update_time desc ;

6.2 接口

因为模糊查询里面的引号不能使用注入,因此用$进行拼接处理。

@Select("select  *from emp where name like '%${name}%' and gender =#{gender} and" +  
        " entrydate between #{begin} and #{end} order by update_time desc ")  
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

6.3测试

@Test  
public void select2()  
{  
    List<Emp> empList = empMapper.list("张", (short) 1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1));  
    System.out.println(empList);  
}

在这里插入图片描述

发现欸,这样用$符号,还是有问题啊,会sql注入,不安全,咋办呢,用sql的函数

6.4优化

contact字符串连接

@Select("select  *from emp where name like concat('%',#{name},'%') and gender =#{gender} and" +  
        " entrydate between #{begin} and #{end} order by update_time desc ")  
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

可以看到已经成功了
在这里插入图片描述

xml操作部分和动态sql,javaweb进行部分的描述,不在进行赘述

四、动态sql

xml配置在之前的非进阶学习过,直接给例子进行动态sql

1.if

可能多个属性,但是只用传输过来的条件
在resource创建对应的xml文件
com/rosen/mapper/EmpMapper.xml
注意名字要一样

  • 上面是固定的
  • namespace=“com.rosen.mapper.EmpMapper”:代表接口的位置
  • id=‘list’:方法名
  • resulttype:返回类型
  • 因为如果是用where的话,可能多一个and或多一个where,因此<where>会自动去除
<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper  
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  
<mapper namespace="com.rosen.mapper.EmpMapper">  
  
    <select id="list" resultType="com.rosen.pojo.Emp">  
        select *  
        from emp  
    <where>  
        <if test="name!=null">  
        name like concat('%',#{name},'%')  
        </if>  
        <if test="gender!=null">  
        and gender=#{gender}  
        </if>  
        <if test="begin!=null and end!=null">  
        and entrydate between #{begin} and #{end}  
        </if>  
        order by update_time desc  
    </where>  
    </select></mapper>
    ```
    
## 2.foreach
删除对应数据,用foreach实现动态sql
+ collections:参数 
+ item:拿出来的实体:自己取名
+ separator:以什么分割
+ open:左边拼接
+ close:右边拼接
```xml
<mapper namespace="com.rosen.mapper.EmpMapper">  
    <delete id="delete" >  
        delete from where emp id in  
        <foreach collection="ids" item="id" separator="," open="(" close=")">  
            #{id}  
        </foreach>  
    </delete>  

    </select>
    </mapper>

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

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

相关文章

EasyRecovery2024功能强大的电脑数据恢复软件

EasyRecovery是一款功能强大的数据恢复软件&#xff0c;支持从各种存储介质中恢复丢失或删除的文件。以下是EasyRecovery的下载教程、功能介绍以及最新版本简介&#xff1a; EasyRecovery支持多种操作系统版本。对于Windows系统&#xff0c;它支持Windows XP、Windows Vista、W…

智能网卡(SmartNIC):增强网络性能

在当今的数字时代&#xff0c;网络性能和数据安全是各行各业面临的关键挑战。智能网卡是一项颠覆性的技术创新&#xff0c;对增强网络性能和加强数据安全性具有关键推动作用。本文旨在探讨智能网卡的工作原理及其在不同应用场景中的重要作用。 什么是智能网卡&#xff1f; 智…

QtApplets-线程池

QtApplets-线程池 ​ 今天咱们稍微看下Qt的线程池。QThreadPool&#xff0c;浅浅搞一下。 文章目录 QtApplets-线程池QThreadPoolQThreadPool 与 QThread 区别替代方案Qt Concurrent QThreadPool 与 Qt Concurrent 区别Demo运行效果 ☞ 源码 关键字&#xff1a; Qt、QRunnable…

Netty中的适配器、Handler共享和资源管理

ChannelHandler的适配器 有一些适配器类可以将编写自定义的ChannelHandler所需要的工作降到最低限度&#xff0c; 因为它们提供了定义在对应接口中的所有方法的默认实现。因为有时会忽略那些不感兴趣的 事件&#xff0c;所以Netty提供了抽象积累ChannelInboundHandlerAdapter(…

SORA:OpenAI最新文本驱动视频生成大模型技术报告解读

Video generation models as world simulators&#xff1a;作为世界模拟器的视频生成模型 1、概览2、Turning visual data into patches&#xff1a;将视觉数据转换为补丁3、Video compression network&#xff1a;视频压缩网络4、Spacetime Latent Patches&#xff1a;时空潜在…

HTTP缓存技术

大家好我是苏麟 , 今天说说HTTP缓存技术 . 资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) HTTP缓存技术 HTTP 缓存有哪些实现方式? 对于一些具有重复性的 HTTP 请求&#xff0c;比如每次请求得到的数据都一样的&#xff0c;我们可以把这对「请求-响…

Python爬虫之Splash详解

爬虫专栏&#xff1a;http://t.csdnimg.cn/WfCSx Splash 的使用 Splash 是一个 JavaScript 渲染服务&#xff0c;是一个带有 HTTP API 的轻量级浏览器&#xff0c;同时它对接了 Python 中的 Twisted 和 QT 库。利用它&#xff0c;我们同样可以实现动态渲染页面的抓取。 1. 功…

交换排序(冒泡排序和快速排序)

交换排序 冒泡排序 传统方法&#xff1a; for (int i 0; i < numsSize - 1; i) {for (int j 0; j < numsSize - 1 - i; j) {if (nums[j] > nums[j 1]) {Swap(&nums[j], &nums[j 1]);}} } 方法二&#xff1a; while循环for循环 int end numsSize - 1…

理解并实现OpenCV中的图像平滑技术

导读 图像模糊&#xff08;也称为图像平滑&#xff09;是计算机视觉和图像处理中的基本操作之一。模糊图像通常是噪声减少、边缘检测和特征提取等应用的第一步。在本博客中&#xff0c;我们将重点介绍如何使用Python中的OpenCV库应用多种模糊技术。 理论概述&#xff1a; 基本…

Netty中的内置通信模式、Bootstrap和ChannelInitializer

内置通信传输模式 NIO:io.netty.channel.socket.nio 使用java.nio.channels包作为基础–基于选择器的方式Epoll:io.netty.channel.epoll由JNI驱动的epoll()和非阻塞IO.这个传输支持只有在Linux上可用的多种特性&#xff0c;如果SO_REUSEPORT&#xff0c;比NIO传输更快&#xf…

视觉slam十四讲学习笔记(六)视觉里程计 1

本文关注基于特征点方式的视觉里程计算法。将介绍什么是特征点&#xff0c;如何提取和匹配特征点&#xff0c;以及如何根据配对的特征点估计相机运动。 目录 前言 一、特征点法 1 特征点 2 ORB 特征 FAST 关键点 BRIEF 描述子 3 特征匹配 二、实践&#xff1a;特征提取…

计算机网络——14CDN

CDN 视频流化服务和CDN&#xff1a;上下文 视频流量&#xff1a;占据着互连网大部分的带宽 Netflix&#xff0c;YouTube&#xff1a;占据37%&#xff0c;16%的下行流量 挑战&#xff1a;规模性-如何服务~1B用户&#xff1f; 单个超级服务器无法提供服务&#xff08;为什么&am…

第7章 Page442~446 7.8.9智能指针

指向堆内存的指针&#xff0c;很容易忘了释放&#xff1a; int foo() {int* p new int(9);cout << *p << endl;return *p; } 为什么要用指针 使用堆数据有以下几个目的&#xff08;也可称为作用&#xff09;如表7-18所列 表7-18 使用堆数据的常见目的 使用堆数…

阿里云服务器租用价格表(2024更新)

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

数据结构:4_二叉树

二叉树 一.树概念及结构 1. 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个**特殊的…

让你的资金运动起来,金钱的聪明处理方式

一、教程描述 本套教程主要讲解了金融思维和财务思维&#xff0c;常见投资工具的实操技巧&#xff0c;资产配置方案的制定方法&#xff0c;等等&#xff0c;将会重构你现有的投资观念&#xff0c;提升你认知的宽度和深度&#xff0c;可以轻松读懂财经新闻&#xff0c;不仅学会…

单片机学习笔记---LED呼吸灯直流电机调速

目录 LED呼吸灯 直流电机调速 模型结构 波形 定时器初始化函数 中断函数 主程序 上一节讲了电机的工作原理&#xff0c;这一节开始代码演示&#xff01; 我们上一篇说Ton的时间长Toff时间短电机会快&#xff0c;Ton的时间短Toff时间长电机会慢 并且我们还要保证无论Ton和…

红队ATKCK|红日靶场Write-Up(附下载链接)

网络拓扑图 下载地址 在线下载&#xff1a; http://vulnstack.qiyuanxuetang.net/vuln/detail/2/ 百度网盘 链接&#xff1a;https://pan.baidu.com/s/1nlAZAuvni3EefAy1SGiA-Q?pwdh1e5 提取码&#xff1a;h1e5 环境搭建 通过上述图片&#xff0c;web服务器vm1既能用于外…

【网络安全】什么样的人适合学?该怎么学?

有很多想要转行网络安全或者选择网络安全专业的人在进行决定之前一定会有的问题&#xff1a; 什么样的人适合学习网络安全&#xff1f;我适不适合学习网络安全&#xff1f; 当然&#xff0c;产生这样的疑惑并不奇怪&#xff0c;毕竟网络安全这个专业在2017年才调整为国家一级…

【BUUCTF 加固题】Ezsql 速通

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …