Mybatis的关系关联配置

前言

MyBatis是一个流行的Java持久化框架,它提供了一种简单而强大的方式来映射Java对象和关系数据库之间的数据。在MyBatis中,关系关联配置是一种用于定义对象之间关系的方式,它允许我们在查询数据库时同时获取相关联的对象。

在MyBatis中,有三种主要的关系关联配置方式:一对一(One-to-One)、一对多(One-to-Many)和多对多(Many-to-Many)。

一. Mybatis关系关联配置的优劣

1.1 MyBatis中的关系关联配置具有以下好处:

  1. 简化数据查询:通过关系关联配置,可以在查询数据时自动加载相关联的数据,无需手动编写复杂的SQL语句。这简化了数据查询的过程,减少了开发人员的工作量。

  2. 提高代码可读性:通过关系关联配置,可以将数据表之间的关系直观地映射到Java对象中。这使得代码更易于理解和维护,提高了代码的可读性。

  3. 减少数据库访问次数:通过关系关联配置,可以一次性加载多个相关联的数据,减少了与数据库的交互次数。这可以提高系统的性能和响应速度。

  4. 支持对象导航:通过关系关联配置,可以在Java对象中直接访问相关联的数据,而无需手动编写额外的查询语句。这简化了代码的编写,提高了开发效率。

1.2 然而,MyBatis中的关系关联配置也存在一些缺点:

  1. 学习成本较高:关系关联配置需要了解MyBatis的配置文件和相关标签的使用方法。对于初学者来说,可能需要花费一些时间来学习和理解这些配置。

  2. 配置复杂性:对于复杂的关系关联,配置文件可能会变得复杂和冗长。这可能增加了维护和调试的难度。

  3. 性能问题:如果关系关联配置不合理,可能会导致数据加载过多或过少,从而影响系统的性能。因此,在配置关系关联时需要注意性能优化的问题。

二. 关联关系的方向

在MyBatis中,关系关联的方向可以分为两种:单向关联和双向关联。

单向关联

单向关联表示关系只在一个方向上存在,其中一个表可以关联到另一个表,但反过来不行。在单向关联中,只有一个表的对象包含了关联对象的引用,而关联对象本身不包含对关联表的引用。

例如,假设我们有两个表:User和Order,一个用户可以有多个订单。在这种情况下,我们可以在User对象中定义一个关联属性List<Order> orders,表示一个用户关联多个订单。但是,在Order对象中并不包含对用户的引用。

单向关联的配置在MyBatis中非常简单,只需要在<resultMap>中使用<collection>或<association>标签来定义关联即可。

双向关联

双向关联表示关系在两个表之间是相互关联的,每个表的对象都包含了对另一个表的引用。这样,我们可以通过一个表的对象访问到关联表的对象,也可以通过关联表的对象访问到原始表的对象。

以前面的例子为例,我们可以在User对象中定义一个关联属性List<Order> orders,表示一个用户关联多个订单。同时,在Order对象中也定义一个关联属性User user,表示一个订单关联一个用户。

双向关联的配置相对复杂一些,需要在<resultMap>中使用<collection>或<association>标签来定义关联,并在关联对象中使用<association>标签来定义反向关联。

需要注意的是,无论是单向关联还是双向关联,都需要在MyBatis的映射文件中进行配置。关联的方向取决于我们在配置时定义的关联属性和关联对象的引用。

总结来说,MyBatis中的关系关联可以是单向关联或双向关联。单向关联表示关系只在一个方向上存在,而双向关联表示关系在两个表之间是相互关联的。在配置关系关联时,我们需要定义关联属性和关联对象的引用,以确定关联的方向。

三. 一对一关联配置

一对一关联配置用于表示两个对象之间的一对一关系(例如夫妻关系,人与身份证)。在数据库中,这通常通过外键来实现。在MyBatis中,我们可以使用<association>元素来配置一对一关联。该元素通常嵌套在<resultMap>元素中,并使用property属性指定关联对象的属性名。

以订单表(order)和订单项表(orderItem)为例,一个订单项对应一个订单。

编写一个vo类继承orderItem,在映射文件中可以通过这个类拿到订单表和订单项表的每个属性:

