若依vue -【 100 ~ 更 】

news2024/12/23 3:18:11

100 主子表代码生成详解

新建数据库表结构(主子表)

-- ----------------------------
-- 客户表
-- ----------------------------
drop table if exists sys_customer;
create table sys_customer (
  customer_id           bigint(20)      not null auto_increment    comment '客户id',
  customer_name         varchar(30)     default ''                 comment '客户姓名',
  phonenumber           varchar(11)     default ''                 comment '手机号码',
  sex                   varchar(20)     default null               comment '客户性别',
  birthday              datetime                                   comment '客户生日',
  remark                varchar(500)    default null               comment '客户描述',
  primary key (customer_id)
) engine=innodb auto_increment=1 comment = '客户表';


-- ----------------------------
-- 商品表
-- ----------------------------
drop table if exists sys_goods;
create table sys_goods (
  goods_id           bigint(20)      not null auto_increment    comment '商品id',
  -- 必须要有的关联字段(外键)
  customer_id        bigint(20)      not null                   comment '客户id',
  name               varchar(30)     default ''                 comment '商品名称',
  weight             int(5)          default null               comment '商品重量',
  price              decimal(6,2)    default null               comment '商品价格',
  date               datetime                                   comment '商品时间',
  type               char(1)         default null               comment '商品种类',
  primary key (goods_id)
) engine=innodb auto_increment=1 comment = '商品表';

代码生成使用

(1)登录系统(系统工具 -> 代码生成 -> 导入主表与子表)

(2)代码生成列表中找到需要表(可预览、编辑、同步、删除生成配置)

(3)点击生成代码会得到一个ruoyi.zip执行sql文件,按照包内目录结构复制到自己的项目中即可

(4)执行customerMenu.sql生成菜单

-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('客户', '3', '1', 'customer', 'system/customer/index', 1, 0, 'C', '0', '0', 'system:customer:list', '#', 'admin', sysdate(), '', null, '客户菜单');

-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();

