monkeyrunner环境搭建和初步用法

news2024/12/26 23:13:59

一、打开模拟器

运行monkeyrunner之前必须先运行相应的模拟器,不然monkeyrunner无法连接设备。

Elipse打开Android模拟器或在CMD中用Android命令打开模拟器。这里重点讲一下在CMD中用Android命令打开模拟器

命令:emulator -avd test (注意:test为虚拟设备的名称——AVD的全称为:Android Virtual Device,就是Android运行的虚拟设备,如下图所示:)

上面命令中的test是模拟器名称。使用时需要改成实际名字。

 

 

如果正常,模拟器应该可以启动起来了。

如果执行的结果出现以下错误内容:

  1. PANIC: Could not open: C:\Documents and Settings\sAdministrator\.android/avd/test.ini  

如下图所示:

原因在于你的环境变量缺少配置。请在系统变量中添加“ANDROID_SDK_HOME”,设置其值为“C:\Documents and Settings\Administrator”(注意:这里的值不能为C:\Documents and Settings\Administrator\.android),如下图所示:

确定后,关闭CMD窗口,重新打开CMD。执行以上命令。将会启用模拟器。

模拟器启动成功后,我们仍在CMD环境中操作。现在进入monkeyrunnershell命令交互模式。

命令:monkeyrunner

进入shell命令交互模式后,首要一件事就是导入monkeyrunner所要使用的模块。直接在shell命令下输入:

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice 回车

OK,这步完成我们就可以利用monkeyrunner进行测试工作了。

这里有两种方案,一是直接在shell命令下输入以下命令;

命令说明

device=MonkeyRunner.waitForConnection() #连接手机设备

device.installPackage("../samples/android-10/ApiDemos/bin/Apidemos.apk") #安装apk包到手机设备。

启动其中的任意activity了,只要传入packageactivity名称即可。命令如下:
device.startActivity(component="com.example.android.apis/com.example.android.apis.ApiDemos")
此时模拟器会自动打开ApiDemos这个应用程序的主页。

device.reboot() #手机设备重启

device.touch(300,300,'DOWN_AND_UP')

MonkeyRunner.alert("hello")#emulator上会弹出消息提示

device.press('KEYCODE_HOME',MonkeyDevice.DOWN_AND_UP)

device.type('hello')#向编辑区域输入文本'hello'

二是将以下命令写到python文件里,例如test.py,然后我们再从命令行直接通过monkeyrunner运行它即可。比如,我们还是用上面的例子,语法如下:monkeyrunner test.py 接下来monkeyrunner会自动调用test.py,并执行其中的语句,相当方便。

实例:test.py

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice  
device=MonkeyRunner.waitForConnection()  
device.startActivity(component="your.www.com/your.www.com.TestActivity")  

在CMD中执行

monkeyrunner test.py

可能出现错误“Can't open specified script file”,如下图所示:

原因在于python脚本文件路径不正确。你可以有以下解决办法:

1、将test.py文件存放到monkeyrunner文件同一目录中。可以执行:monkeyrunner test.py 调用

2、指定python文件位置。如果test.py文件在D盘根目录下,可以这样执行:monkeyrunner d:\test.py

重要大点:

环境变量

变量名:ANDROID_SDK_HOME
变量值:C:\Documents and Settings\Administrator

变量名:Path
变量值:%SystemRoot%\system32;%SystemRoot%;C:\Python27;C:\py;D:\android\android-sdk-windows\tools;D:\android\android-sdk-windows\platform-tools


android
自动化测试框架:CTSmonkeymonkeyrunnerbenchmarkrobot

monkeyrunner

monkeyrunner工具提供了一个API,运用该API编写的程序可以不用通过android代码来直接控制android设备和模拟器,我们可以写一个python程序对android应用程序或测试包进行安装、运行、发送模拟击键,对用户界面进行截图并将截图存储在workstation上等操作。monkeyrunner工具的主要设计目的是用于测试application/framework层上的应用程序和设备、或用于运行单元测试套件,也可以用于其它目的。