package com.xissl.vo;import com.xissl.model.HOrder;
import com.xissl.model.HOrderItem;/*** @author xissl* @create 2023-09-04 9:52*/
public class OrderItemVo extends HOrderItem {private HOrder horder;public HOrder getHorder() {return horder;}public void setHorder(HOrder horder) {this.horder = horder;}
}

 在映射文件中配置一对一关联,HOrderItemMapper.xml

  <resultMap id="OrderItemVoMap" type="com.xissl.vo.OrderItemVo"><result column="order_item_id" property="orderItemId"></result><result column="product_id" property="productId"></result><result column="quantity" property="quantity"></result><result column="oid" property="oid"></result><association property="horder" javaType="com.xissl.model.HOrder"><result column="order_id" property="orderId"></result><result column="order_no" property="orderNo"></result></association></resultMap><select id="selectByOrderItemId" resultMap="OrderItemVoMap" parameterType="java.lang.Integer">select * from t_hibernate_order o,t_hibernate_order_item oi
where o.order_id=oi.oid and order_item_id= #{orderItemId}</select>

在上面的示例中,我们首先定义了一个resultMap,用于映射OrderItem对象和Order对象之间的关系。在resultMap中,我们使用association元素来配置一对一关联。association元素中的property属性指定了在OrderItem对象中表示Order对象的属性名,javaType属性指定了关联对象的类型。

然后,我们定义了一个查询语句selectByOrderItemId,使用resultMap来映射查询结果。

 编写mapper层接口:

OrderItemVo selectByOrderItemId(@Param("orderItemId") Integer orderItemId);

 业务逻辑层:

package com.xissl.biz;import com.xissl.model.HOrderItem;
import com.xissl.vo.OrderItemVo;
import org.apache.ibatis.annotations.Param;public interface HOrderItemBiz {OrderItemVo selectByOrderItemId(Integer orderItemId);
}

实现业务层接口:

package com.xissl.biz.impl;import com.xissl.biz.HOrderItemBiz;
import com.xissl.mapper.HOrderItemMapper;
import com.xissl.vo.OrderItemVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author xissl* @create 2023-09-04 9:59*/
@Service
public class HOrderItemBizImpl implements HOrderItemBiz {@Autowiredprivate HOrderItemMapper hOrderItemMapper;@Overridepublic OrderItemVo selectByOrderItemId(Integer orderItemId) {return hOrderItemMapper.selectByOrderItemId(orderItemId);}
}

  测试代码及结果:

package com.xissl.biz.impl;import com.xissl.biz.HOrderItemBiz;
import com.xissl.vo.OrderItemVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.junit.Assert.*;/*** @author xissl* @create 2023-09-04 10:01*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HOrderItemBizImplTest {@Autowiredprivate HOrderItemBiz hOrderItemBiz;@Testpublic void selectByOrderItemId() {OrderItemVo orderItemVo = hOrderItemBiz.selectByOrderItemId(27);System.out.println(orderItemVo);System.out.println(orderItemVo.getHorder());}
}

四. 一对多关联配置

一对多关联配置用于表示一个对象与多个相关对象之间的关系(例如用户与用户的订单,锁和钥匙)。在数据库中,这通常通过外键来实现。在MyBatis中,我们可以使用<collection>元素来配置一对多关联。该元素通常嵌套在<resultMap>元素中,并使用property属性指定关联对象的属性名。

以订单表(order)和订单项表(orderItem)为例,一个订单可以有多个订单项。

编写一个vo类继承order,在映射文件中可以通过这个类拿到订单表和订单项表的每个属性:

package com.xissl.vo;import com.xissl.model.HOrder;
import com.xissl.model.HOrderItem;import java.util.ArrayList;
import java.util.List;/*** @author xissl* @create 2023-09-04 8:49*/
public class OrderVo extends HOrder {private List<HOrderItem> orderItems = new ArrayList<>();public List<HOrderItem> getOrderItems() {return orderItems;}public void setOrderItems(List<HOrderItem> orderItems) {this.orderItems = orderItems;}
}

在映射文件中配置一对多关联,HOrderMapper.xml

<resultMap id="OrderVoMap" type="com.xissl.vo.OrderVo" ><result column="order_id" property="orderId"></result><result column="order_no" property="orderNo"></result><collection property="orderItems" ofType="com.xissl.model.HOrderItem"><result column="order_item_id" property="orderItemId"></result><result column="product_id" property="productId"></result><result column="quantity" property="quantity"></result><result column="oid" property="oid"></result></collection></resultMap><select id="selectByOid" resultMap="OrderVoMap" parameterType="java.lang.Integer">select * from t_hibernate_order o,t_hibernate_order_item oiwhere o.order_id=oi.oid and order_id= #{oid}</select>

在上面的示例中,我们首先定义了一个resultMap,用于映射Order对象和OrderItem对象之间的关系。在resultMap中,我们使用collection元素来配置一对多关联。collection元素中的property属性指定了在Order对象中表示订单项表的属性名,ofType属性指定了关联对象的类型。

