Postgresql关于JSON、JSONB的操作符、处理函数(持续更新)

news2024/11/9 9:43:35

一、postgresql实用函数

(只列举本次用到的函数,其他函数在文章后面有详解)

1.1、将jsonb格式的数组中的值展开/分解成单独的数据/对象?

SELECT answer_id,  jsonb_array_elements(option_ids)::INTEGER  AS option_id

FROM db_live_answer 

WHERE survey_code='No.20230605165428002'

 

 

1.2、如何根据对象id将jsonb数组展开到每个jsonb列的对象中?

 如果所有json数组都包含两个新列的两个元素,那么使用固定路径,如dmfay的答案。 否则,你应该使用jsonb_array_elements()两次取消数组,分别为text_id_onetext_id_two

update sample t set
    text_id_one = value1,
    text_id_two = value2
from sample s, 
    jsonb_array_elements(s.metadata_array) as e1(value1),
    jsonb_array_elements(s.metadata_array) as e2(value2)
where s.id = t.id
    and value1->>'id' = 'textIdOne'
    and value2->>'id' = 'textIdTwo'
returning t.*

如果数组中有两个以上的元素,则此变体可能更高效(也更方便):

update sample t
set 
    text_id_one = arr1->0,
    text_id_two = arr2->0
from (
    select 
        id,
        jsonb_agg(value) filter (where value->>'id' = 'textIdOne') as arr1,
        jsonb_agg(value) filter (where value->>'id' = 'textIdTwo') as arr2
    from sample,
    jsonb_array_elements(metadata_array)
    group by id
    ) s
where t.id = s.id
returning t.*

例子来源:如何根据对象id将jsonb数组展开到每个jsonb列的对象中?

2、postgresql操作符的使用

一、 -> 和 ->>  (适用于操作数组) :

-> 表示获取一个JSON数组元素,支持下标值(下标从0开始)、Key获取。

->> 表示获取一个JSON对象字符串。

代码:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON -> 1;
结果:
{"b":2}
以上,::JSON 表示声明前面的字符串为一个JSON字符串对象,而且PostgreSQL中的JSON、JSONB对象 Key的声明必须是字符串 。同时,1表示获取JSON数组中下标值为1的JSON对象。

接下来,看下 ->> 的用法:

代码:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1;
结果:
{"b":2}
以上,->> 的查询结果和 -> 对比不太直观,我们可以进一步验证。

连用:

代码:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON -> 1 -> 'b';
结果:
2
以上,我们可以看到首先我们使用下标的方式,获取JSON数组中下标值为1的JSON对象 {"b":2}。然后,我们通过Key的方式来获取这个JSON对象的Value值,结果是 2。

接下来,我们测试下 ->> 的方式来获取:

代码:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
 
报错:
[SQL]SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
 
[Err] 错误:  操作符不存在: text -> unknown
LINE 1: SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
                                                       ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
以上,可以看到错误提示操作符不存在,因为第一步查询出来的是一个字符串,不是JSON对象。

改成正确提取方式:

