Mybatis——Javaweb进阶学习(五)

目录

  • 一、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.mzph.cn/news/684952.shtml

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

相关文章

CSS盒子的概念

盒子模型 盒子的概念 页面中的每一个标签都可以看做是一个“盒子”&#xff0c;通过盒子的视角更方便的进行布局 浏览器在渲染&#xff08;显示&#xff09;网页时&#xff0c;会将网页中的元素看做是一个个的矩形区域&#xff0c;称之为“盒子” 盒子模型 CSS中规定每个盒…

从计算机恢复已删除文件的 6 种方法!

如果您的重要文件之一已从计算机中删除怎么办&#xff1f;如果不小心从硬盘中删除了文件怎么办&#xff1f; 如今的公司通常将重要数据存储在云或硬盘中。但最重要的是&#xff0c;您必须考虑这样一个事实&#xff1a;您可能会丢失计算机上的数据。数据丢失的原因有多种&#x…

C语言-----用二维数组解决菱形的打印问题

1.打印菱形&#xff0c;多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜线和正斜线的长度。 #include <stdio.h>int main() {int n0;while(scanf("%d",&n)! EOF){int i0;int j0;f…

【数据结构】12 堆栈应用:表达式求值

表达式类型 后缀表达式 有一个常量表达式的中缀表达式为&#xff1a;5 6 / 2 - 3 * 4&#xff0c;其后缀形式表示为&#xff1a; 5 6 2 / 3 4 -。后缀表达式的特点是运算符位于两个预算数之后。其前缀表达式为&#xff1a; - 5 / 6 2 3 4。 后缀表达式相比于中缀表达式的…

彻底理解无刷电机

前言 现在很多设备都是搭载的无刷电机而不是有刷电机了&#xff0c;为啥&#xff1f;性能好啊&#xff01; 引入 同性相斥异性相吸 可以看出&#xff0c;只要改变磁铁的极性&#xff0c;电机就能转起来 那 怎么改变磁铁极性呢&#xff1f; 右手螺旋定则可以根据电流的流向…

可变参数(c/c++)

目录 一、C语言版本 二、C的实现方法 2.1数据包 2.2sizeof...运算符 2.3可变参数模板的使用 2.4emplace_back() 有时候我们在编写函数时&#xff0c;可能不知道要传入的参数个数&#xff0c;类型 。比如我们要实现一个叠加函数&#xff0c;再比如c语言中的printf,c中的emp…

2024年2月份实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】

首先&#xff0c;来看下效果图 在线体验地址&#xff1a;https://geojson.hxkj.vip&#xff0c;并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据&#xff0…

Springboot+vue的大学生智能消费记账系统的设计与实现(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的大学生智能消费记账系统的设计与实现&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的大学生智能消费记账系统的设计与实现&#xff0c;采…

回溯题中借助哈希法来巧妙去重的操作

今天总结一下回溯法以来做过的这些题&#xff0c;我又发现一个困扰了我的问题&#xff0c;就是在491. 非递减子序列、46. 全排列、47. 全排列 II中都有涉及到用哈希法&#xff0c;去记录曾经用过的元素&#xff0c;下面来总结一下吧。 首先得知道&#xff0c;为什么会用到哈希法…

wordpress外贸成品网站模板

首页大图slider轮播&#xff0c;橙色风格的wordpress外贸网站模板 https://www.zhanyes.com/waimao/6250.html 蓝色经典风格的wordpress外贸建站模板 https://www.zhanyes.com/waimao/6263.html

RapidMiner数据挖掘2 —— 初识RapidMiner

本节由一系列练习与问题组成&#xff0c;这些练习与问题有助于理解多个基本概念。它侧重于各种特定步骤&#xff0c;以进行直接的探索性数据分析。因此&#xff0c;其主要目标是测试一些检查初步数据特征的方法。大多数练习都是关于图表技术&#xff0c;通常用于数据挖掘。 为此…

【复现】cellinx摄像设备 未授权漏洞_50

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 cellinx是一家韩国的摄像设备 二 .漏洞影响 通过未授权访问可以创建用户进入后台&#xff0c;可能造成系统功能破坏。 三.漏洞复…

多线程面试题汇总

多线程面试题汇总 一、多线程1、线程的生命周期2、线程的创建&#xff08;函数创建&#xff09;3、线程的创建&#xff08;使用类&#xff09;4、守护线程 二、全局解释器锁1、使用单线程实现累加到5000000002、使用多线程实现累加到5000000003、总结 三、线程安全1、多线程之数…

SQL的1999语法

目录 交叉连接 实现交叉连接 自然连接 实现自然连接&#xff08;实际上就是内连接&#xff09; ON和USING 使用自然连接时要求两张表的字段名称相同&#xff0c;但是如果不相同或者两张表中有两组字段是重名,这时就要利用 ON 子句指定关联条件&#xff0c;利用 USING 子句…

【Android】使用Apktool反编译Apk文件

文章目录 1. 下载Apktool1.1 Apktool官网下载1.2 百度网盘下载 2. 安装Apktool3. 使用Apktool3.1 配置Java环境3.2 准备Apk文件3.3 反编译Apk文件3.3.1 解包Apk文件3.3.2 修改Apk文件3.3.3 打包Apk文件3.3.4 签名Apk文件 1. 下载Apktool 要使用Apktool&#xff0c;需要准备好 …

OpenSource - 一站式自动化运维及自动化部署平台

文章目录 orion-ops 是什么重构特性快速开始技术栈功能预览添砖加瓦License orion-ops 是什么 orion-ops 一站式自动化运维及自动化部署平台, 使用多环境的概念, 提供了机器管理、机器监控报警、Web终端、WebSftp、机器批量执行、机器批量上传、在线查看日志、定时调度任务、应…

2.14:二维数组、非函数实现strcat、strcmp、strcpy、strlen

1.编程实现二维数组的杨辉三角 程序代码&#xff1a; 1 #include<stdio.h>2 #include<string.h>3 #include<stdlib.h>4 int main(int argc, const char *argv[])5 {6 int n;7 printf("please enter n:");8 scanf("%d",&…

C++文件操作->文本文件(->写文件、读文件)、二进制文件(->写文件、读文件)

#include<iostream> using namespace std; #include <fstream>//头文件包含 //文本文件 写文件 void test01() { //1.包含头文件 fstream //2.创建流对象 ofstream ofs; //3.指定打开方式 ofs.open("test.txt", ios::out); //4.写…

蓝桥杯嵌入式学习记录——PWM输出

目录 一、PWM原理介绍 二、学习目的 三、cubeMX的配置 四、PWM输出代码 一、PWM原理介绍 PWM&#xff08;Pulse Width Modulation&#xff0c;脉宽调制&#xff09;是一种通过改变信号的脉冲宽度来控制电平的技术。它通过调整脉冲信号的占空比&#xff08;高电平时间与周期…

互联网加竞赛 基于计算机视觉的身份证识别系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的身份证识别系统 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-sen…