总结:
1、配置
Java环境变量时需要注意设置的路径需要和JDK安装的路径一样
2、配置Java环境变量时需要注意JDK的版本号
3、配置环境变量时多个变量以分号隔开,但是确保是英文输入法的分号
1、检测负载机是否可以被调用,检测负载机的ip是否能被ping通
2、当负载机的ip不能ping通时,有可能是防火墙拦截了,可以检测防火墙是否是启用状态,如果是暂时设置禁用防火墙
3、测试的数据调用文件应该放在负载机上,并且在控制中心设置正确的数据访问路径
Jmeter测试工具安装步骤:
1、安装Jmeter
下载Jmeter工具包 并把工具包放到C盘下
http://jmeter.apache.org/download_jmeter.cgi
2、安装JDK
下载Java的JDK并安装,一般会安装在C:\Program Files\Java目录下
http://java.sun.com/javase/downloads/index.jsp
3、Java环境变量配置
桌面上 右键选中计算机--->属性--->高级系统设置--->环境变量设置
在“系统变量”--->“新建”, 在变量名中输入:CLASSPATH,变量值中输入:C:\Program Files\Java\jdk1.6.0_10\lib\dt.JAR; C:\Program Files\Java\jdk1.6.0_10\lib\TOOLS.JAR; C:\Program Files\Java\jdk1.6.0_10\BIN;再按“新建”,在变量名中输入:JAVA_HOME,变量中输入:C:\Program Files\Java\jdk1.6.0_10;修改PATH变量,添加%JAVA_HOME%/bin;然后确定即可
4、Jmeter环境变量配置
桌面上 右键选中计算机--->属性--->高级系统设置--->环境变量设置
在“系统变量”--->“新建”, 在变量名中输入:JMETER_HOME,变量值中输入:C:\jakarta-jmeter-2.3.4 ,再修改CLASSPATH变量,变量值中添加%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;% JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-1.2.jar; 然后确定即可
通常
Java有三种编译方式,编译方式不同,那么得到的.class的大小也不同。
1)默认编译方式:javac A.java
2) 调试编译方式:javac -g A.java
3) 代码编译方式:javac -g:none A.java
案例如下:类A
public class A{ public static void main(String args[]){ for(int i=0;i<100000;i++){ A a = new A(); } } } |
通过上面这三种编译方式,得到的.class文件大小分别为:
默认编译方式:322字节
调试编译方式:453字节
代码编译方式:238字节
三种编译方式对应的.class文件的内容,分别如下:
默认编译方式:代码(Code)、源文件信息(SourceFile Infomation)、代码行序列表(LineNumberTable)。
调试编译方式:代码(Code)、源文件信息(SourceFile Infomation)、代码行序列表(LineNumberTable)、本地变量表(LocalVariableTable)。
代码编译方式:代码(Code)。
由于javac -g:none A.java这种方式编译的内容最少,所以.class占用的空间也就最小。
由于javac -g A.java这种方式编译的内容最多,所以.class占用的空间也就最大。
而javac A.java这种方式编译的内容居中,所以.class占用的空间也就居中。
使用selenium 的python包,然后实现了简单的自动登录和查看所需的页面。
脚本写起来很简单,需要会使用浏览器的debug功能,分析下页面结构。这个例子只是简单参考,应该无法运行,因为是内部系统。。
# -*- coding: utf-8 -*- #get_info_of_working.py python2.7.x #orangleliu@gmail.com 2014-04-24 ''''' |
用来自动打开查询工时的界面 直接看到自己最近的打卡情况
''' from selenium import webdriver from selenium.webdriver.common.keys import Keys def login_system(driver): ''''' |
登陆到考勤管理系统
''' login_url = 'http://att.xx.com/' username = 'zhizhi.liu' password = '1234' driver.get(login_url) driver.find_element_by_id("username").clear() driver.find_element_by_id("username").send_keys(username) driver.find_element_by_id("password").clear() driver.find_element_by_id("password").send_keys(password) driver.find_elements_by_tag_name("form")[0].submit() driver.get('http://att.xx.com/TRecordList.action') if __name__ == "__main__": driver = webdriver.Firefox() login_system(driver) |
安装前准备 需要下载xampp 与 testlink
一、 安装前准备
本安装手册所有安装步骤都基于WINDOWS操作系统;我使用的Windows7系统
二、 安装XMAPP
当前下载版本:xampp-win32-1.7.4-VC6-installer.exe, 下载地址:http://www.apachefriends.org/zh_cn/xampp-windows.html
1. 点击 安装包,进行安装XAMPP;
2. 在弹出的对话框中选取安装路径;
3. 安装完毕后,进入安装路径找到”xampp”文件夹;首先点击xampp_start图标;待对话框加载完毕后;点击”xampp-control”图标;
注:如果apache与MYSQL启动不成功,可能是80端口与3306端口被占用;
解决方法一:将暂用此端口的进程关闭
1.打开运行-》输入CMD 进入命令行模式
2.在命令行模式中输入netstat -a -n -o
3.查看0.0.0.0:80所对应的PID(即进程号)
4.按CTRL+SHIFT+ESC键打开WINDOWS任务管理器,选择进程标签,然后在菜单栏的查看-》选择列里勾上PID(进程标识符),根据第三部所查到的PID的进程,KILL掉该进程,再重新安装APACHE即可
还有你修改了, apache/conf/httpd listen12.34.56.78:80 改成(其他)例如8080的话,那么在浏览器里访问就要加,不能是localhost:8080
**使用说明:
** netstat -ano 查看端口使用情况
**或者 netstat -ano|findstr 80
**C:\Documents and Settings\cjx>netstat -ano|findstr 80
安装时请注意,选择要安装的服务,默认不安装;
4. 为MYSQL设置密码;打开IE浏览器;输入http://127.0.0.1/xampp;进入页面,选择中文;
进入XAMPP配置页面;选择【安全】列表,在点击右侧链接;
输入MYSQL SuperUser密码,输入成功后,点击【改变密码】按钮;
注:记录密码的保密属性是cookie还是。。。
三、 配置testlink
TL-1.9,下载你需要用的TestLink版本,写该文档的时候,TestLink的版本是1.9.2,下载地址:http://sourceforge.net/projects/testlink/files/TestLink%201.9/TestLink%201.9.3/
在windows下,发现该文档的打包方式是Linux下的方式Testlink1.9.2.tar.gz,用Winzip工具解压两次,就可以看到Testlink1.9.2.tar.gz--->Testlink1.9.2.tar--->TestLink1.9.2
1、 将”testlink”文件夹复制到”\xampp\htdocs\”目录下;
注意: 将后面的版本号去掉,TestLink---1.9.2变成TestLink
2、 打开IE浏览器,输入:http://IP地址:端口号/testlink(如:http://localhost:80/testlink); 在页面中点击“new installation”;
进入配置页面,配置参数如下图:
上述参数配置好后,点击页面中【Process Tesklink Setup】按钮;
在此页面中,选中复选框后,点击【Proceed】按钮;
当出现以下页面提示时,表示配置成功;
3、 进入“\xampp\htdocs\testlink”目录下,把install目录删除;
4、 汉化过程:将String.txt拷贝到” \xampp\htdocs\testlink\locale\zh_CN”目录下,替换原有的String.txt文件;
5、 再次登录:http://IP地址/testlink; 默认用户名:admin密码:admin
到此处所有testlink配置工作已经完成,接下来可以使用;
我常常在会议上听测试行业内部的人说:“现在啊,刚毕业的大学生都不具备我们所需要的技能……”这话没错,可我倒是有一个提议可以稍微缓解一下这个实际上很简单的问题。简单来说就是,为什么不帮这些大学生一把,或者接受当地的学术界专家教授呢?
一个大学和企业都不得不面对的难题就是预算限制(尤其在现今的经济状况之下)。就像许多企业已经大大减少了他们的可支配支出,不少大学也是,或许大学减少的还要多些。众所周知,专业会议的价格是相当昂贵的,你的专业领域的专业培训课程也是。现在,在计算机科学和其他信息技术相关的领域里,我们需要了解的知识主体是处于不断变化中的,而且很快就会过时。
现在所用的技术――硬件和软件,在我们许多专家还在研究生院时都没发明出来。所以,我们现在课上所教的基本都是我们自学的。如果那时够幸运的话,我们或许能够参加培训班去学习我们现在所教授的内容。但更可能的是我们不得不自学。
所以,努力工作的员工怎样才能得到他们所需要的培训,将来成为软件测试/软件工程的专家呢?——通过正式或非正式地让企业和大学建立更多的合作关系。
非正式联盟
企业花费大量经费来培养他们的员工,花钱让他们获得正规的大学教育,派他们参加相关会议和专业发展研讨会。许多这类研讨会大多是在线的,要么请了咨询顾问来上培训课要么由公司自己内部的员工举办。通常顾问讲师是按学员个数来要价,但也有时按一定范围的人数要价,比如:20到25人一个固定价。但愿这是我最后一次这么说了。下次你们邀请当地教授免费来帮你们上在线培训课,怎么样?
怎样才能更好的确保你们所招顾问讲师所教的东西就是你们希望你们将来的员工能学会的?这得花费多少经费?另一套培训资料和一顿午餐吗?或者如果他们确实是按每个人来收费,那这样,你还要额外花这么多钱去培养一个专家还值不值得?或许吧......
正式联盟
建立一个更加正式的联盟是另一个的选择,它或许对参与其中的每个人都更具价值。这种正式联盟有多种形式,包括:提供资金让学校教授去参与测试会议或课程;让公司员工在大学里做讲座嘉宾;提供机会让教职员工和学生来公司参观;让学校的教职员工来公司工作一段时间。给学校的教授们提供可以在课上用得着的材料和例子也是极具价值的。
我的一个难题是:找出对学生既有意义又有挑战的现实生活中的实例与练习。你们可以把任何有关你们公司行业机密的东西留着,只提供可以融入课堂的知识。
许多公司已经制定了正式的教授计划,如:设立一个持续几个月或者几年的客座教授的职位。我很幸运,在几年前的一个夏天加入了这样一个联盟,作为一个大企业的学院合作计划的一部分,我在他们的一个重要的软件测试实验室工作了五个礼拜。那次经历是相当珍贵的。在学校和企业都受益的同时,我计划着在学校开一门新的软件测试的课程。
作为开新课的一部分准备,我想学习当前的实例并熟悉一些现在大家使用的自动化测试工具;我想了解成为一名全职测试员是怎样的:测试员会面对哪些挑战?他们用哪些自动化工具?这些工具的优劣点是什么?成为一位测试队伍的项目经理又是怎样的?我想知道企业是如何在软件测试的业务流程中整合工具的;我想加强我们学校和测试企业的合作关系。
我也可以看书来了解这些,但是我想知道更多,想提高我对这方面的理解,想把这些知识带到课堂。公司企业的目标是从长远角度积极影响招聘员工。更明确地来说,他们在向我们展示他们为其公司内部需求和客户需求所设计的测试软件的同时,也想要加强和学校的联系。因为他们以及许多其他公司都为了该如何招到有专业测试背景和把软件测试作为一个职业选择的学生烦恼着。
我被任用了
作为他们院校合作计划的一部分,我有幸能够采访和近距离观察测试员的日常工作,可以和软件测试项目经理探讨问题。
其中一个不错的经历就是我花了几个小时向他们的可用性专家学习了可用性测试。一个意外的收获是:他在他们可用性实验室为我录制了在一个网页上运行可用性测试的过程。我利用录制的内容给学生阐释说明了一个正规的可用性测试的流程。我也参加了几次培训课学习了两家供应商的测试软件。
这次联盟的一个结果是我能够获得我为了开软件测试课程所需要的准备工作。除了我接受的技术培训,我还对现下业务测试行业的难题与挑战有了更好的了解。下个学期,我就开办了软件测试课程。班级的学生有来自商业学院信息系统专业的,还有来自工程学院计算机科学专业的。他们团队合作,我会确保一队中有两名学生是信息系统专业(商业)的,另外两名学生是计算机科学专业(工程)的。这样来自两所学院的学生就不得不合作了。
通过加强和我们学校的合作并且通过让学生更好地了解了测试相关的职业,而公司的招聘成功率随之上升,公司就从中获益。
这样,学生会把软件测试作为一个职业选择。潜在员工变得更适合企业的需求:学生获得暑期实习的机会,毕业后立即成为该公司的正式员工。
我现在有新的合作伙伴了
当我在软件公司时,一位经理联系了自动化软件测试工具的一家供应商的CEO,恳请他们为我校捐赠测试工具。这样子,其中的每一方都能受益:学校可以收到最好的测试工具来用到课上教学;公司可以雇用对自动化测试工具有经验的新人;自动化测试工具的供应商可以把他们的软件送到将来的软件测试决策者们的手上。同时,软件公司开始以我们学校为成功案例和其他高校建立正式项目。
与这家公司合作了差不多一年的时候,他们宣布了新的计划:提供软件和培训材料俩帮助学术机构发展他们的技术课程。
我们学校是第一个参与这个合作计划并收到捐赠的机构。在课上,我使用他们的网页应用测试软件,网页下载测试软件和管理需求、制定测试计、划追踪缺陷的产品。
其他公司也给我们学校捐赠了软件(和硬件),供我们上课使用。它的意义是许多公司都开始十分慷慨地捐赠他们的产品给学校供上课使用了,但也许只有我们提出时他们才会这么做。
挑战
这是一项巨大的任务,但只有我一个人在做着。所以,如果软件公司愿意给一所学校捐赠软件,他们必须有提供额外培训和支持的准备。不然的话,这项计划就会破产。
一所学校里多个不同的学科的人都加入的话,这项计划成功的几率就大些,但这样的机会也不是经常有的。但确实有来自其他学科(如:商业信息系统和计算机科学)的教职员工参与也是很吸引人的一点。
为了成功开设一门软件测试课并把软件与课堂整合得花上不少时间。至少以我自己的例子来说,我除了平常的教学任务就一心一意专门做这个。不必说,我很忙。所以,有什么能大大地提高成功的几率呢?——让企业对与当地教授合作产生兴趣并在大学的release time提供资金。这是什么意思呢?就是说,这个教授一学期教两门课,这笔资金就提供给大学来支付教授教一门课的工资,这样的话,他们就可以少教一门课。
我最需要的就是时间。在一些大学,如果正处于资金短缺时期,那么教学工作量(每学期每个教授要教的课程的数量)就会增加。那样,我们教课比平常要多,就没时间花在软件测试课的事情上了。
但是这样做会耗费企业的经费吗?当然会。但是,为了让你能够招到合格的大学毕业生,做什么事是值得的呢?当雇佣到优秀的员工时,想想公司花在培训上的所有资金吧,那就是答案。
另一个选择就是企业给教授发工资,事实上一付就要长达一年。但或许你更愿意一直不断吸引更换新的教授来上课而不提供资金,这样的话你或许不会像你提供稳定的资金那么成功。
话虽如此,一些教授倒愿意作为客座教授,或许离开校园,在企业公司里工作个一、两年。
一个永久的选择是:建一个由企业提供资金的讲座职位。这个职位或许是比较耗费资金的,但可能是更成功的。在这种情况下,一家公司要长达一年投入大笔资金和精力在这个职位上。
如果你们学校设有硕士、博士学位,那么学校的研究生们就能和公司测试员工一起做项目。反之,这些项目也可以成为他们的硕士、博士论文的实例。
总结:
显然,通过更近一步的合作,测试行业和学术界都可以获益。想要了解你们当地学校的教职员工的更好的方法是什么?让测试行业和学术界结成联盟的更好的方法是什么?帮助你们招到符合要求的学生的更好的方法是什么?——一大批当地学校的教授求任用!
1. Xcode(IOS)
测试时连接到Xcode上,在 console 上面可以时时看到当前的日志。可以便于一些非必现问题的定位。
2. Sqlitespy
数据库地址: app/ Documents/ .db文件
通过Sqlitespy 进行增删改查、构建数据等。
3. iTools
通过此工具可以将iPhone手机上app安装目录下的数据库 及 Log信息等导出。
4. Fiddler
通过设置
手机代理为Fiddler IP 地址,进行相应的抓包测试,抓取Http相关的信息。
通过抓包更改服务器的新版本号来 验证自动更新功能。
通过抓包更改返回数据来验证一些比较难构建的场景。
这是本人自学
Linux所做的笔记,以及实现一些功能作的总结。乐意与各位喜欢linux的朋友交流
学习,共同进步。这篇
文章只是简单介绍一些linux比较常用的或者说是最基础的也是最重要的知识,有些在模块后面标上“重点”的,就是必须熟记的知识了,还有一些关于在linux上进行服务器管理和应用程序开发的总结将在稍后更新。声明一下:本文的命令为排版需要,可能使用了中文字符,若直接复制到linux中可能出错。
Linux 由于性能卓越,开源,安全性和稳定性高,处理多并发,支持多线程,多用户,对内存和文件管理优越等众多优点而被应用的越来越多。反正我感觉是越来越喜欢Linux了。
Linux的最小配置只需要4M内存,因此适合嵌入式开发。
首先介绍Linux的安装,本人用的发行版是Red Hat Enterprise Linux 6,虽然说基本上是下一步,但是linux的分区是必须要掌握或者是要理解的,这也正体现出了它自己独特的文件管理模式,并且,这个与windows是完全不同的。分区原则:
/boot分区:启动分区,100M足矣,一般的范围在32—100M之间,100M左右最好;
Swap分区:又叫交换分区,一般是物理内存的2倍,但不要大于256M;
/ : 即根分区,尽可能大,因此,我们将剩下的硬盘大小全部分给根分区。
一些基础但经常使用的命令:
参看Linux系统分区的具体情况:fdisk –l
查看某个目录是在哪个分区上:df 目录全路径 如:df /boot/
Linux采用级层式的树状目录结构,最上层是根目录,为:“/”
基础常用命令:
关机:shutdown –h now(立刻进行关机)
重启:shutdown –r now
reboot--------也是重启的命令
用户注销:logout
列出当前目录下所有文件:ls 或者使用命令:dir
列出当前目录下所有文件,包含隐藏文件:ls –a
列出当前目录下所有文件的详细信息:ls –l
切换目录:cd
切换到上一级目录:cd .
切换到上上级目录:cd ..
切换到图形化界面:startx
Linux文件夹常识:
因为Linux良好的文件管理系统,以下几个关键或者说是比较重要的文件目录是必须要知道的:
root:存放root用户的相关文件
home:存放普通用户的相关文件
bin:存放普通命令(常用命令)
sbin:存放要具有一定权限才可以使用的命令
mnt:挂载软驱,光驱的目录(默认)
etc:存放配置的相关文件
var:存放经常变化的文件
boot:存放引导相关的文件
usr:默认程序(文件)安装文件夹
显示自己的当前路径:pwd 当自己不知道处在了哪个文件夹路径下时,用这个命令可以方便的看到自己的路径。比较有用的一个命令。
Linux的用户管理:
添加用户: useradd 用户名
设置密码:passwd 用户名 回车之后输入密码,然后确认,如果没错,操作成功。
删除用户:userdel 用户名 userdel –r 用户名 删除该用户及该用户的主目录
在linux中的每个用户必须属于一个组,不能独立于组外
ls –ahl 查看文件的所有组
可通过[chgrp 组名 文件名]修改用户的所在组
如何在Linux中添加组: groupadd 组名
查看linux中所有组信息: cat /etc/group或者是 vi /etc/group
创建用户并同时指定将该用户分配到某个组: useradd -g 组名 用户名
查看Linux中所有用户信息:vi /etc/passwd 或者是: cat /etc/passwd
Linux的运行级别:
直接输入命令:vi /etc/initab
下面说说每个数字表示的意义:
0:关机 1:单用户 2:多用户没有网络服务 3:多用户有网络服务 4.系统未使用保留给用户 5.图形界面 6:系统重启
常用级别是3和5
但别人更改了用户级别为4或其他数字使Linux不能正常启动时,需要用到以下解决方案将Linux进行重新设置:
在开机图形化界面(GRUB引导界面)中输入“e”,然后高亮第2行,再输入“e”,然后是空格和1(即: 1):代表单用户级别,按“b”进行重新启动。解决问题
文件夹管理:
建立目录:mkdir
删除目录:rmdir
删除所有内容:rm –rf
建立符号链接:ln
建立空文件:touch
拷贝命令:cp
移动文件和改文件名:mv
管道命令:| 将一个命令的输出作为另一个命令的输入,即将上一个命令的结果交给管道命令后的命令进行处理
一个最重要的命令:man 任何关于命令问题的问题都能解决的好“男人”,瞬间感觉设计linux的人很有才,其实际上应该是手册的意思。
搜索文件及目录:find
按文件名查找:find / —name a.java 从根目录开始查找名为a.java的文件
重定向命令:ls –l > a.txt 把结果输入到a.txt中 (覆盖以前的内容)
追加信息: >> (在内容后面追加信息)
关于文件权限的问题:(重点)
修改文件的访问权限:chmod 777 文件名
备注:第一个7表示:文件的所有者可以对文件进行读,写,执行等操作;
第二个7表示:文件所在组的其他用户可以对该文件进行读,写,执行等操作;
第三个7表示:其他组用户可以对该文件进行读,写,执行等操作。
如:文件名前面的字符串为“-rw-r--r--”
r :可读,值为4;
w:可写,值为2;
x:可执行,值为1.
因此,将其分为三个字符代替一数,上面的权限字符串的值为“-644”。最前面的横线表示文件的所属类型。
关于Linux在虚拟机的挂载和卸载操作(重点):
首先需要在虚拟机中进行简单的设置:点击设置,然后点击CD/DVD IDE,将device status 下面的两个选项全部勾上,选择您要挂在的镜像文件;如下图示:
挂载的步骤:
a. 查看/dev/中是否有cdrom文件,即可以挂载的目录:
结果为:
存在该目录,退出到根目录,继续下一步;
b. 输入挂载命令,进行挂载:mount /dev/cdrom /mnt
c. 退出到根目录,查看刚才挂载的镜像文件:
d. 挂载成功。可以用镜像文件了。
Shell基础:
常用的三种shell:
No1. Bash,在大陆一般比较流行,指向sh
No2. Csh
No3. Ksh ,在欧洲比较流行
用命令ls —l /bin/*sh可查询以上文件。
查看目前使用的是哪种shell,直接用命令env,该命令可以显示当前操作系统的环境变量
修改shell的命令:chsh —s 输入新的shell 如: chsh —s /bin/csh 将当前的shell设置为csh
前言
SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系
数据库。iOS SDK很早就支持了SQLite,在使用时,只需要加入 libsqlite3.dylib 依赖以及引入 sqlite3.h 头文件即可。但是,原生的SQLite API在使用上相当不友好,在使用时,非常不便。于是,开源社区中就出现了一系列将SQLite API进行封装的库,而FMDB (https://github.com/tryingx/fmdb-master) 则是开源社区中的优秀者。
第一步 引入:sqlite3的类库
第二步 引入:FMDB的类库
主要包括以下几方面
引入文件结束以后就可以使用了,使用很简单
第一步 建立一个数据库类
1 NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; // 获取document文件的路径 2 /** 3 * 强调一点就是对于数据库的名:我们可以用"" 或用 NULL 4 * 5 * An empty string (@""). An empty database is created at a temporary location. This database is deleted with the FMDatabase connection is closed. 6 也就是说如果我们使用(@""),会创建一个临时数据库,当我们数据库关闭后会自动删除 7 NULL. An in-memory database is created. This database will be destroyed with the FMDatabase connection is closed. 8 在内存中给你创建一个数据库 9 */ 10 NSString *dbPath = [docPath stringByAppendingPathComponent:@"student.sqlite"]; 11 NSLog(@"%@", dbPath); // 拼接字符串 12 FMDatabase *dataBase = [FMDatabase databaseWithPath:dbPath]; 13 [dataBase open]; 14 // 用来判断数据库打开是否成功 15 if (![dataBase open]) { 16 NSLog(@"error"); 17 } |
第二步 就是执行一些常用的操作
常用操作:
1.创建一个表
NSString *sql = @"CREATE TABLE student(_id Integer primary key, name text, password text, email text)";
BOOL isCreateTable = [dataBase executeStatements:sql];
NSLog(@"%d", isCreateTable );
2.插入数据
NSString *sqlInsert = @"INSERT INTO student (name, password, email) values ('宝贝', '1232', '3343243')";
BOOL isInsertOK = [dataBase executeStatements:sqlInsert];
NSLog(@"%d", isInsertOK );
3.批量的创建表和插入数据
NSString *sql1 = @"create table bulktest1 (id integer primary key autoincrement, x text);" "create table bulktest2 (id integer primary key autoincrement, y text);" "create table bulktest3 (id integer primary key autoincrement, z text);" "insert into bulktest1 (x) values ('XXX');" "insert into bulktest2 (y) values ('YYY');" "insert into bulktest3 (z) values ('ZZZ');"; [dataBase executeStatements:sql1]; |
当然也可以通过数组的方式插入数据
NSArray *stuentInfo = [NSArray arrayWithObjects:@"大傻瓜",@"213",@"123456@qq.com", nil nil];
[dataBase executeUpdate:@"insert into student (name, password, email) values (?,?,?)" withArgumentsInArray:stuentInfo];
4.匹配的方式插入数据
NSString *sqlInsert = @"INSERT INTO student (name, password, email) values (?,?,?)";
BOOL flag = [dataBase executeUpdate:sqlInsert, @"大宝贝", @"123", @"654321@qq.com"];
NSLog(@"%d", flag);
5.1.查询所有数据
FMResultSet *result = [dataBase executeQuery:@"SELECT * FROM student"];
[self showInfo:result];
[result close];
- (void)showInfo:(FMResultSet *)result { while ([result next]) { int _id = [result intForColumnIndex:0]; NSLog(@"id : %d", _id); NSString *name = [result stringForColumnIndex:1]; NSLog(@"name : %@", name); NSString *password = [result stringForColumnIndex:2]; NSLog(@"password : %@", password); NSString *email = [result stringForColumnIndex:3]; NSLog(@"email : %@", email); } } |
5.2.查询指定信息
NSString *sqlInsert = @"SELECT * from student where name = %@";
FMResultSet *result = [dataBase executeQueryWithFormat:sqlInsert, @"宝贝"];
NSLog(@"%@", result);
[self showInfo:result];
6.执行删除操作
NSString *sql = @"delete from student where name = ?";
[dataBase executeUpdate:sql,@"宝贝"];
执行更新操作的步骤和删除操作一样,只不过sql语句不同而已
重要注意事项是:1 使用完数据库后记得关闭
2 查询结果完场后result也得记得关闭
这是很久以前编写的一个
测试案例,那时是为了检查大量往
Mysql数据库里插入数据,看一下
数据库的性能如何?服务器是否会很快就被写满了。
前期的准备
工作:Mysql 数据库搭建,
LoadRunner,libmysql.dll and 网上搜一份LoadRunner访问mysq的公共库。
Step1:Mysql数据库搭建(这里就不详细讲述如何安装Mysq数据库和创建表了)
IP:192.168.1.100
访问名:root
密码是:123456
数据库名是:t3db
访问端口是:3306
数据库的相关信息就是这样了!
Step2:LoadRunner如何连接mysql呢?
以下全都是在网上找到原代码
int rc; int db_connection; char *server = "192.168.1.100"; // 数据库的ip地址 char *user = "root"; // 数据库访问用户名 char *password = "123456"; // 密码 char *database = "t3db"; // 数据库名称 int port = 3306; // 访问端口 int unix_socket = NULL; int flags = 0; char** result_row; int query_result; char szSql[256]; int MySqlInit() { rc = lr_load_dll("libmysql.dll"); db_connection = mysql_init(NULL); if (db_connection == NULL) { lr_error_message("Insufficient memory"); lr_abort(); } if(rc!=0) { lr_error_message("Load MySql.dll Error!"); lr_abort(); } rc = mysql_real_connect(db_connection,server, user, password, database, port, unix_socket, flags); if(rc == NULL) { lr_error_message("connect mysql error! %s",mysql_error(db_connection)); mysql_close(db_connection); lr_abort(); } return rc; } int MySqlUnit() { // 释放MySQL资源 mysql_close(db_connection); return 0; } int InsertValue(char* query) { rc = mysql_query(db_connection,query); if (rc != 0) { lr_error_message("%s", mysql_error(db_connection)); } query = NULL; return rc; } int MySqlQuery(char* szSql) { rc = mysql_query(db_connection,szSql); if(rc != 0) { lr_error_message("%s",lr_eval_string("?")); lr_error_message("%s", mysql_error(db_connection)); szSql = NULL; return -1; } query_result = mysql_use_result(db_connection); if (query_result == NULL) { lr_error_message("%s", mysql_error(db_connection)); mysql_free_result(query_result); szSql = NULL; return -2; } result_row = (char **)mysql_fetch_row(query_result); if (result_row == NULL) { lr_error_message("Did not expect the result set to be empty"); mysql_free_result(query_result); szSql = NULL; return -3; } mysql_free_result(query_result); szSql = NULL; return 0; } |
这里提供了几个公共函数,看名字大家都明白他们是干啥的。
Step3:Loadrunner里需要怎么编写写呢?
1、添加libmysql.dll到你的工程
2、把公共库添加到你的公共
3、vuser_init
vuser_init() { index = 0; MySqlInit(); // 初始化数据库 return 0; } |
4、vuser_end
vuser_end() { MySqlUnit(); // 反初始化 return 0; } |
5、Action
Action() { int resultValue; char cIndex[10]; char onceAccount[1024]; char insertQuery[22584]; index = index +1; // 组合插入数据库的sql语句 strcpy(insertQuery, "INSERT INTO `t3db`.`role`(GroupID, RoleName, Account, BaseInfo, ExtInfo, LastModify) VALUES('1', '"); strcat(insertQuery, lr_eval_string("{Account}")); strcat(insertQuery, itoa(index, cIndex, 10 )); strcat(insertQuery, "', 'q1031', '111', '111','2013-02-28 20:42:33')"); strcat(insertQuery, ";\0"); lr_start_transaction("Insert"); resultValue = InsertValue(insertQuery); // 调用插入函数 if(resultValue != 0) { lr_end_transaction("Insert",LR_FAIL); } else { lr_end_transaction("Insert",LR_PASS); } sleep(100); return 0; } |
1.在类中方法上加上
synchronized关键字,是对整个对象加锁,当一个线程访问带有synchronized的方法时,其他带有synchronized的方法的访问就都会阻塞。
样例:
public class ThreadTest { public static void main(String[] args) { Stu stu = new Stu(); StuThread1 t1 = new StuThread1(stu); t1.start(); StuThread2 t2 = new StuThread2(stu); t2.start(); } } class StuThread1 extends Thread { Stu stu; public StuThread1(Stu stu) { this.stu = stu; } public void run() { stu.read1(); } } class StuThread2 extends Thread { Stu stu; public StuThread2(Stu stu) { this.stu = stu; } public void run() { stu.read2(); } } class Stu { public synchronized void read1() { System.out.println("read1 begin"); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("read1 end"); } public synchronized void read2() { System.out.println("read2 begin"); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("read2 end"); } } |
打印结果为(两个线程是顺序执行的):
read1 begin read1 end read2 begin read2 end |
如果去掉read2前面的synchronized关键字,打印为(线程出现了交叉执行):
read1 begin read2 begin read2 end read1 end |
修改read2方法,
public void read2() { synchronized(this) { System.out.println("read2 begin"); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("read2 end"); } } |
对this进行加锁,结果同一次,线程是顺序执行的。