-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('客户查询', @parentId, '1',  '#', '', 1, 0, 'F', '0', '0', 'system:customer:query',        '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('客户新增', @parentId, '2',  '#', '', 1, 0, 'F', '0', '0', 'system:customer:add',          '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('客户修改', @parentId, '3',  '#', '', 1, 0, 'F', '0', '0', 'system:customer:edit',         '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('客户删除', @parentId, '4',  '#', '', 1, 0, 'F', '0', '0', 'system:customer:remove',       '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('客户导出', @parentId, '5',  '#', '', 1, 0, 'F', '0', '0', 'system:customer:export',       '#', 'admin', sysdate(), '', null, '');

(5)覆盖前端代码:主要是里面的模板有不同

(6)覆盖后端代码:主要是里面的模板有不同

  

(7)测试

  1. F5刷新ruoyi-system
  2. 重启前后端
  3. 测试成功

3 后台(区别)详解

(1)SysCustomer:客户

    /** 
     * 关联关系 商品信息 集合。
     * 后续:前端会把商品信息传进来。
     * */
    private List<SysGoods> sysGoodsList;

(2)SysGoods:商品。就跟单表一样

(3)SysCustomerServiceImpl:大区别

package com.ruoyi.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.system.domain.SysGoods;
import com.ruoyi.system.mapper.SysCustomerMapper;
import com.ruoyi.system.domain.SysCustomer;
import com.ruoyi.system.service.ISysCustomerService;

/**
 * 客户Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-08-09
 */
@Service
public class SysCustomerServiceImpl implements ISysCustomerService 
{
    @Autowired
    private SysCustomerMapper sysCustomerMapper;

    /**
     * 查询客户
     * 
     * 区别:XxxMapper.xml中会是一个关联查询
     */
    @Override
    public SysCustomer selectSysCustomerByCustomerId(Long customerId)
    {
        return sysCustomerMapper.selectSysCustomerByCustomerId(customerId);
    }

    /**
     * 查询客户列表
     *
     * 区别:XxxMapper.xml中会是一个关联查询
     */
    @Override
    public List<SysCustomer> selectSysCustomerList(SysCustomer sysCustomer)
    {
        return sysCustomerMapper.selectSysCustomerList(sysCustomer);
    }

    /**
     * 新增客户
     *
     * 区别:新增对应的商品信息(列表)
     */
    @Transactional
    @Override
    public int insertSysCustomer(SysCustomer sysCustomer)
    {
        int rows = sysCustomerMapper.insertSysCustomer(sysCustomer);
        insertSysGoods(sysCustomer);
        return rows;
    }

    /**
     * 修改客户
     */
    @Transactional
    @Override
    public int updateSysCustomer(SysCustomer sysCustomer)
    {
        /**
         * 删除子表中的全部数据
         */
        sysCustomerMapper.deleteSysGoodsByCustomerId(sysCustomer.getCustomerId());
        /**
         * 子表数据入库
         */
        insertSysGoods(sysCustomer);
        /**
         * 主表信息修改入库
         */
        return sysCustomerMapper.updateSysCustomer(sysCustomer);
    }

    /**
     * 批量删除客户
     */
    @Transactional
    @Override
    public int deleteSysCustomerByCustomerIds(Long[] customerIds)
    {
        /**
         * 删除子表数据
         */
        sysCustomerMapper.deleteSysGoodsByCustomerIds(customerIds);
        /**
         * 删除主表数据
         */
        return sysCustomerMapper.deleteSysCustomerByCustomerIds(customerIds);
    }

    /**
     * 删除客户信息
     */
    @Transactional
    @Override
    public int deleteSysCustomerByCustomerId(Long customerId)
    {
        /**
         * 删除子表数据
         */
        sysCustomerMapper.deleteSysGoodsByCustomerId(customerId);
        /**
         * 删除主表数据
         */
        return sysCustomerMapper.deleteSysCustomerByCustomerId(customerId);
    }

    /**
     * 新增商品信息
     * 即从客户中获取对应的商品信息列表,然后入库
     */
    public void insertSysGoods(SysCustomer sysCustomer)
    {
        List<SysGoods> sysGoodsList = sysCustomer.getSysGoodsList();
        Long customerId = sysCustomer.getCustomerId();
        if (StringUtils.isNotNull(sysGoodsList))
        {
            List<SysGoods> list = new ArrayList<SysGoods>();
            for (SysGoods sysGoods : sysGoodsList)
            {
                sysGoods.setCustomerId(customerId);
                list.add(sysGoods);
            }
            if (list.size() > 0)
            {
                sysCustomerMapper.batchSysGoods(list);
            }
        }
    }
}

(4)SysCustomerMapper.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">
<mapper namespace="com.ruoyi.system.mapper.SysCustomerMapper">
    
    <resultMap type="SysCustomer" id="SysCustomerResult">
        <result property="customerId"    column="customer_id"    />
        <result property="customerName"    column="customer_name"    />
        <result property="phonenumber"    column="phonenumber"    />
        <result property="sex"    column="sex"    />
        <result property="birthday"    column="birthday"    />
        <result property="remark"    column="remark"    />
    </resultMap>

    <resultMap id="SysCustomerSysGoodsResult" type="SysCustomer" extends="SysCustomerResult">
        <collection property="sysGoodsList" notNullColumn="sub_goods_id" javaType="java.util.List" resultMap="SysGoodsResult" />
    </resultMap>

    <resultMap type="SysGoods" id="SysGoodsResult">
        <result property="goodsId"    column="sub_goods_id"    />
        <result property="customerId"    column="sub_customer_id"    />
        <result property="name"    column="sub_name"    />
        <result property="weight"    column="sub_weight"    />
        <result property="price"    column="sub_price"    />
        <result property="date"    column="sub_date"    />
        <result property="type"    column="sub_type"    />
    </resultMap>

    <sql id="selectSysCustomerVo">
        select customer_id, customer_name, phonenumber, sex, birthday, remark from sys_customer
    </sql>

    <select id="selectSysCustomerList" parameterType="SysCustomer" resultMap="SysCustomerResult">
        <include refid="selectSysCustomerVo"/>
        <where>  
            <if test="customerName != null  and customerName != ''"> and customer_name like concat('%', #{customerName}, '%')</if>
            <if test="phonenumber != null  and phonenumber != ''"> and phonenumber = #{phonenumber}</if>
            <if test="sex != null  and sex != ''"> and sex = #{sex}</if>
            <if test="birthday != null "> and birthday = #{birthday}</if>
        </where>
    </select>

    <!--
        区别:关联查询
    -->
    <select id="selectSysCustomerByCustomerId" parameterType="Long" resultMap="SysCustomerSysGoodsResult">
        select a.customer_id, a.customer_name, a.phonenumber, a.sex, a.birthday, a.remark,
 b.goods_id as sub_goods_id, b.customer_id as sub_customer_id, b.name as sub_name, b.weight as sub_weight, b.price as sub_price, b.date as sub_date, b.type as sub_type
        from sys_customer a
        left join sys_goods b on b.customer_id = a.customer_id
        where a.customer_id = #{customerId}
    </select>
        
    <insert id="insertSysCustomer" parameterType="SysCustomer" useGeneratedKeys="true" keyProperty="customerId">
        insert into sys_customer
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="customerName != null">customer_name,</if>
            <if test="phonenumber != null">phonenumber,</if>
            <if test="sex != null">sex,</if>
            <if test="birthday != null">birthday,</if>
            <if test="remark != null">remark,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="customerName != null">#{customerName},</if>
            <if test="phonenumber != null">#{phonenumber},</if>
            <if test="sex != null">#{sex},</if>
            <if test="birthday != null">#{birthday},</if>
            <if test="remark != null">#{remark},</if>
         </trim>
    </insert>

    <update id="updateSysCustomer" parameterType="SysCustomer">
        update sys_customer
        <trim prefix="SET" suffixOverrides=",">
            <if test="customerName != null">customer_name = #{customerName},</if>
            <if test="phonenumber != null">phonenumber = #{phonenumber},</if>
            <if test="sex != null">sex = #{sex},</if>
            <if test="birthday != null">birthday = #{birthday},</if>
            <if test="remark != null">remark = #{remark},</if>
        </trim>
        where customer_id = #{customerId}
    </update>

    <delete id="deleteSysCustomerByCustomerId" parameterType="Long">
        delete from sys_customer where customer_id = #{customerId}
    </delete>

    <delete id="deleteSysCustomerByCustomerIds" parameterType="String">
        delete from sys_customer where customer_id in 
        <foreach item="customerId" collection="array" open="(" separator="," close=")">
            #{customerId}
        </foreach>
    </delete>
    
    <delete id="deleteSysGoodsByCustomerIds" parameterType="String">
        delete from sys_goods where customer_id in 
        <foreach item="customerId" collection="array" open="(" separator="," close=")">
            #{customerId}
        </foreach>
    </delete>

    <delete id="deleteSysGoodsByCustomerId" parameterType="Long">
        delete from sys_goods where customer_id = #{customerId}
    </delete>

    <insert id="batchSysGoods">
        insert into sys_goods( goods_id, customer_id, name, weight, price, date, type) values
		<foreach item="item" index="index" collection="list" separator=",">
            ( #{item.goodsId}, #{item.customerId}, #{item.name}, #{item.weight}, #{item.price}, #{item.date}, #{item.type})
        </foreach>
    </insert>
</mapper>

4 前端(区别)详解

(1)ruoyi-ui\src\views\system\customer\index.vue

<template>
        <!--
          1、指定了商品信息(列表)
          2、选择事件:@selection-change="handleSysGoodsSelectionChange"
        -->
        <el-table :data="sysGoodsList" :row-class-name="rowSysGoodsIndex" @selection-change="handleSysGoodsSelectionChange" ref="sysGoods">
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column label="序号" align="center" prop="index" width="50"/>
          <el-table-column label="商品名称" prop="name" width="150">
            <template slot-scope="scope">
              <el-input v-model="scope.row.name" placeholder="请输入商品名称" />
            </template>
          </el-table-column>
          <el-table-column label="商品重量" prop="weight" width="150">
            <template slot-scope="scope">
              <el-input v-model="scope.row.weight" placeholder="请输入商品重量" />
            </template>
          </el-table-column>
          <el-table-column label="商品价格" prop="price" width="150">
            <template slot-scope="scope">
              <el-input v-model="scope.row.price" placeholder="请输入商品价格" />
            </template>
          </el-table-column>
          <el-table-column label="商品时间" prop="date" width="240">
            <template slot-scope="scope">
              <el-date-picker clearable v-model="scope.row.date" type="date" value-format="yyyy-MM-dd" placeholder="请选择商品时间" />
            </template>
          </el-table-column>
          <el-table-column label="商品种类" prop="type" width="150">
            <template slot-scope="scope">
              <el-select v-model="scope.row.type" placeholder="请选择商品种类">
                <el-option label="请选择字典生成" value="" />
              </el-select>
            </template>
          </el-table-column>
        </el-table>
</template>
<script>
export default {
  name: "Customer",
  data() {
      // 商品表格数据,初始化为空
      sysGoodsList: [],
  },
  methods:{
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const customerId = row.customerId || this.ids
      getCustomer(customerId).then(response => {
        this.form = response.data;
        /**
         * 从客户中获取商品集合(列表)
         */
        this.sysGoodsList = response.data.sysGoodsList;
        this.open = true;
        this.title = "修改客户";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
         /**
          * 提交时把商品赋值到对应的客户中
          */
          this.form.sysGoodsList = this.sysGoodsList;
          if (this.form.customerId != null) {
            updateCustomer(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addCustomer(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 商品添加按钮操作 */
    handleAddSysGoods() {
      let obj = {};
      obj.name = "";
      obj.weight = "";
      obj.price = "";
      obj.date = "";
      obj.type = "";
      this.sysGoodsList.push(obj);
    },
  }
}
</script>

101 【更】3.4.0版本更新介绍

102 使用undertow容器来替代tomcat容器

1 undertow与tomcat的区别与联系

  1. springboot默认使用tomcat做为http容器。
  2. undertow与tomcat是一样的。
  3. undertow在处理高并发请求、对内存的优化要好于tomcat。

2 替换过程详解

(1)ruoyi-framework\pom.xml模块修改web容器依赖,使用undertow来替代tomcat容器

        <!-- SpringBoot Web容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!-- 排除springboot默认使用的tomcat容器 -->
                <exclusion>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- web 容器使用 undertow 替换 tomcat -->
        <!-- undertow的版本默认跟随springboot的版本-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

(2)修改application.yml,使用undertow来替代tomcat容器

# 开发环境配置
server:
  # 服务器的HTTP端口,默认为80
  port: 80
  servlet:
    # 应用的访问路径
    context-path: /
  # undertow 配置(可以参考官网,设置更多的属性)
  undertow:
    # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
    max-http-post-size: -1
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # 每块buffer的空间大小,越小的空间被利用越充分
    buffer-size: 512
    # 是否分配的直接内存
    direct-buffers: true
    threads:
      # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
      io: 8
      # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
      worker: 256

(3)修改文件上传工具类FileUploadUtils#getAbsoluteFile

        使用undertow容器以后上传文件可能会报错,这是因为undertow和tomcat的底层实现是不一样的,因此undertow是不需要去创建的:

private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
{
	File desc = new File(uploadDir + File.separator + fileName);

	if (!desc.getParentFile().exists())
	{
		desc.getParentFile().mkdirs();
	}
	// undertow文件上传,因底层实现不同,无需创建新文件
	// if (!desc.exists())
	// {
	//    desc.createNewFile();
	// }
	return desc;
}

(3)测试

  1. 重启后端
  2. 简单测试几个功能:文件上传

3 拓展:模拟高并发的场景

103 实现优雅关闭应用(集成springboot自带的监控工具actuator)

1 为什么要优雅关闭呢?

       比如每一秒有上百笔的并发请求到订单接口,如果直接停掉应用,那这上百笔订单的线程没执行完导致这些订单就丢失了,这种情况是很严重的。所以一定要等到这些订单线程全部执行完之后,再去停掉应用,才能防止一些正在执行或者在执行的过程中的线程被强制停掉。

2 详细步骤

(1)ruoyi-admin/pom.xml中引入actuator依赖

<!-- 依赖springboot自带的监控工具actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

(2)ruoyi-admin/application.yml配置文件中endpoint开启shutdown

# 可监控:内存、线程、日志
management:
  endpoint:
    shutdown:
      # shutdown打开,即允许使用它去停止应用
      enabled: true
  endpoints:
    web:
      exposure:
        # 优雅关闭
        # include其实我们可以配置成" * ",但不建议这么写,因为很多东西都暴露出去对就项目来说是有风险的
        include: "shutdown"
      # 前缀路径
      base-path: /monitor

(3)SecurityConfig#configure():因为在没有登录的情况下就停止了,所以需要配置白名单。

.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
/**
* 1、其中" /monitor/ "对应base-path: /monitor,shutdown对应include: "shutdown"
*/
.antMatchers("/monitor/shutdown").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

(4)Post请求测试验证优雅停机 curl -X POST http://localhost:80/monitor/shutdown

  1. 重启后端
  2. 这个接口是自带的,所以需要按照它的规则去请求。是POST请求,可以用postman工具发送post请求:

104 实现swagger文档增强(knife4j)

1 为什么要增强?

  1. swagger界面风格、英文
  2. knife4j对比swagger相比有以下优势,友好界面,离线文档,接口排序,安全控制,在线调试,文档清晰,后端注解增强,容易上手。

2 前端ui增强,详细步骤

(1)ruoyi-admin\pom.xml模块添加整合依赖(替换掉swagger的ui)

  1. 针对不分离版 
    1. 把swagger的ui删除掉后:
    2. 替换成knife4j的ui:
      <!-- knife4j -->
      <dependency>
      	<groupId>com.github.xiaoymin</groupId>
      	<artifactId>knife4j-spring-boot-starter</artifactId>
      	<version>3.0.3</version>
      </dependency>
  2. 针对分离版本
    1. 直接在ruoyi-admin\pom.xml加入knife4j的依赖即可

(2)修改首页跳转访问地址

        针对不分离版本:SwaggerController.java修改跳转访问地址" /doc.html "

// 默认swagger-ui.html前端ui访问地址
public String index()
{
	return redirect("/swagger-ui.html");
}
// 修改成knife4j前端ui访问地址doc.html
public String index()
{
	return redirect("/doc.html");
}

        针对前后端分离版本:ruoyi-ui\src\views\tool\swagger\index.vue修改跳转访问地址为" /doc.html ":

(3)测试

  1. 重启前后端

  2. 浏览器访问:http://localhost:8080/doc.html#/home

  3. 登录系统,访问菜单系统工具/系统接口,出现如下图表示成功

     

(4)提示:引用knife4j-spring-boot-starter依赖,项目中的swagger依赖可以删除。

3 使用案例

 

4 拓展:后端注解增强
 

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

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

相关文章

《大型网站技术架构》第二篇 架构-高可用

高可用在公司中的重要性 对公司而言&#xff0c;可用性关系网站的生死存亡。对个人而言&#xff0c;可用性关系到自己的绩效升迁。 工程师对架构做了许多优化、对代码做了很多重构&#xff0c;对性能、扩展性、伸缩性做了很多改善&#xff0c;但别人未必能直观地感受到&#…

字节编码学习

字节编码学习 文章目录 字节编码学习01_字节与ASCII码表02_每个国家都有独特的码表03_国际化UTF-804_编码本和解码本不一致&#xff0c;乱码 01_字节与ASCII码表 public class Demo01 {public static void main(String[] args) {// 计算机的底层全部都是字节 ---- ----// 一个…

Android Studio实现简单ListView

效果图 MainActivity package com.example.listviewtest;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.widget.ListView;import com.example.listviewtest.adapter.PartAdapter; import com.example.listviewtest.bean.PartB…

多目标优化之MOEA-D算法,MATLAB代码,免费获取

今天给大家分享一期MOEA/D算法。1 引言 基于分解的多目标进化算法(MOEA/D)的核心思想将多目标优化问题被转化为一系列单目标优化子问题或者是多个多目标的子问题&#xff0c;然后利用子问题之间的邻域关系&#xff0c;采用协作的方式对这些子问题同时进行优化。从而向整个Paret…

大麦订单截图 一键生成订单截图

新版付款图样式展示 这个样式图就是在大麦刚付款完的一个订单截图&#xff0c;它的状态是等待卖家发货 下滑下载源码 下载源码&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

LoRaWAN网关与网络服务器(NS)的通信LNS协议介绍

将 LoRaWAN网关连接到 LoRaWAN 网络服务器 (LNS) 是一个两步过程,该过程使用 WebSocket 作为传输协议来交换包含 JSON 编码对象的文本记录。 首先,网关向LNS查询LNS实际连接端点的URI。其次,它与该端点建立数据连接以接收设置信息。从那时起,LoRa 上行链路和下行链路帧通过…

golang专栏

GOLANG专栏订阅会员 Golang基础教程 Golang基础教程 Golang练手算法 Golang练手算法 Golang设计模式 Golang设计模式 Golang数据结构和算法 Golang数据结构和算法 Golang并发编程 Golang并发编程 ORM框架Gorm Golang ORM框架gorm Golang源码分析 Golang源码分析 MySQL教…

校园防欺凌防霸凌该怎么做

校园防欺凌防霸凌该怎么做 校园防欺凌和霸凌是一个长期而全面的过程&#xff0c;需要学生、教师和家长共同参与和努力。以下是一些可以采取的措施&#xff1a; 1. 教育和意识提高&#xff1a;通过教育和培训&#xff0c;提高学生、教师和家长对欺凌和霸凌的认识和了解。学校可…

机器人制作开源方案 | 超市服务机器人

作者&#xff1a;林江斌 岳沛霖 李锦扬 单位&#xff1a;北京理工大学 机械与车辆学院 指导老师&#xff1a;李忠新 朱杰 一、作品简介 1.设计背景 当前社会疫情防控已经成为常态化&#xff0c;超市是人员流动相对密集的公共场所&#xff0c;超市防疫也是社会防疫工作中重要…

linuxARM裸机学习笔记(4)----GPIO中断以及定时器中断实验

1.中断向量表 这个表里面存放的都是中断向量&#xff0c;中断服务程序的入口地址或存放中断服务程序的首地址成为中断向量。中断向量表是一系列中断服务程序入口地址组成的表&#xff0c;当某个中断触发的时候会自动跳转到中断向量表对应的中断服务程序的入口。 2.NVIC(内嵌向…

vue3+ts+element-plus大屏看板---横向轮播(anime.js)

vue3ts大屏看板---横向轮播&#xff08;anime.js&#xff09; 1. 安装和引入anime.js1. 安装2. 引入* 引入报错&#xff1a;引入时候报错 2. 基于vue3tsanime.js实现一个大屏组件轮播效果&#xff0c;如下1. 写一个需要轮播的模块样式✏️ 代码&#xff08;有写注释&#xff09…

智能照明控制系统助力某商业综合体实现“双碳”-安科瑞黄安南

摘要&#xff1a;智能照明是当前非常普及的一种照明控制方式。广泛使用于建筑物,景观&#xff0c;公共场所。本文以智能照明在商业综合体中的应用为基础&#xff0c;主要介绍了智能照明系统的功能与特点&#xff0c;系统运用的效果&#xff0c;在建筑自动化系统中的地位及优势等…

oracle积累增量和差异增量

积累增量和差异增量&#xff1a; 对于 RMAN 来说&#xff0c;积累增量备份和差异增量备份都是增量备份的一种形式&#xff0c;它们之间的区别在于备份的范围和备份集的方式。 积累增量备份&#xff1a;在进行积累增量备份时&#xff0c;RMAN 会备份自最后一次完全备份或增量备…

JVM 性能优化思路

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ 一般在系统出现问题的时候&#xff0c;我们会考虑对 JVM 进行性能优化。优化思路就是根据问题的情况&#xff0c;结合工具进行问题排查&#xff0c;针对排查出来的可能问题…

06 - Stream如何提高遍历集合效率?

前面我们讲过 List 集合类&#xff0c;那我想你一定也知道集合的顶端接口 Collection。 在 Java8 中&#xff0c;Collection 新增了两个流方法&#xff0c;分别是 Stream() 和 parallelStream()。 1、什么是 Stream&#xff1f; 现在很多大数据量系统中都存在分表分库的情况…

安防视频监控平台EasyNVR页面无法上传授权文件,该如何进行授权?

TSINGSEE青犀视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif协议接入&#xff0c;并能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。在智慧安防等视频监控场景中&#xff0c;EasyNVR可提供视频实时监控直播、云端…

LeetCode 1289. 下降路径最小和 II:通俗易懂地讲解O(n^2) + O(1)的做法

【LetMeFly】1289.下降路径最小和 II&#xff1a;通俗易懂地讲解O(n^2) O(1)的做法 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-falling-path-sum-ii/ 给你一个 n x n 整数矩阵 arr &#xff0c;请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下…

【力扣每日一题】2023.8.10 下降路径最小和Ⅱ

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个数组&#xff0c;让我们模拟从上面第一层走到下面的最后一层&#xff0c;下降路径需要加上经过的格子的值&#xff0c;每层…

vue使用ElementUI

1.安装 npm i element-ui -S 2.引入 2.1完整引入 import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue;Vue.use(ElementUI); 2.2按需引入 说明&#xff1a;为了输入时候有提示&#xff0c;建…

【雕爷学编程】Arduino动手做(03)---RCWL-0516微波雷达传感器模块2

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…