然后,我们定义了一个查询语句selectByOid,使用resultMap来映射查询结果。

编写mapper层接口:

    OrderVo selectByOid(@Param("oid") Integer oid);

 业务逻辑层:

 OrderVo selectByOid(Integer oid);

 实现业务层接口:

package com.xissl.biz.impl;import com.xissl.biz.HOrderBiz;
import com.xissl.mapper.HOrderMapper;
import com.xissl.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author xissl* @create 2023-09-04 9:08*/
@Service
public class HOrderBizImpl implements HOrderBiz {@Autowiredprivate HOrderMapper hOrderMapper;@Overridepublic OrderVo selectByOid(Integer oid) {return hOrderMapper.selectByOid(oid);}
}

 测试代码及结果:

package com.xissl.biz.impl;import com.xissl.biz.HOrderBiz;
import com.xissl.vo.OrderVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.junit.Assert.*;/*** @author xissl* @create 2023-09-04 9:10*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HOrderBizImplTest {@Autowiredprivate HOrderBiz hOrderBiz;@Testpublic void selectByOid() {OrderVo orderVo = hOrderBiz.selectByOid(7);System.out.println(orderVo);orderVo.getOrderItems().forEach(System.out::println);}
}

五. 多对多关联配置

多对多关联配置用于表示两个对象之间的多对多关系(例如老师和学生)。在数据库中,这通常通过中间表来实现。在MyBatis中,我们可以使用<collection>元素来配置多对多关联。该元素通常嵌套在<resultMap>元素中,并使用property属性指定关联对象的属性名。

多对多关系就是和一对多的关系的大同小异,只是多对多的关系可以看成两个一对多关系。

vo类 BookVo:

package com.xissl.vo;import com.xissl.model.HBook;
import com.xissl.model.HCategory;import java.util.List;/*** @author xissl* @create 2023-09-04 10:43*/
public class HBookVo extends HBook {private List<HCategory> categories;public List<HCategory> getCategories() {return categories;}public void setCategories(List<HCategory> categories) {this.categories = categories;}
}

CategoryVo:

package com.xissl.vo;import com.xissl.model.HBook;
import com.xissl.model.HCategory;import java.util.ArrayList;
import java.util.List;/*** @author xissl* @create 2023-09-04 11:03*/
public class CategroyVo extends HCategory {private List<HBook> hbooks = new ArrayList<>();public List<HBook> getHbooks() {return hbooks;}public void setHbooks(List<HBook> hbooks) {this.hbooks = hbooks;}
}

映射文件 HBookMapper.xml

 <resultMap id="HBookVoMap" type="com.xissl.vo.HBookVo"><result column="book_id" property="bookId"></result><result column="book_name" property="bookName"></result><result column="price" property="price"></result><collection property="categories" ofType="com.xissl.model.HCategory"><result column="category_id" property="categoryId"></result><result column="category_name" property="categoryName"></result></collection></resultMap><!--  根据书籍id查询出书籍信息及所属类别--><select id="selectByBid" resultMap="HBookVoMap" parameterType="java.lang.Integer">select * from t_hibernate_book b, t_hibernate_book_category bc,
t_hibernate_category c where b.book_id = bc.bid and bc.cid = c.category_id
and b.book_id= #{bid}</select>

HCategoryMapper.xml 

  <resultMap id="CategoryVoMap" type="com.xissl.vo.CategroyVo"><result column="category_id" property="categoryId"></result><result column="category_name" property="categoryName"></result><collection property="hbooks" ofType="com.xissl.model.HBook"><result column="book_id" property="bookId"></result><result column="book_name" property="bookName"></result><result column="price" property="price"></result></collection></resultMap><select id="selectByCategroyId" resultMap="CategoryVoMap" parameterType="java.lang.Integer">select * from t_hibernate_book b, t_hibernate_book_category bc,
t_hibernate_category c where b.book_id = bc.bid and bc.cid = c.category_id
and c.category_id= #{cid}</select>

 mapper层接口 BookMapper:

    HBookVo selectByBid(@Param("bid") Integer bid);

CategoryMapper 

    HBookVo selectByBid(@Param("bid") Integer bid);

业务逻辑层:

    HBookVo selectByBid(Integer bid);

 

    CategroyVo selectByCategroyId(Integer cid);

 实现业务层 BookBiz

package com.xissl.biz.impl;import com.xissl.biz.HBookBiz;
import com.xissl.mapper.HBookMapper;
import com.xissl.vo.HBookVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author xissl* @create 2023-09-04 10:55*/
@Service
public class HBookBizImpl implements HBookBiz {@Autowiredprivate HBookMapper hBookMapper;@Overridepublic HBookVo selectByBid(Integer bid) {return hBookMapper.selectByBid(bid);}
}