代码:
SELECT ('[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1)::JSON -> 'b';
结果:
2
以上,可以看到现在可以正确查询出结果,我们将第一步查询出来的字符串转成JSON对象,然后通过 Key 的方式来获取 Value。不过,这种查询方式相对于 -> 来说还是比较繁琐的。

二、 #> 和 #>> (适用于操作对象)

在前一步,我们在一个JSON数组中可以使用 -> 下标值的方式来获取一个JSON对象。但是,如果我们我们检索的不是JSON数组,而是一个JSON对象中的JSON对象。很显然,这种下标获取的方式不再适用。不过,我们可以使用下面的方式来获取。

#> 表示获取指定路径的一个JSON对象,

#>>表示获取指定路径的一个JSON对象的字符串。

代码:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON #> '{b}'
结果:
{"ba":"b1","bb":"b2"}
以上,我们使用 #> 方式来获取一个JSON对象中的JSON对象。

注意:

在获取一个JSON对象时,除非是JSON数组中的下标,必须要要用 { } 将JSON对象的 Key 包裹起来,否则会抛出异常。

代码:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'b'
结果:
[Err] 错误:  有缺陷的数组常量:"b"
LINE 1: SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'b'
                                                                ^
DETAIL:  数组值必须以 "{" 或者维度信息开始。

同样的,我们还可以在 #> 的基础上,继续获取这个JSON对象内的相关信息。

代码:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'{b}'->'ba'
结果:
"b1"
​​​​​​以上,可以看到 -> 获取的是一个JSON对象。->>是获取的一个text 文本


二、PostgreSQL 操作符、函数

json和jsonb 操作符

操作符右操作数类型描述例子例子结果
->int获得 JSON 数组元素(索引从 0 开始,负整数从末尾开始计)[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2{"c":"baz"}
->text通过键获得 JSON 对象域{"a": {"b":"foo"}}'::json->'a'{"b":"foo"}
->>int以text形式获得 JSON 数组元素[1,2,3]'::json->>23
->>text以text形式获得 JSON 对象域{"a":1,"b":2}'::json->>'b'2
#>text[]获取在指定路径的 JSON 对象{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'{"c": "foo"}
#>>text[]以text形式获取在指定路径的 JSON 对象{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'3

额外的jsonb操作符

操作符右操作数类型描述例子
@>jsonb左边的 JSON 值是否在顶层包含右边的 JSON 路径/值项?{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb
<@jsonb左边的 JSON 路径/值项是否被包含在右边的 JSON 值的顶层?{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb
?text键/元素字符串是否存在于 JSON 值的顶层?{"a":1, "b":2}'::jsonb ? 'b'
?|text[]这些数组字符串中的任何一个是否做为顶层键存在?{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c']
?&text[]是否所有这些数组字符串都作为顶层键存在?["a", "b"]'::jsonb ?& array['a', 'b']
||jsonb把两个jsonb值串接成一个新的jsonb值["a", "b"]'::jsonb || '["c", "d"]'::jsonb
-text从左操作数删除键/值对或者string 元素。键/值对基于它们的键值来匹配。{"a": "b"}'::jsonb - 'a'
-text[]从左操作数中删除多个键/值对或者string元素。键/值对基于它们的键值来匹配。{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[]
-integer删除具有指定索引(负值表示倒数)的数组元素。如果 顶层容器不是数组则抛出一个错误。["a", "b"]'::jsonb - 1
#-text[]删除具有指定路径的域或者元素(对于 JSON 数组,负值 表示倒数)["a", {"b":1}]'::jsonb #- '{1,b}'

JSON 创建函数

函数描述例子例子结果
to_json(anyelement)  to_jsonb(anyelement)    把该值返回为json或者jsonb。数组和组合 会被(递归)转换成数组和对象;对于不是数组和组合的值,如果有 从该类型到json的造型,造型函数将被用来执行该 转换;否则将产生一个标量值。对于任何不是数字、布尔、空值的标 量类型,将使用文本表达,在这种风格下它是一个合法的 json或者jsonb值。to_json('Fred said "Hi."'::text)Fred said \Hi.\""
array_to_json(anyarray [, pretty_bool])    把数组作为一个 JSON 数组返回。一个 PostgreSQL 多维数组会成为一个数组 的 JSON 数组。如果pretty_bool为真,将在 第 1 维度的元素之间增加换行。array_to_json('{{1,5},{99,100}}'::int[])[[1,5],[99,100]]
row_to_json(record [, pretty_bool])    把行作为一个 JSON 对象返回。如果pretty_bool为真,将在第1层元素之间增加换行。row_to_json(row(1,'foo')){"f1":1,"f2":"foo"}
json_build_array(VARIADIC "any")   jsonb_build_array(VARIADIC "any")    从一个可变参数列表构造一个可能包含异质类型的 JSON 数组。json_build_array(1,2,'3',4,5)[1, 2, "3", 4, 5]
json_build_object(VARIADIC "any")   jsonb_build_object(VARIADIC "any")    从一个可变参数列表构造一个 JSON 对象。通过转换,该参数列表由交替 出现的键和值构成。json_build_object('foo',1,'bar',2){"foo": 1, "bar": 2}
json_object(text[])  jsonb_object(text[])    从一个文本数组构造一个 JSON 对象。该数组必须可以是具有偶数个成员的 一维数组(成员被当做交替出现的键/值对),或者是一个二维数组(每一个 内部数组刚好有 2 个元素,可以被看做是键/值对)。json_object('{a, 1, b, "def", c, 3.5}')  json_object('{{a, 1},{b, "def"},{c, 3.5}}')    {"a": "1", "b": "def", "c": "3.5"}

json_object(keys text[], values text[]) 

jsonb_object(keys text[], values text[])

 json_object的这种形式从两个独立的数组得到键/值对。在其 他方面和一个参数的形式相同。json_object('{a, b}', '{1,2}'){"a": "1", "b": "2"}

JSON 处理 

函数返回值描述例子例子结果
json_array_length(json)  jsonb_array_length(jsonb)int返回最外层 JSON 数组中的元素数量。json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')5
json_each(json) 
jsonb_each(jsonb)
setof key text, value json
setof key text, value jsonb
扩展最外层的 JSON 对象成为一组键/值对。select * from json_each('{"a":"foo", "b":"bar"}') key | value
-----+-------
 a   | "foo"
 b   | "bar"
json_each_text(json)  jsonb_each_text(jsonb)setof key text, value text扩展最外层的 JSON 对象成为一组键/值对。返回值将是text类型。select * from json_each_text('{"a":"foo", "b":"bar"}') key | value
-----+-------
 a   | foo
 b   | bar
json_extract_path(from_json json, VARIADIC path_elems text[])   jsonb_extract_path(from_json jsonb, VARIADIC path_elems text[])json
jsonb
返回由path_elems指向的 JSON 值(等效于#>操作符)。json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4'){"f5":99,"f6":"foo"}
json_extract_path_text(from_json json, VARIADIC path_elems text[])  jsonb_extract_path_text(from_json jsonb, VARIADIC path_elems text[]) text以text返回由path_elems指向的 JSON 值(等效于#>>操作符)。json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6')foo
json_object_keys(json)  jsonb_object_keys(jsonb)setof text返回最外层 JSON 对象中的键集合。json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')json_object_keys
------------------
 f1
 f2
json_populate_record(base anyelement, from_json json)  jsonb_populate_record(base anyelement, from_json jsonb)anyelement扩展from_json中的对象成一个行,它的列匹配由base定义的记录类型(见下文的注释)。select * from json_populate_record(null::myrowtype, '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}}') a |   b       |      c
---+-----------+-------------
 1 | {2,"a b"} | (4,"a b c")
json_populate_recordset(base anyelement, from_json json)  jsonb_populate_recordset(base anyelement, from_json jsonb)setof anyelement扩展from_json中最外的对象数组为一个集合,该集合的列匹配由base定义的记录类型。select * from json_populate_recordset(null::myrowtype, '[{"a":1,"b":2},{"a":3,"b":4}]') a | b
---+---
 1 | 2
 3 | 4
json_array_elements(json)  jsonb_array_elements(jsonb)setof json
setof jsonb
把一个 JSON 数组扩展成一个 JSON 值的集合。select * from json_array_elements('[1,true, [2,false]]')value
-----------
 1
 true
 [2,false]
json_array_elements_text(json)  jsonb_array_elements_text(jsonb)setof text把一个 JSON 数组扩展成一个text值集合。select * from json_array_elements_text('["foo", "bar"]')  value
-----------
 foo
 bar
json_typeof(json)  jsonb_typeof(jsonb)text把最外层的 JSON 值的类型作为一个文本字符串返回。可能的类型是: object、array、string、number、 boolean以及null。json_typeof('-123.4')number
json_to_record(json)  jsonb_to_record(jsonb)record从一个 JSON 对象(见下文的注解)构建一个任意的记录。正如所有返回record 的函数一样,调用者必须用一个AS子句显式地定义记录的结构。select * from json_to_record('{"a":1,"b":[1,2,3],"c":[1,2,3],"e":"bar","r": {"a": 123, "b": "a b c"}}') as x(a int, b text, c int[], d text, r myrowtype) a |    b    |    c    | d |       r
---+---------+---------+---+---------------
 1 | [1,2,3] | {1,2,3} |   | (123,"a b c")
json_to_recordset(json)  jsonb_to_recordset(jsonb)setof record从一个 JSON 对象数组(见下文的注解)构建一个任意的记录集合。正如所有返回record 的函数一样,调用者必须用一个AS子句显式地定义记录的结构。select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text); a |  b
---+-----
 1 | foo
 2 |
json_strip_nulls(from_json json)  jsonb_strip_nulls(from_json jsonb)json
jsonb
返回from_json,其中所有具有空值的 对象域都被省略。其他空值不动。json_strip_nulls('[{"f1":1,"f2":null},2,null,3]')[{"f1":1},2,null,3]
jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean])jsonb返回target,其中由 path指定的节用 new_value替换,如果 path指定的项不存在并且 create_missing为真(默认为 true)则加上 new_value。正如面向路径的 操作符一样,出现在path中的 负整数表示从 JSON 数组的末尾开始数。jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false) jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}','[2,3,4]')[{"f1":[2,3,4],"f2":null},2,null,3][{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]
jsonb_insert(target jsonb, path text[], new_value jsonb, [insert_after boolean])jsonb返回被插入了new_value的target。如果path指定的target节在一个 JSONB 数组中,new_value将被插入到目标之前(insert_after为false,默认情况)或者之后(insert_after为真)。如果path指定的target节在一个 JSONB 对象内,则只有当target不存在时才插入new_value。对于面向路径的操作符来说,出现在path中的负整数表示从 JSON 数组的末尾开始计数。jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"')  jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true){"a": [0, "new_value", 1, 2]}  {"a": [0, 1, "new_value", 2]}
jsonb_pretty(from_json jsonb)text把from_json返回成一段 缩进后的 JSON 文本。jsonb_pretty('[{"f1":1,"f2":null},2,null,3]')[
    {
        "f1": 1,
        "f2": null
    },
    2,
    null,
    3
]

 参考:PostgreSQL中JSON函数和操作符_function jsonb_set(json, unknown, unknown) does no_EngineerForSoul的博客-CSDN博客

postgresql 关于JSON、JSONB操作符以处理函数_postgresql json函数_谷满满的博客-CSDN博客

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

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

相关文章

Java HashMap初始化大小设置多少合适

修改公司老代码的时候&#xff0c;发现阿里编码规约插件提示HashMap初始化时尽量指定初始值大小&#xff0c;因为设置合理的初始值可以提升性能&#xff1a; HashMap继承自AbstractMap类&#xff0c;实现了Map、Cloneable、java.io.Serializable接口&#xff0c;是基于散列表实…

Prompt 工程指南(三)—— 高级技术篇之零样本和少样本提示

到目前为止&#xff0c;显而易见的是&#xff0c;改进提示有助于在不同任务上获得更好的结果。这就是提示工程背后的理念和目标。 虽然上篇教程介绍的基本示例已经很有趣&#xff0c;但在接下来的几篇教程中&#xff0c;我们将介绍更高级的 Prompt 提示工程技巧&#xff0c;使…

LabVIEW编程开发PCB测试仪

LabVIEW编程开发PCB测试仪 使用PXI和LabVIEW的PCB钉床测试仪 用于PCB&#xff08;印刷电路板&#xff09;的钉床测试仪&#xff0c;使用PXI和LabVIEW。一家电子制造公司需要测试仪来测试他们的PCB产品。钉床测试仪是一种具有连接到电路板上各个测试点的引脚的测试。电路板需要…

【大数据学习篇12】在linux上安装jupyter

下面介绍在liunx怎么安装jupyter&#xff0c;一步到位介绍。 1、安装Anaconda3 1.1 自己选择一个位置下载 wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh1.2 进入自己的安装目录&#xff0c;安装anaconda bash Anaconda3-5.2.0-Linux-x86_64.sh一…

小程序模板语法样式与页面配置

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/front-end-tutorial 】或者公众号【AIShareLab】回复 小程序 也可获取。 文章目录 小程序模板与配置WXML 模板语法数据绑定事件绑定小程序中常用的事件事件对象的属性列表target 和 currentTarget 的…

spark入门 高可用部署HA(五)

一、standalone基于修改部署 https://blog.csdn.net/weixin_43205308/article/details/131070277?spm1001.2014.3001.5501 二、安装ZOOKEEPER zookeeper 安装下载与集群 三、修改conf下的spark-env.sh vim conf/spark-env.sh注释以下内容&#xff08;根据自己环境修改&am…

备战金九银十:大厂面试官必问MySQL连环炮全梳理,你扛得住嘛?

最近后台好多小伙伴发私信咨询阿Q&#xff0c;问马上就是金九银十的面试黄金期了&#xff0c;该如何在三个月内突击一下&#xff0c;以便更好地通过面试呢&#xff1f; 阿Q的想法就是需要对自己掌握的知识进行归纳整理&#xff0c;系统的、分类的去复习相关的知识点。这样也能…

公司新来了个00后测开,上来一顿操作给我秀麻了.....

开年公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司实习半年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍!给公司…

提升效率:P4VFS让虚拟文件同步更迅速、更简单

虚拟文件同步&#xff08;Virtual File Sync&#xff09;是一个备受期待的功能集&#xff0c;能够显著缩短Perforce Helix Core用户的同步时间。本篇文件将解释什么是虚拟文件同步&#xff0c;如何设置它以及如何使用它。 什么是虚拟文件同步&#xff1f; 虚拟文件同步是一项…

配置Wildfly的JDBC驱动程序

1、环境 windows10、Wildfly26.1.3、JDK8.0、mysql8.0 2、配置方式 配置Wildfly的JDBC驱动一般有两种方式 1️⃣、以module的方式安装&#xff1b; 2️⃣、以应用deploy的程序包方式安装&#xff1b; 以module方式安装&#xff0c;是把驱动置于应用服务器中&#xff1b;以…

Ubuntu 20.04 Apache2 增加不同端口站点

概述 Apache HTTP Server&#xff08;简称Apache&#xff09;是Apache软件基金会的一个开放源码的网页服务器软件&#xff0c;可以在大多数电脑操作系统中运行。由于其跨平台和安全性[注 1]&#xff0c;被广泛使用&#xff0c;是最流行的Web服务器软件之一。它快速、可靠并且可…

ROS:move_base路径规划介绍、更换全局路径规划算法(A star、Dijkstra、DWA,测试当前是哪种算法,效果展示图)

前提&#xff1a;需要安装navigation包&#xff0c;才可以运行move_base。 一.move_base路径规划包内容 二.更换全局路径规划算法&#xff08;A*、Dijkstra、DWA&#xff09; A*、Dijkstra属于全局路径规划、DWA属于局部路径规划。 1、move_base.launch move_base.launch文…

开源 AI 面临的挑战

译者&#xff1a;明明如月 人工智能的代价 尽管我坚信开源人工智能将继续蓬勃发展&#xff0c;但我也认为未来几年企业和政府将越来越有动机限制对新型神经网络架构和技术的应用。本文旨在预测并概述可能在本十年发生的潜在颠覆性变革&#xff0c;并提出一些想法和解决方案&a…

玩转css逐帧动画,努力成为更优质的Ikun~

&#x1f389; 一、前言 css3的animation想必大家都知道吧&#xff0c;那 steps 逐帧动画你知道吗&#xff1f;对于我来说&#xff0c;实际工作及练习中也很少用到这种跳跃式变化的动画&#xff0c;而它start和end的解释又比较“不说人话”&#xff0c;以前用到steps动画的时候…

FL Studio21水果软件各个版本功能区别对比

作为音乐人&#xff0c;在电脑上进行编曲&#xff0c;混音&#xff0c;合成是家常便饭&#xff0c;而市面上大家常用的音乐编曲制作软件很多&#xff0c;小编在这里就给大家做一个推荐。 大家常听到的音乐编曲制作软件大多是Cubase、Nuendo、Pro Tools、 SONAR等等&#xff0c…

Qt中QFile类读取ansi编码格式txt文件,在QTextEdit控件中显示乱码

系列文章目录 文章目录 系列文章目录前言一、依然无法解决乱码问题二、解决办法1.方法一&#xff1a;使用QString的fromLocal8Bit()函数2.读取utf-8编码格式的文件 总结 前言 使用Qt中的QFile类读取ANSI编码格式的文本文件&#xff0c;并在QTextEdit控件中显示乱码&#xff0c…

适配器模式的运用

文章目录 一、适配器模式的运用1.1 介绍1.2 适配器模式结构1.3 类适配器模式1.3.1 类适配器模式类图1.3.2 代码 1.4 对象适配器模式1.4.1 对象适配器模式类图1.4.2 代码 1.5 应用场景1.6 JDK源码解析1.6.1 字节流到字符流的转换类图1.6.2 部分源码分析1.6.3 总结 一、适配器模式…

MyBatis的使用、Spring AOP、Spring事务

一、MyBatis 的使用 1、环境配置 1.1、建库建表 -- 创建数据库 drop database if exists mycnblog; create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使⽤数据数据 use mycnblog;-- 创建表[⽤户表] drop table if exists userinfo; create table userinfo(id in…

智能算法终极大比拼,以CEC2017测试函数为例,十种智能算法直接打包带走,不含任何套路!

包含人工蜂群(ABC)、灰狼(GWO)、差分进化(DE)、粒子群(PSO)、麻雀优化(SSA)、蜣螂优化(DBO)、白鲸优化(BWO)、遗传算法(GA)、粒子群算法(PSO)&#xff0c;基于反向动态学习的差分进化算法&#xff0c;共十种算法&#xff0c;直接一文全部搞定&#xff01; 还是老规矩&#xff…

Android MaterialComponents主题下Button设置background无效

问题描述 使用的主题代码如下图&#xff1a; <!-- Base application theme. --><style name"Base.Theme.MyApplication" parent"Theme.Material3.DayNight.NoActionBar"><!-- Customize your light theme here. --><!-- <item na…