monkey工具,是直接运行在设备或模拟器的adb shell中,生成用户或系统的伪随机事件流。

monkeyrunnerandroid测试提供了以下独特的功能:
1、多设备控制:monkeyrunner API可以跨多个设备或模拟器实施测试套件。可以在同一时间接上所有设备或一次启动全部模拟器,依据程序依次连接到每一个,然后运行一个或多个测试。也可以用程序启动一个配置好的模拟器,运行一个或多个测试,然后关闭模拟器。
2、功能测试:monkeyrunner可以为一个应用自动贯彻一次功能测试。您提供按键或触摸事件的输入数值,然后观察输出结果的截屏。
4、回归测试:monkeyrunner可以运行某个应用,并将其结果截屏与既定已知正确的结果截屏相比较,以此测试应用的稳定性。
4、可扩展的自动化:由于monkeyrunner是一个API工具包,我们可以开发基于python模块和程式的一整套系统,以此来控制android设备。除了使用monkeyrunner API,我们还可以使用标准的python osubprocess模块来调用android debug bridge这样的android工具。如ADB这样的android工具,也可以将自己写的类添加到monkeyrunner API中。

运行monkeyrunner

可以直接使用一个代码文件运行monkeyrunner,抑或在交互式对话中输入monkeyrunner语句。不论使用哪种方式,你都需要调用SDK目录的tools子目录下的monkeyrunner命令。如果提供一个文件名作为运行参数,则monkeyrunner将视文件内容为python程序,并加以运行;否则,它将提供一个交互对话环境。

monkeyrunner命令语法

monkeyrunner -plugin <plugin_jar> <programe_filename> <programe_option>

monkeyrunner API

主要包括三个模块
1MonkeyRunner:这个类提供了用于连接monkeyrunner和设备或模拟器的方法,它还提供了用于创建用户界面显示提供了方法。
2MonkeyDevice:代表一个设备或模拟器。这个类为安装和卸载包、开启Activity、发送按键和触摸事件、运行测试包等提供了方法。
3MonkeyImage:这个类提供了捕捉屏幕的方法。这个类为截图、将位图转换成各种格式、对比两个MonkeyImage对象、将image保存到文件等提供了方法。

注意:在运行monkeyrunner之前必须先运行相应的模拟器,否则monkeyrunner无法连接到设备
运行模拟器有两种方法:1、通过eclipse中执行模拟器 2、在CMD中通过命令调用模拟器

这里介绍通过命令,在CMD中执行模拟器的方法

命令:emulator -avd test
上面命令中test是指模拟器的名称。

导入需要的模块

import sys
from com.android.monkeyrunner import MonkeyRunner as mr
from com.android.monkeyrunner import MonkeyDevice as md
from com.android.monkeyrunner import MonkeyImage as mi

如果给导入的模块起了别名,就应该使用别名,而不能使用原名,否则会出现错误。
比如连接设备或模拟器,起了以上别名后,命令应该如下:
device=mr.waitForConnection() 

也可以采用以下方式
from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

也可以采用这种方式
import com.android.monkeyrunner
但是在使用时,就显得特别麻烦
device=com.android.monkeyrunner.MonkeyRunner.waitForConnection() 
我们也可以给它一个别名
import com.android.monkeyrunner as cam
但是在使用时,就显得特别麻烦
device=cam.MonkeyRunner.waitForConnection()

#
等待连接到设备,与模拟器连接,返回monkeydevice对象,代表连接的设备。没有报错的话说明连接成功。
参数1:超时时间,单位秒,浮点数。默认是无限期地等待。
参数2:串deviceid,指定的设备名称。默认为当前设备(手机优先,比如手机通过USB线连接到PC、其次为模拟器)。
默认连接:device=MonkeyRunner.waitForConnection()
参数连接:device = mr.waitForConnection(1.0,'emulator-5554')

向设备或模拟器安装要测试的APK

device.installPackage('myproject/bin/MyApplication.apk') #参数是相对或绝对APK路径
路径级别用“/”,不能用“\”,比如d:\www\a.apk,而应该写成d:/www/a.apk
安装成功返回true,此时查看模拟器我们可以在IDLE界面上看到安装的APK的图标了。


从设备中删除指定的软件包,包括其相关的数据和调整缓存

device.removePackage('myproject/bin/MyApplication.apk')
删除成功返回true


#启动任意的Activity

device.startActivity(component="your.www.com/your.www.com.TestActivity")
或者
device.startActivity(component="your.www.com/.TestActivity")

此时可以向模拟器发送如按键、滚动、截图、存储等操作了。


执行一个adb shell命令,并返回结果,如果有的话
device.shell("...")

暂停目前正在运行的程序指定的秒数
MonkeyRunner.sleep(秒数,浮点数)

获取设备的屏蔽缓冲区,产生了整个显示器的屏蔽捕获。(截图)
result=device.takeSnapshot()
返回一个MonkeyImage对象(点阵图包装),我们可以用以下命令将图保存到文件
result.writeToFile('takeSnapshot\\result1.png','png')

写文件MonkeyImage

MonkeyImage.writeToFile(参数1:输出文件名,也可以包括路径,参数2:目标格式)
写成功返回true,否则返回false


键盘上的类型指定的字符串,这相当于要求每个字符串中的字符按(键码,DOWN_AND_UP.
字符串发送到键盘
device.type('字符串')

唤醒设备屏幕(在设备屏幕上唤醒)

device.wake()

重新引导到指定的引导程序指定的设备

device.reboot()
=========================================================

在指定位置发送触摸事件(x,y的单位为像素)

device.touch(x,y,TouchPressType-触摸事件类型)

发送到指定键的一个关键事件

device.press(参数1:键码,参数2:触摸事件类型)
参数1:见android.view.KeyEvent
参数2,如有TouchPressType()返回的类型-触摸事件类型,有三种。
1DOWN 发送一个DOWN事件。指定DOWN事件类型发送到设备,对应的按一个键或触摸屏幕上。
2UP 发送一个UP事件。指定UP事件类型发送到设备,对应释放一个键或从屏幕上抬起。
3DOWN_AND_UP 发送一个DOWN事件,然后一个UP事件。对应于输入键或点击屏幕。
以上三种事件做为press()touch()参数。原英文如下:
use this with the type argument of press() or touch() to send a down event.


为了模拟输入键,发送DOWN_AND_UP


参数1的部分具体内容逻辑:

按下HOME device.press('KEYCODE_HOME',MonkeyDevice.DOWN_AND_UP) 
按下BACK device.press('KEYCODE_BACK',MonkeyDevice.DOWN_AND_UP) 
按下下导航键 device.press('KEYCODE_DPAD_DOWN',MonkeyDevice.DOWN_AND_UP) 
按下上导航键 device.press('KEYCODE_DPAD_UP',MonkeyDevice.DOWN_AND_UP) 
按下OK device.press('KEYCODE_DPAD_CENTER',MonkeyDevice.DOWN_AND_UP)


device.press('KEYCODE_ENTER',MonkeyDevice.DOWN_AND_UP)#
输入回车
device.press('KEYCODE_BACK',MonkeyDevice.DOWN_AND_UP)#点击返回

home KEYCODE_HOME 
back
KEYCODE_BACK 
send
KEYCODE_CALL 
end
KEYCODE_ENDCALL 
上导航键 KEYCODE_DPAD_UP 
下导航键 KEYCODE_DPAD_DOWN 
左导航 KEYCODE_DPAD_LEFT 
右导航键 KEYCODE_DPAD_RIGHT  
ok
KEYCODE_DPAD_CENTER 
上音量键 KEYCODE_VOLUME_UP  
下音量键 KEYCODE_VOLUME_DOWN 
power
KEYCODE_POWER 
camera
KEYCODE_CAMERA 
menu
KEYCODE_MENU 

                                                            Com from .int

参数中,包含默认值的参数,为可选参数

 

MonkeyRunner.alert(string message, string title, string okTitle)

在脚本运行过程中,PC端弹出敬告对话框.脚本暂停运行,直至关闭对话框.

参数:

        message: 弹出对话框内容

        title: 对话框的标题栏显示内容,默认值为"Alert"

        okTitle : 对话框的按钮,默认值为"OK"

返回值:

        不返回任何值.

例子:

        MonkeyRunner.alert('Message','tip','sure')

        

实际应用:

可以使用在脚本运行之前,判断手机设备连接等.

 


 

MonkeyRunner.Chice(string message, iterable choices, string title)

在脚本运行过程中,PC端弹出对话框,对话框中包含选择列表.脚本暂停运行,直至关闭对话框.

参数:

message: 弹出对话框显示内容

choices: 选择列表数组

title: 对话框标题内容.默认为"Input"

返回值:

如果用户选择并点击确认按钮,返回0-数组最大值.

如果用户关闭了对话框,返回值为-1.

例子:

MonkeyRunner.choice('message',['choice1','choice2','choice3'],'title')

实际应用:

可以在脚本运行之前,选择需要运行的脚本.

 


MonkeyRunner.help(string format)

打印出MonkeyRunner的帮助文档.

参数: 

format: 可以输入"text"或者"html"进行输出

返回值

没有

不知道为什么这个参数我是从来没有成功过


MonkeyRunner.input(string message, string initialValue, string title, string okTitle, string cancelTitle)

在脚本运行中,PC端弹出可输入对话框.脚本暂停运行,直至对话框关闭

参数:

message: 对话框显示信息

initiaValue: 文本框显示文本.默认为空

title: 对话框标题内容.默认为"Input"

okTitle: 确认按钮的文本显示.默认为"OK"

cancelTitle: 取消按钮的文本显示.默认为"Cancel"

返回值:

如果用户点击确认按钮,将文本框的值返回

如果用户点击取消按钮,将返回一个空的String

例子:

MonkeyRunner.input('message','please input','title','ok','cancel')

实际应用:

用例执行之前,输入测试存放文件夹名称.

在脚本运行时,可以灵活输入文本,进行测试,不过感觉意义不大

 


 

MonkeyRunner.sleep(float seconds)

脚本暂停运行指定的时间,单位以秒计算.

参数: 

seconds: 暂停的时间.

例子:

MonkeyRunner.sleep(1.5)

实际应用:

太多了


 

MonkeyRunner.waitForConnection(float timeout, string deviceId)

尝试对android设备或模拟器通过monkeyrunner进行连接

参数:

 timeout: 等待超时时间,默认值为永久等待.

deviceId: 通过设备ID去设别手机或模拟器.如果只有一台手机的时候,不需要输入.

deviceId可以通过adb devices来获得

返回值:

连接成功后,建立一个MonkeyDevice.用来控制手机或模拟器.

例子:

device = MonkeyRunner.waitForConnection(1.5,'181fa9b2')

实际应用:

每个脚本必备,没啥可说的

deviceId可以用于多设备选择.adb devices


MonkeyRunner源码

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.  
// Jad home page: http://kpdus.tripod.com/jad.html  
// Decompiler options: packimports(3) fieldsfirst ansi space   
// Source File Name:   MonkeyRunner.java  
package com.android.monkeyrunner;  
import com.android.chimpchat.ChimpChat;  
import com.android.chimpchat.core.ChimpImageBase;  
import com.google.common.base.Functions;  
import com.google.common.base.Preconditions;  
import com.google.common.collect.Collections2;  
import java.util.Collection;  
import java.util.logging.Level;  
import java.util.logging.Logger;  
import javax.swing.JOptionPane;  
import org.python.core.*;  
// Referenced classes of package com.android.monkeyrunner:  
//          MonkeyDevice, MonkeyImage, JythonUtils, MonkeyRunnerHelp  
public class MonkeyRunner extends PyObject  
    implements ClassDictInit  
{  
    private static final Logger LOG = Logger.getLogger(com/android/monkeyrunner/MonkeyRunner.getCanonicalName());  
    private static ChimpChat chimpchat;  
    public MonkeyRunner()  
    {  
    }  
    public static void classDictInit(PyObject dict)  
    {  
        JythonUtils.convertDocAnnotationsForClass(com/android/monkeyrunner/MonkeyRunner, dict);  
    }  
    static void setChimpChat(ChimpChat chimp)  
    {  
        chimpchat = chimp;  
    }  
    public static MonkeyDevice waitForConnection(PyObject args[], String kws[])  
    {  
        ArgParser ap = JythonUtils.createArgParser(args, kws);  
        Preconditions.checkNotNull(ap);  
        long timeoutMs;  
        try  
        {  
            double timeoutInSecs = JythonUtils.getFloat(ap, 0);  
            timeoutMs = (long)(timeoutInSecs * 1000D);  
        }  
        catch (PyException e)  
        {  
            timeoutMs = 0x7fffffffffffffffL;  
        }  
        com.android.chimpchat.core.IChimpDevice device = chimpchat.waitForConnection(timeoutMs, ap.getString(1, ".*"));  
        MonkeyDevice chimpDevice = new MonkeyDevice(device);  
        return chimpDevice;  
    }  
    public static void sleep(PyObject args[], String kws[])  
    {  
        ArgParser ap = JythonUtils.createArgParser(args, kws);  
        Preconditions.checkNotNull(ap);  
        double seconds = JythonUtils.getFloat(ap, 0);  
        long ms = (long)(seconds * 1000D);  
        try  
        {  
            Thread.sleep(ms);  
        }  
        catch (InterruptedException e)  
        {  
            LOG.log(Level.SEVERE, "Error sleeping", e);  
        }  
    }  
    public static String help(PyObject args[], String kws[])  
    {  
        ArgParser ap = JythonUtils.createArgParser(args, kws);  
        Preconditions.checkNotNull(ap);  
        String format = ap.getString(0, "text");  
        return MonkeyRunnerHelp.helpString(format);  
    }  
    public static void alert(PyObject args[], String kws[])  
    {  
        ArgParser ap = JythonUtils.createArgParser(args, kws);  
        Preconditions.checkNotNull(ap);  
        String message = ap.getString(0);  
        String title = ap.getString(1, "Alert");  
        String buttonTitle = ap.getString(2, "OK");  
        alert(message, title, buttonTitle);  
    }  
    public static String input(PyObject args[], String kws[])  
    {  
        ArgParser ap = JythonUtils.createArgParser(args, kws);  
        Preconditions.checkNotNull(ap);  
        String message = ap.getString(0);  
        String initialValue = ap.getString(1, "");  
        String title = ap.getString(2, "Input");  
        return input(message, initialValue, title);  
    }  
    public static int choice(PyObject args[], String kws[])  
    {  
        ArgParser ap = JythonUtils.createArgParser(args, kws);  
        Preconditions.checkNotNull(ap);  
        String message = ap.getString(0);  
        Collection choices = Collections2.transform(JythonUtils.getList(ap, 1), Functions.toStringFunction());  
        String title = ap.getString(2, "Input");  
        return choice(message, title, choices);  
    }  
    public static MonkeyImage loadImageFromFile(PyObject args[], String kws[])  
    {  
        ArgParser ap = JythonUtils.createArgParser(args, kws);  
        Preconditions.checkNotNull(ap);  
        String path = ap.getString(0);  
        com.android.chimpchat.core.IChimpImage image = ChimpImageBase.loadImageFromFile(path);  
        return new MonkeyImage(image);  
    }  
    public static void alert(String message, String title, String okTitle)  
    {  
        Object options[] = {  
            okTitle  
        };  
        JOptionPane.showOptionDialog(null, message, title, -1, 1, null, options, options[0]);  
    }  
    public static int choice(String message, String title, Collection choices)  
    {  
        Object possibleValues[] = choices.toArray();  
        Object selectedValue = JOptionPane.showInputDialog(null, message, title, 3, null, possibleValues, possibleValues[0]);  
        for (int x = 0; x < possibleValues.length; x++)  
            if (possibleValues[x].equals(selectedValue))  
                return x;  
        return -1;  
    }  
    public static String input(String message, String initialValue, String title)  
    {  
        return (String)JOptionPane.showInputDialog(null, message, title, 3, null, null, initialValue);  
    }  
}  

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

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

相关文章

使用ElementUI结合Vue完善主页的导航菜单和书籍管理以及后台数据分页查询

目录 动态树 数据表 案列 书籍管理 动态树 动态树&#xff08;Dynamic tree&#xff09;是一种数据结构&#xff0c;它可以在树中动态地插入、删除和修改节点。与静态树不同&#xff0c;静态树的节点是固定的&#xff0c;一旦构建完成就无法再进行修改。而动态树可以在运行时…

中间件 - 分布式协调服务Zookeeper

目录 一. 前言 二. 树状结构 2.1. ZNode 2.1.1. stat 2.1.2. ACL 三. NameService命名服务 四. Configuration 配置管理 五. GroupMembers 集群管理 六. 集群三个角色及状态 七. 选举算法 八. Watcher 九. 设计目的 十. 典型使用场景 一. 前言 Zookeeper是一个分布…

Learn Prompt- Midjourney案例:Logo设计

Logo设计是一个充满挑战的任务&#xff0c;因为Logo是品牌重要价值的浓缩。 快速开始​ 直接使用logo design for...来获取灵感。 备注 图像中生成文字在Midjourney中的效果还不是很好&#xff0c;但你可以用Canva编辑图片并替换自己的文字。 在提示中使用那些擅长你所寻找的…

02-Zookeeper实战

上一篇&#xff1a;01-Zookeeper特性与节点数据类型详解 1. zookeeper安装 Step1&#xff1a; 配置JAVA环境&#xff0c;检验环境&#xff1a; java -versionStep2: 下载解压 zookeeper wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeepe…

大数据安全 | 【实验】仿射加密

文章目录 &#x1f4da;实验目的&#x1f4da;关于仿射加密&#x1f525;使用暴力破解的方式对仿射加密进行破解&#xff0c;还原明文&#x1f525;使用词频统计的方式对仿射加密进行破解&#xff0c;还原明文&#x1f525;在同一运行环境下&#xff0c;对比两种破解方式所需的…

LLM之Colossal-LLaMA-2:Colossal-LLaMA-2的简介、安装、使用方法之详细攻略

LLM之Colossal-LLaMA-2&#xff1a;Colossal-LLaMA-2的简介、安装、使用方法之详细攻略 导读&#xff1a;2023年9月25日&#xff0c;Colossal-AI团队推出了开源模型Colossal-LLaMA-2-7B-base。Colossal-LLaMA-2项目的技术细节&#xff0c;主要核心要点总结如下: >> 数据处…

融合之力:数字孪生、人工智能和数据分析的创新驱动

数字孪生、人工智能&#xff08;AI&#xff09;和数据分析是当今科技领域中的三个重要概念&#xff0c;它们之间存在着紧密的关联和互动&#xff0c;共同推动了许多领域的创新和发展。 一、概念 数字孪生是一种数字化的模拟技术&#xff0c;它通过复制现实世界中的物理实体、…

应用在手机触摸屏中的电容式触摸芯片

触控屏&#xff08;Touch panel&#xff09;又称为触控面板&#xff0c;是个可接收触头等输入讯号的感应式液晶显示装置&#xff0c;当接触了屏幕上的图形按钮时&#xff0c;屏幕上的触觉反馈系统可根据预先编程的程式驱动各种连结装置&#xff0c;可用以取代机械式的按钮面板&…

数据库存储引擎和数据类型详细介绍

目录 一、数据库存储引擎&#xff08;了解&#xff09;1.了解MySQL体系结构2.存储引擎&#xff08;了解&#xff09;2.1.存储引擎的介绍2.2.存储引擎分类2.3.如何选择引擎&#xff1f; 3.事务控制语言(TCL)事务的四个特性(ACID) 二、数据类型&#xff08;了解&#xff09;1.整型…

【文献】TOF标定 Time-of-Flight Sensor Calibration for a Color and Depth Camera Pair

文章目录 Article info.Introduction处理TOF误差Take home messagesResourcesIDEAS Article info. Time-of-Flight Sensor Calibration for a Color and Depth Camera Pair IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 37, NO. 7, JULY 2015 Intr…

(一)连续随机量的生成-加权重采样

加权重采样 import numpy as np import matplotlib.pyplot as plt# Step 1: Generate 10,000 random theta values from U([0, 1]) n 10000 theta_values np.random.rand(n)# Define the function to compute weights for a given theta def compute_weight(theta):return (…

SQLAlchemy列参数的使用和query函数的使用

目录 Column常用参数 代码演示 代码刨析 query函数的使用 基本用法 常见用法示例 查询所有记录 根据条件查询 查询第一条符合条件的记录 查询特定列的值 添加排序规则 使用聚合函数 连接查询 使用filter_by Column常用参数 primary_key&#xff1a;True设置某个字…

当蛋白质成为儿童的敌人:应对蛋白过敏的挑战

儿童时期是充满欢笑和探索的时光&#xff0c;但对某些孩子来说&#xff0c;它可能伴随着一项不太受欢迎的挑战——蛋白过敏。在这篇文章中&#xff0c;我们将探讨蛋白过敏的现象、挑战以及如何在这个过程中为孩子提供支持。 蛋白质过敏&#xff1a;小儿的无情敌人 蛋白质过敏…

flink的序列化基准测试

背景&#xff1a; flink提供了在本地环境使用jmh测试不同序列化方法的性能差异&#xff0c;本文就是基于这个https://github.com/apache/flink-benchmarks这个性能测试&#xff0c;总结几个结论&#xff0c;以便后面使用时避免掉坑 基准测试 我们本次运行的是SerializationF…

2023 年解锁网络安全即服务

在当今快速发展的数字世界中&#xff0c;强大的网络安全机制的重要性怎么强调都不为过。对于越来越多地发现自己成为网络威胁焦点的小型企业来说尤其如此。 那么&#xff0c;“网络安全即服务”到底是什么&#xff1f;为什么它对小型企业至关重要&#xff1f; 网络安全即服务…

【RocketMQ】(八)Rebalance负载均衡

消费者负载均衡&#xff0c;是指为消费组下的每个消费者分配订阅主题下的消费队列&#xff0c;分配了消费队列消费者就可以知道去消费哪个消费队列上面的消息&#xff0c;这里针对集群模式&#xff0c;因为广播模式&#xff0c;所有的消息队列可以被消费组下的每个消费者消费不…

服务断路器_服务雪崩解决方案之服务限流

服务熔断和服务隔离都属于出错后的容错处理机制&#xff0c;而限流模式则可以称为预防模式。 限流模式主要是提前对各个类型的请求设置最高的QPS阈值&#xff0c;若高于设置的阈值则对该请求直接返回&#xff0c;不再调用后续资源。 注意&#xff1a; 限流的目的是通过对并发访…

【SQL server】数据库入门基本操作教学

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 前言 数据库是计算机系统中用于存储和管理数据的一种软件系统。它通常由一个或多个数据集合、管理系统和应用程序组成&#xff0c;被广泛应用于企业、政府和个人等各种领域。目前常用的数…

点击、拖拉拽,BI系统让业务掌握数据分析主动权

在今天的商业环境中&#xff0c;数据分析已经成为企业获取竞争优势的关键因素之一。然而&#xff0c;许多企业在面对复杂的数据分析工具时&#xff0c;却常常感到困扰。这些工具往往需要专业的技术人员操作&#xff0c;而且界面复杂&#xff0c;难以理解和使用。对业务人员来说…

java: 通过xml模板转成word文件

依赖: freemarker <dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version> <!-- 请根据您的需求选择最新版本 --></dependency> 代码展示 import freemarker.t…