实现CategoryBiz

 

package com.xissl.biz.impl;import com.xissl.biz.HCategoryBiz;
import com.xissl.mapper.HCategoryMapper;
import com.xissl.vo.CategroyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author xissl* @create 2023-09-04 11:11*/
@Service
public class HCategoryBizImpl implements HCategoryBiz {@Autowiredprivate HCategoryMapper hCategoryMapper;@Overridepublic CategroyVo selectByCategroyId(Integer cid) {return hCategoryMapper.selectByCategroyId(cid);}
}

 测试代码及结果:

package com.xissl.biz.impl;import com.xissl.biz.HBookBiz;
import com.xissl.vo.HBookVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.junit.Assert.*;/*** @author xissl* @create 2023-09-04 10:56*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HBookBizImplTest {@Autowiredprivate HBookBiz hBookBiz;@Testpublic void selectByBid() {HBookVo hBookVo = hBookBiz.selectByBid(8);System.out.println(hBookVo);hBookVo.getCategories().forEach(System.out::println);}
}

 

 

package com.xissl.biz.impl;import com.xissl.biz.HCategoryBiz;
import com.xissl.vo.CategroyVo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.junit.Assert.*;/*** @author xissl* @create 2023-09-04 11:12*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HCategoryBizImplTest {@Autowiredprivate HCategoryBiz hCategoryBiz;@Testpublic void selectByCategroyId() {CategroyVo categroyVo = hCategoryBiz.selectByCategroyId(8);System.out.println(categroyVo);categroyVo.getHbooks().forEach(System.out::println);}
}

 

除了上述关系关联配置方式,MyBatis还提供了其他一些配置选项,如延迟加载(Lazy Loading)和级联操作(Cascade)。延迟加载允许我们在需要时才加载关联对象的数据,而级联操作允许我们在操作主对象时同时操作关联对象。

总结起来,MyBatis中的关系关联配置提供了一种灵活而强大的方式来处理对象之间的关系。通过合理配置关系关联,我们可以轻松地进行复杂的数据库查询和操作。

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

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

相关文章

第17章 站点构建

mini商城第17章 站点构建 一、课题 站点构建 二、回顾 1、Gateway限流 2、Nginx限流 3、Redis集群应用 4、缓存灾难处理 三、目标 1、Sentinel Sentinel介绍 Sentinel核心功能 Sentinel集成Gateway Sentinel控制台 2、Lvs+Nginx集群 Lvs负载均衡模式 NAT模式 TUN模式 …

实现在外网SSH远程访问内网树莓派的详细教程

文章目录 如何在局域网外SSH远程访问连接到家里的树莓派&#xff1f;如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar4.2 cpolar进行token认证4.3 配置cpol…

HCIA自学笔记01-冲突域

共享式网络&#xff08;用同一根同轴电缆通信&#xff09;中可能会出现信号冲突现象。 如图是一个10BASE5以太网&#xff0c;每个主机都是用同一根同轴电缆来与其它主机进行通信&#xff0c;因此&#xff0c;这里的同轴电缆又被称为共享介质&#xff0c;相应的网络被称为共享介…

15:00面试,15:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%,…

算法通关村第12关【白银】| 字符串经典问题

一、反转问题 1.反转字符串 思路&#xff1a;双指针&#xff0c;反转数组一个套路 class Solution {public void reverseString(char[] s) {int l 0;int r s.length -1;while(l<r){char c s[l];s[l] s[r];s[r] c;l;r--;}} } 2.k个一组反转 思路&#xff1a;每k个进行…

第14章_瑞萨MCU零基础入门系列教程之QSPI

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

【leetcode 力扣刷题】删除字符串中的子串or字符以满足要求

删除字符串中的子串或者字符以满足题意要求 1234. 替换子串得到平衡字符串680. 验证回文串917. 仅仅反转字母 1234. 替换子串得到平衡字符串 题目链接&#xff1a;1234. 替换子串得到平衡字符串 题目内容&#xff1a; 题目中给出了平衡字符串的定义——只有’Q’&#xff0c;…

彻底掌握Protobuf编码原理与实战

目录 1.类型2.VARINT 2.1 无符号数2.2 有符号数3.定长 3.1 I64类型3.2 I32类型4.LEN5.代码 学习这些有什么用&#xff1f; - 如果你是后端开发者&#xff0c;掌握这个对工作非常有用 - 如果你是求职者&#xff0c;面试时可以临危不惧 1.类型 最近看到有直接操作wire type相关的…

React+antd实现可编辑单元格,非官网写法,不使用可编辑行和form验证

antd3以上的写法乍一看还挺复杂&#xff0c;自己写了个精简版 没用EditableRowCell的结构&#xff0c;也不使用Context、高阶组件等&#xff0c;不使用form验证 最终效果&#xff1a; class EditableCell extends React.Component {state {editing: false};toggleEdit () &…

系统软件启动过程

实验一&#xff1a;系统软件启动过程 参考 重要文件 调用顺序 1. boot/bootasm.S | bootasm.asm&#xff08;修改了名字&#xff0c;以便于彩色显示&#xff09;a. 开启A20 16位地址线 实现 20位地址访问 芯片版本兼容通过写 键盘控制器8042 的 64h端口 与 60h端口。b.…

Selenium自动化测试框架常见异常分析及解决方法

01 pycharm中导入selenium报错 现象: pycharm中输入from selenium import webdriver, selenium标红 原因1: pycharm使用的虚拟环境中没有安装selenium, 解决方法: 在pycharm中通过设置或terminal面板重新安装selenium 原因2: 当前项目下有selenium.py,和系统包名冲突导致, …

Amazon Aurora MySQL 和 Amazon RDS for MySQL 集群故障转移和只读实例扩容时间测试

01 测试背景 Amazon Aurora MySQL 是与 MySQL 兼容的关系数据库&#xff0c;专为云而打造&#xff0c;性能和可用性与商用数据库相当&#xff0c;成本只有其 1/10。 Amazon RDS for MySQL 让您能够在云中更轻松设置、操作和扩展 MySQL 部署。借助 Amazon RDS&#xff0c;您可以…

SpringBoot环境MongoDB分页+去重+获取去重后的原始数据

最近有个比较复杂的MongoDB查询需求&#xff0c; 要求1&#xff1a;获取最近订单表中的请求参数信息&#xff0c;并需要按照请求参数中的账号进行去重 要求2&#xff1a;数据量可能比较大&#xff0c;因此需要做分页查询 研究了大半天&#xff0c;终于搞出了解决方案&#xff0…

MySQL触发器详解保证入土

文章目录 简介一、MySQL触发器基础触发器分类基础常用关键字1. 定义触发器2. 创建和删除触发器3. 执行时机和条件 二、MySQL触发器的使用场景1. 数据完整性约束插入触发器更新触发器删除触发器 2. 数据变更日志的记录与追踪3. 触发器与存储过程的对比与选择 三、触发器的性能和…

C++学习笔记(重载、类)

C 1、函数重载2、类2.1、类的方法和属性2.2、类的方法的定义2.3、构造器和析构器2.4、基类与子类2.5、类的public、protected、private继承2.6、类的方法的重载2.7、子类方法的覆盖2.8、继承中的构造函数和析构函数 1、函数重载 函数重载大概可以理解为&#xff0c;定义两个名…

C语言实现三字棋

实现以下&#xff1a; 1游戏不退出&#xff0c;继续玩下一把&#xff08;循环&#xff09; 2应用多文件的形式完成 test.c. --测试游戏 game.c -游戏函数的实现 game.h -游戏函数的声明 (2)游戏再走的过程中要进行数据的存储&#xff0c;可以使用3*3的二维数组 char bor…

idea VCS配置多个远程仓库

Idea VCS配置多个远程仓库 首先要有两个或多个不同远程仓库地址 idea 添加数据源 查看推送记录 添加数据源 ok之后填写账号密码 推送本地项目 选择不同远程地址 push 查看不同远程地址的 不同分支的 推送记录 不期而遇的温柔&#xff1a; 应用开源架构进行项目开发&#xff0…

Java版企业电子招标采购系统源码—企业战略布局下的采购寻源

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部供…

Qt串口基本设置与协议收发

前言 1.一直都想要做一个Qt上位机&#xff0c;趁着这个周末有时间&#xff0c;动手写一下 2.comboBox没有点击的信号&#xff0c;所以做了一个触发的功能 3.Qt的数据类型很奇怪&#xff0c;转来转去的我也搞得很迷糊 4.给自己挖个坑&#xff0c;下一期做一个查看波形的上位…

Android 9.0 网络之netd详解

一、DHCP流程 分析netd之前先了解一下网络自动获取IP流程&#xff0c;借鉴下图流程查看代码&#xff1a; &#xff08;1&#xff09;WIFI扫描到可用网络后进行连接&#xff0c;代码路径&#xff1a;\frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiStateMa…