发布新日志

  • Oracle日常性能查看

    2016-04-16 22:41:08

    1、查看锁(lock)情况
    SELECT /* RULE */ Ls.Osuser Os_User_Name, Ls.Username User_Name,Decode(Ls.TYPE,
    'RW', 'Row wait enqueue lock', 'TM', 'DML enqueue lock','TX', 'Transaction enqueue lock', 'UL', 'User supplied lock') Lock_Type,o.Object_Name OBJECT,Decode(Ls.Lmode,1, NULL, 2, 'Row Share', 3, 'Row Exclusive',
    2、查询耗资源的进程(top session)
    SELECT s.Schemaname Schema_Name,Decode(Sign(48 - Command),
    1, To_Char(Command), 'Action Code #' || To_Char(Command)) Action,Status Session_Status, s.Osuser Os_User_Name, s.Sid, p.Spid,s.Serial# Serial_Num, Nvl(s.Username, '[Oracle process]') User_Name,
    s.Terminal Terminal, s.Program Program, St.VALUE Criteria_Value
    FROM V$sesstat St, V$session s, V$process p
    WHERE St.Sid = s.Sid
    AND St.Statistic# = To_Number('38')
    AND ('ALL' = 'ALL' OR s.Status = 'ALL')
    AND p.Addr = s.Paddr
    ORDER BY St.VALUE DESC, p.Spid ASC, s.Username ASC, s.Osuser ASC
    3、捕捉运行很久的SQL
    column username format a12
    column opname format a16
    column progress format a8 select username,sid,opname,
    round(sofar*100 / totalwork,0) || '%' as progress,
    time_remaining,sql_text
    from v$session_longops , v$sql
    where time_remaining <> 0
    and sql_address = address
    and sql_hash_value = hash_value
    /
    4、求当前会话的SID,SERIAL#
    SELECT Sid, Serial# FROM V$session
    WHERE Audsid = Sys_Context('USERENV', 'SESSIONID');
    5、查询session的OS进程ID
    SELECT p.Spid "OS Thread", b.NAME "Name-User", s.Program, s.Sid, s.Serial#,s.Osuser, s.Machine
    FROM V$process p, V$session s, V$bgprocess b
    WHERE p.Addr = s.Paddr
    AND p.Addr = b.Paddr And (s.sid=&1 or p.spid=&1)
    UNION ALL
    SELECT p.Spid "OS Thread", s.Username "Name-User", s.Program, s.Sid,s.Serial#, s.Osuser, s.Machine
    FROM V$process p, V$session s
    WHERE p.Addr = s.Paddr
    And (s.sid=&1 or p.spid=&1)
    AND s.Username IS NOT NULL;
    6、根据sid查看对应连接正在运行的sql
    SELECT /* PUSH_SUBQ */ Command_Type, Sql_Text, Sharable_Mem, Persistent_Mem, Runtime_Mem, Sorts,
    Version_Count, Loaded_Versions, Open_Versions, Users_Opening, Executions,
    Users_Executing, Loads, First_Load_Time, Invalidations, Parse_Calls,
    Disk_Reads, Buffer_Gets, Rows_Processed, SYSDATE Start_Time,
    SYSDATE Finish_Time, '>' || Address Sql_Address, 'N' Status
    FROM V$sqlarea WHERE Address = (SELECT Sql_Address
    FROM V$session WHERE Sid = &sid );
    7、查看有哪些用户连接
    SELECT s.Osuser Os_User_Name,Decode(Sign(48 - Command),1,To_Char(Command),
    'Action Code #' || To_Char(Command)) Action,
    p.Program Oracle_Process, Status Session_Status, s.Terminal Terminal,
    s.Program Program, s.Username User_Name,
    s.Fixed_Table_Sequence Activity_Meter, '' Query, 0 Memory,
    0 Max_Memory, 0 Cpu_Usage, s.Sid, s.Serial# Serial_Num
    FROM V$session s, V$process p
    WHERE s.Paddr = p.Addr
    AND s.TYPE = 'USER'
    ORDER BY s.Username, s.Osuser

  • AWR的生成

    2016-04-16 22:28:35

    AWRAutomatic Workload Repository)报告是我们进行日常数据库性能评定、问题SQL发现的重要手段。熟练掌握AWR报告,是做好开发、运维DBA工作的重要基本功。

     

     

    AWR报告的原理是基于Oracle数据库的定时镜像功能。默认情况下,Oracle数据库后台进程会以一定间隔(一小时)收集系统当前状态镜像,并且保存在数据库中。生成AWR报告时,只需要指定进行分析的时间段(开始镜像编号和结束镜像编号),就可以生成该时间段的性能分析情况。AWR镜像保存在数据库中的时间为一个月左右。

     

     

    目前Oracle10g之后,AWR报告取代了原先的Statspack报告成为一个主流性能分析报告。通常可以从OEMOracle Enterprise Manager Console)平台上生成查看AWR报告。在OEM中,使用图形化方法更加容易。本篇中介绍使用手工脚本方式生成AWR的方法,脱离OEM的限制。

     

     

    1、  运行脚本

     

    首先,准备一个目录作为AWR生成报告的路径。

     

     

    [oracle@bspdev /]$ ls -l | grep test

    drwxr-xr-x.   2 oracle oinstall  4096 Jun 21 13:01 test

     

    [oracle@bspdev /]$ cd test

     

     

    启动sqlplus等开发工具,调用生成脚本。程序脚本一般保存在$ORACLE_HOME下的rdbms/admin中,名称为awrrpt.sql

     

     

    [oracle@bspdev test]$ sqlplus /nolog

     

    SQL*Plus: Release 11.2.0.1.0 Production on Tue Jun 21 13:04:44 2011

     

    Copyright (c) 1982, 2009, Oracle.  All rights reserved.

     

    SQL> conn / as sysdba

    Connected.

     

    --调用脚本,生成文件

    SQL> @?/rdbms/admin/awrrpt.sql

     

     

    之后进入报告参数输入模块。

     

    2、输入报告参数

     

    之后,要持续输入一系列的报告参数。

     

    ü        输入生成报告类型,目前AWR提供txthtml两种格式。需要确认生成格式,默认是html格式。

     

     

    Current Instance

    ~~~~~~~~~~~~~~~~

     

       DB Id    DB Name      Inst Num Instance

    ----------- ------------ -------- ------------

     4143510747 ORA11G              1 ora11g

     

     

    Specify the Report Type

    ~~~~~~~~~~~~~~~~~~~~~~~

    Would you like an HTML report, or a plain text report?

    Enter 'html' for an HTML report, or 'text' for plain text

    Defaults to 'html'

     

     

    ü        报告涉及天数范围

     

    启动报告后,会显示生成实例的名称等基本信息。

     

    默认情况下,AWR会将镜像信息保留一个月。手工生成的时候,需要确认生成AWR报告的时间范围。一般情况下,特别是生产环境下,我们通常设置1-7天也就够用了。

     

     

    Instances in this Workload Repository schema

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     

       DB Id     Inst Num DB Name      Instance     Host

    ------------ -------- ------------ ------------ ------------

    * 4143510747        1 ORA11G       ora11g       bspdev.local

                                                    domain

     

    Using 4143510747 for database Id

    Using          1 for instance number

     

     

    Specify the number of days of snapshots to choose from

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Entering the number of days (n) will result in the most recent

    (n) days of snapshots being listed.  Pressing without

    specifying a number lists all completed snapshots.

     

    Enter value for num_days: 3 

     

     

    ü        输入开始和结束的snapshot编号

     

    输入天数信息后,AWR生成代码会将天数范围内的snapshot镜像点列出,供输入选择。

     

     

    Listing the last 3 days of Completed Snapshots

     

                                                            Snap

    Instance     DB Name        Snap Id    Snap Started    Level

    ------------ ------------ --------- ------------------ -----

    ora11g       ORA11G            1789 20 Jun 2011 13:01      1

                                   1790 20 Jun 2011 14:00      1

                                   1791 20 Jun 2011 15:00      1

                                   1792 20 Jun 2011 16:00      1

                                   (篇幅原因,有省略……

                                   1811 21 Jun 2011 11:00      1

                                   1812 21 Jun 2011 12:00      1

                                   1813 21 Jun 2011 13:00      1

     

     

     

    Specify the Begin and End Snapshot Ids

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     

     

    之后,我们需要根据列出的时间范围,输入开始和结束的snap编号。

     

     

    Specify the Begin and End Snapshot Ids

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Enter value for begin_snap: 1796

    Begin Snapshot Id specified: 1796

     

    Enter value for end_snap: 1813  

     

     

    ü        确定报告名称

     

    最后就是确定生成报告的名称。一般采用默认的名称就可以了。

     

     

    Specify the Report Name

    ~~~~~~~~~~~~~~~~~~~~~~~

    The default report file name is awrrpt_1_1796_1813.html.  To use this name,

    press to continue, otherwise enter an alternative.

     

    Enter value for report_name:

     

     

    之后输出内容很多,此处不加以累述。最后提示报告生成成功。

     

     

    Report written to awrrpt_1_1796_1813.html

     

     

    于是,指定目录上可以看到相应的报告文件。

     

     

    [oracle@bspdev test]$ ls -l

    total 508

    -rw-r--r--. 1 oracle oinstall 515262 Jun 21 13:10 awrrpt_1_1796_1813.html

     

     

     

    3、说明两个问题

     

    首先,此处生成的html格式的报表。如果要求生成txt格式,就在生成过程中选择text格式报表。

     

     

    Specify the Report Type

    ~~~~~~~~~~~~~~~~~~~~~~~

    Would you like an HTML report, or a plain text report?

    Enter 'html' for an HTML report, or 'text' for plain text

    Defaults to 'html'

    Enter value for report_type: text

     

    Type Specified:  text

     

    End of Report

    Report written to awrrpt_1_1789_1800.txt

     

    [oracle@bspdev test]$ ls -l

    total 692

    -rw-r--r--. 1 oracle oinstall 180601 Jun 21 13:27 awrrpt_1_1789_1800.txt

    -rw-r--r--. 1 oracle oinstall 515262 Jun 21 13:10 awrrpt_1_1796_1813.html

     

     

     

    第二个就是调用脚本的方式问题。调用时使用的sqlplus客户端可以在Oracle服务器本机上(远程登录),也可以在客户端机器本机上。笔者建议是在客户端本机上进行生成,这样可以避免报告文件来回拷贝的工作。但是最好要保证客户端版本与服务器版本相匹配。

     

     

    4、结论

     

    手工生成AWR报告,可以避免受到OEM的限制约束,而且灵活度高。本篇记录,权当备忘。

  • RestAssured之post表单实例

    2016-04-15 17:24:57

    package RestAssured;

    import com.jayway.restassured.RestAssured;
    import com.jayway.restassured.path.json.JsonPath;
    import com.jayway.restassured.response.Response;
    import static org.junit.Assert.*;
    import org.junit.Before;
    import org.junit.Test;
    import static com.jayway.restassured.RestAssured.*;
    //import static org.hamcrest.Matchers.*;
    import static org.hamcrest.Matchers.equalTo;


    /**
     * Created by chenman on 4/15/16.
     */
    public class Zhitong {
        @Before
        public void setUp() {
            RestAssured.baseURI = "http://wwwtest3.lu.com";
            //RestAssured.port = 8080;
            RestAssured.basePath = "/ztcs-gw/service";
        }

        @Test
        public void testAddgrouptime() {

           // final String bodyString = "{\"userId\": \"500588\",\"operator\": \"wangyoudong001\",\"requestTime\": \"2016-03-0916:10:00\",\"sign\": \"PTGJhzIN2bpTzUpuBnuxaZNl8ucwytZX6oLgmHx7IcQkSZ8SYfDf6v0sl3mw5bRtUWGEwjNyIrDbzeHdeyIschoecgXv3pJlFbi15YLVFP%2FUFywaVzE3%2FczcxgjsffP6vWriL7jS%2B6gSDeXc3c%2Fo0M8bqyiMSNOaktttmjtSnuaA5mz98a4oKnYqwSn%2B%2F1OO4p8Z%2FPM%2FzI26F88rewRDP5cK74kpBs9kzCyBdbV3XqnCy9FKsPqHJ%2Fw8%2FObInPTyT7NJTsRuQef63g%2FvUA6aXWbsHFaE8eMp%2BriOzzcRNunxVuhz8FIqDj2GelgHTFVnEsa2xHlquYjsZuLMvrjXCA%3D%3D\"}";
             given().
                    formParam("userId", "500588").formParam("operator","wangyoudong001").formParam("requestTime", "2016-03-0916:10:00").
                    formParam("sign", "PTGJhzIN2bpTzUpuBnuxaZNl8ucwytZX6oLgmHx7IcQkSZ8SYfDf6v0sl3mw5bRtUWGEwjNyIrDbzeHdeyIschoecgXv3pJlFbi15YLVFP/UFywaVzE3/czcxgjsffP6vWriL7jS+6gSDeXc3c/o0M8bqyiMSNOaktttmjtSnuaA5mz98a4oKnYqwSn+/1OO4p8Z/PM/zI26F88rewRDP5cK74kpBs9kzCyBdbV3XqnCy9FKsPqHJ/w8/ObInPTyT7NJTsRuQef63g/vUA6aXWbsHFaE8eMp+riOzzcRNunxVuhz8FIqDj2GelgHTFVnEsa2xHlquYjsZuLMvrjXCA==").
                    request().
                    expect().
                    statusCode(200).
                    body(
                             "result.code", equalTo("700000"),
                             "result.message", equalTo("成功")
                    ).
                    when().
                    post("/user-group/add-group-time");

        }

    }
  • 如何使用git clone下载github中源码

    2016-04-14 17:02:44

    一、安装git
    详见另一篇
    二、
    1、github的账号,https://github.com/pkainulainen/gradle-examples
    2、进入到要存放该代码的目录
    3、git clone https://github.com/pkainulainen/gradle-examples.git即可
    4、或者,点击Download zip
    三、
    使用IntelliJ IDEA分享、获取Github项目:
    · 1.在IDEA中配置Git:
      ·选择菜单”File — Settings”,找到”Version Control — Git”:到Git的安装目录下的Git.exe执行文件所在地
    ·  
     
      其次,配置你在Github上注册的账户:
      填入你的Github账户信息,点击”Test”按钮测试连接,若链接成功会提示”Connection successful”。保存完成。
      点击OK,此时可能要你输入IntelliJ IDEA的密码,如果没设,点击确定即可。
      
     
     2.分享项目Github上:
      选择菜单”VCS — Import into Version Control — Share project on Github”:
      
     
      填写描述信息后,点击”Share”按钮即可。
     
     3.获取Github项目:
      选择菜单”VCS — Checkout from Version Control — Github”:
      
     
      等待一段时间的验证和登陆,出现界面:
      
      在”Git Repository URL”下来列表中既有你自己的项目,也有你在Github网站上”Wacth”的项目,选择后,选择你存放的路径,再输入你想要的项目名称,点击”Clone”按钮,即完成获取过程。



  • 安装gradle

    2016-04-14 15:50:55

    安装gradle

    (系统构建工具,和MAVEN类似。目前使用的版本是gradle-1.0-milestone-3,如果有升级,相关同事会统一升级,默认请使用这个版本)
    unzip gradle-1.0-milestone-3-all.zip
    export PATH=/home/wangui800/Downloads/software/gradle-1.0-milestone-3/bin:$PATH

    配置启动的参数并使之生效(参看本页底部 bash_profile文件,可以直接copy其他同事的,然后替换机器名)
    vi ~/.bash_profile
    source ~/.bash_profile

    确认gradle安装成功
    gradle -version

  • Java 构建入门——gradle

    2016-04-14 14:31:34

    Java 插件

    如你所见,Gradle 是一个通用工具。它可以通过脚本构建任何你想要实现的东西,真正实现开箱即用。但前提是你需要在脚本中编写好代码才行。

    大部分 Java 项目基本流程都是相似的:编译源文件,进行单元测试,创建 jar 包。使用 Gradle 做这些工作不必为每个工程都编写代码。Gradle 已经提供了完美的插件来解决这些问题。插件就是 Gradle 的扩展,简而言之就是为你添加一些非常有用的默认配置。Gradle 自带了很多插件,并且你也可以很容易的编写和分享自己的插件。Java plugin 作为其中之一,为你提供了诸如编译,测试,打包等一些功能。

    Java 插件为工程定义了许多默认值,如Java源文件位置。如果你遵循这些默认规则,那么你无需在你的脚本文件中书写太多代码。当然,Gradle 也允许你自定义项目中的一些规则,实际上,由于对 Java 工程的构建是基于插件的,那么你也可以完全不用插件自己编写代码来进行构建。

    后面的章节我们通过许多深入的例子介绍了如何使用 Java 插件来进行以来管理和多项目构建等。但在这个章节我们需要先了解 Java 插件的基本用法。

    一个基本 Java 项目

    来看一下下面这个小例子,想用 Java 插件,只需增加如下代码到你的脚本里。

    采用 Java 插件

    build.gradle
    apply plugin: 'java'

    备注:示例代码可以在 Gralde 发行包中的 samples/java/quickstart 下找到。

    定义一个 Java 项目只需如此而已。这将会为你添加 Java 插件及其一些内置任务。

    添加了哪些任务?

    你可以运行 gradle tasks 列出任务列表。这样便可以看到 Java 插件为你添加了哪些任务。

    标准目录结构如下:

    project  
        +build  
        +src/main/java  
        +src/main/resources  
        +src/test/java  
        +src/test/resources  

    Gradle 默认会从 src/main/java 搜寻打包源码,在 src/test/java 下搜寻测试源码。并且 src/main/resources 下的所有文件按都会被打包,所有 src/test/resources 下的文件 都会被添加到类路径用以执行测试。所有文件都输出到 build 下,打包的文件输出到 build/libs 下。

    构建项目

    Java 插件为你添加了众多任务。但是它们只是在你需要构建项目的时候才能发挥作用。最常用的就是 build 任务,这会构建整个项目。当你执行 gradle build 时,Gralde 会编译并执行单元测试,并且将 src/main/* 下面 class 和资源文件打包。

    构建 Java 项目

    运行 gradle build 的输出结果

    Output of gradle build
    > gradle build
    :compileJava
    :processResources
    :classes
    :jar
    :assemble
    :compileTestJava
    :processTestResources
    :testClasses
    :test
    :check
    :build
    BUILD SUCCESSFUL
    Total time: 1 secs

    其余一些较常用的任务有如下几个:

    clean

    删除 build 目录以及所有构建完成的文件。

    assemble

    编译并打包 jar 文件,但不会执行单元测试。一些其他插件可能会增强这个任务的功能。例如,如果采用了 War 插件,这个任务便会为你的项目打出 War 包。

    check

    编译并测试代码。一些其他插件也可能会增强这个任务的功能。例如,如果采用了 Code-quality 插件,这个任务会额外执行 Checkstyle。

    外部依赖

    通常,一个 Java 项目拥有许多外部依赖。你需要告诉 Gradle 如何找到并引用这些外部文件。在 Gradle 中通常 Jar 包都存在于仓库中。仓库可以用来搜寻依赖或发布项目产物。下面是一个采用 Maven 仓库的例子。

    添加 Maven 仓库

    build.gradle
    repositories {
        mavenCentral()
    }

    添加依赖。这里声明了编译期所需依赖 commons-collections 和测试期所需依赖 junit。

    添加依赖

    build.gradle
    dependencies {
        compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
        testCompile group: 'junit', name: 'junit', version: '4.+'
    }

    了解更多可参阅依赖管理基础

    自定义项目

    Java 插件为你的项目添加了众多默认配置。这些默认值通常对于一个普通项目来说已经足够了。但如果你觉得不适用修改起来也很简单。看下面的例子,我们为 Java 项目指定了版本号以及所用的 JDK 版本,并且添加一些属性到 mainfest 中。

    自定义 MANIFEST.MF

    build.gradle
    sourceCompatibility = 1.5
    version = '1.0'
    jar {
        manifest {
            attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
        }
    }

    都有哪些可用属性?

    可以执行 gradle propertie s来得到项目的属性列表。用这条命令可以看到插件添加的属性以及默认值。

    Java 插件添加的都是一些普通任务,如同他们写在 Build 文件中一样。这意味着前面章节展示的机制都可以用来修改这些任务的行为。例如,可以设置任务的属性,添加任务行为,更改任务依赖,甚至是重写覆盖整个任务。在下面的例子中,我们将修改 test 任务,这是一个 Test 类型任务。让我们来在它执行时为它添加一些系统属性。

    为 test 添加系统属性

    build.gradle
    test {
        systemProperties 'property': 'value'
    }

    发布 jar 包

    如何发布 jar 包?你需要告诉 Gradle 发布到到哪。在 Gradle 中 jar 包通常被发布到某个仓库中。在下面的例子中,我们会将 jar 包发布到本地目录。当然你也可以发布到远程仓库或多个远程仓库中。

    发布 jar 包

    build.gradle
    uploadArchives {
        repositories {
           flatDir {
               dirs 'repos'
           }
        }
    }

    执行 gradle uploadArchives 以发布 jar 包。

    创建 Eclipse 文件

    若要把项目导入 Eclipse 中,你需要添加另外一个插件到你的脚本文件中。

    Eclipse plugin

    build.gradle
    apply plugin: 'eclipse'

    执行 gradle eclipse 来生成 Eclipse 项目文件。

    示例汇总

    这是示例代码汇总得到的一个完整脚本:

    Java 示例 - 一个完整构建脚本

    build.gradle
    apply plugin: 'java'
    apply plugin: 'eclipse'
    sourceCompatibility = 1.5
    version = '1.0'
    jar {
        manifest {
            attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
        }
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
        testCompile group: 'junit', name: 'junit', version: '4.+'
    }
    test {
        systemProperties 'property': 'value'
    }
    uploadArchives {
        repositories {
           flatDir {
               dirs 'repos'
           }
        }
    }

    多项目构建

    现在来看一个典型的多项目构建的例子。项目结构如下:

    多项目构建-项目结构

    Build layout
    multiproject/
      api/
      services/webservice/
      shared/

    备注: 本示例代码可在 Gradle 发行包的 samples/java/multiproject 位置找到

    此处有三个工程。api 工程用来生成给客户端用的 jar 文件,这个 jar 文件可以为 XML webservice 提供 Java 客户端。webservice 是一个 web 应用,生成 XML。shared 工程包含的是前述两个工程共用的代码。

    多项目构建定义

    定义一个多项目构建工程需要在根目录(本例中与 multiproject 同级)创建一个setting 配置文件来指明构建包含哪些项目。并且这个文件必需叫 settings.gradle 本例的配置文件如下:

    多项目构建中的 settings.gradle

    settings.gradle
    include "shared", "api", "services:webservice", "services:shared"

    公共配置

    对多项目构建而言,总有一些共同的配置.在本例中,我们会在根项目上采用配置注入的方式定义一些公共配置。根项目就像一个容器,子项目会迭代访问它的配置并注入到自己的配置中。这样我们就可以简单的为所有工程定义主配置单了:

    多项目构建-公共配置

    build.gradle
    subprojects {
        apply plugin: 'java'
        apply plugin: 'eclipse-wtp'
        repositories {
           mavenCentral()
        }
        dependencies {
            testCompile 'junit:junit:4.11'
        }
        version = '1.0'
        jar {
            manifest.attributes provider: 'gradle'
        }
    }

    值得注意的是我们为每个子项目都应用了 Java 插件。这意味着我们在前面章节学习的内容在子项目中也都是可用的。所以你可以在根项目目录进行编译,测试,打包等所有操作。

    工程依赖

    同一个构建中可以建立工程依赖,一个工程的 jar 包可以提供给另外一个工程使用。例如我们可以让 api 工程以依赖于 shared 工程的 jar 包。这样 Gradle 在构建 api 之前总是会先构建 shared 工程。

    多项目构建-工程依赖

    api/build.gradle
    dependencies {
        compile project(':shared')
    }

    打包发布

    如何发布,请看下文:

    多项目构建-发布

    api/build.gradle
    task dist(type: Zip) {
        dependsOn spiJar
        from 'src/dist'
        into('libs') {
            from spiJar.archivePath
            from configurations.runtime
        }
    }
    artifacts {
       archives dist
    }
  • 依赖管理基础

    2016-04-14 14:08:43

    什么是依赖管理?

    通俗来讲,依赖管理由如下两部分组成。首先,Gradle 需要知道项目构建或运行所需要的一些文件,以便于找到这些需要的文件。我们称这些输入的文件为项目的依赖。其次,你可能需要构建完成后自动上传到某个地方。我们称这些输出为发布。下面来仔细介绍一下这两部分:

    大部分工程都不太可能完全自给自足,一般你都会用到其他工程的文件。比如我工程需要 Hibernate 就得把它的类库加进来,比如测试的时候可能需要某些额外 jar 包,例如 JDBC 驱动或 Ehcache 之类的 Jar 包。

    这些文件就是工程的依赖。Gradle 需要你告诉它工程的依赖是什么,它们在哪,然后帮你加入构建中。依赖可能需要去远程库下载,比如 Maven 或者 Ivy 库。也可以是本地库,甚至可能是另一个工程。我们称这个过程叫依赖解决

    通常,依赖的自身也有依赖。例如,Hibernate 核心类库就依赖于一些其他的类库。所以,当 Gradle 构建你的工程时,会去找到这些依赖。我们称之为依赖传递

    大部分工程构建的主要目的是脱离工程使用。例如,生成 jar 包,包括源代码、文档等,然后发布出去。

    这些输出的文件构成了项目的发布内容。Gralde 也会为你分担这些工作。你声明了发布到到哪,Gradle 就会发布到哪。“发布”的意思就是你想做什么。比如,复制到某个目录,上传到 Maven 或 Ivy 仓库。或者在其它项目里使用,这些都可以称之为发行

    依赖声明

    来看一下这个脚本里声明依赖的部分:

    声明依赖

    build.gradle

    apply plugin: 'java'
    repositories {
        mavenCentral()
    }
    dependencies {
        compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
        testCompile group: 'junit', name: 'junit', version: '4.+'
    }

    这是什么意思呢?这段脚本是这么个意思。首先,Hibernate-core.3.6.7.final.jar 这货是编译期必需的依赖。并且这货相关的依赖也会一并被加载进来,该段脚本同时还声明项目测试阶段需要 4.0 版本以上的 Junit。同时告诉 Gradle 可以去 Maven 中央仓库去找这些依赖。下面的章节会进行更详细的描述。

    依赖配置

    Gradle 中依赖以组的形式来划分不同的配置。每个配置都只是一组指定的依赖。我们称之为依赖配置 。你也可以借由此声明外部依赖。后面我们会了解到,这也可用用来声明项目的发布。

    Java 插件定义了许多标准配置项。这些配置项形成了插件本身的 classpath。比如下面罗列的这一些,并且你可以从Table 23.5,“Java 插件 - 依赖配置”了解到更多详细内容.。

    compile

    编译范围依赖在所有的 classpath 中可用,同时它们也会被打包

    runtime

    runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要 JDBC API JAR,而只有在运行的时候才需要 JDBC 驱动实现

    testCompile

    测试期编译需要的附加依赖

    testRuntime

    测试运行期需要

    不同的插件提供了不同的标准配置,你甚至也可以定义属于自己的配置项。

    外部依赖

    依赖的类型有很多种,其中有一种类型称之为外部依赖。这种依赖由外部构建或者在不同的仓库中,例如 Maven 中央仓库或 Ivy 仓库中抑或是本地文件系统的某个目录中。

    定义外部依赖需要像下面这样进行依赖配置

    定义外部依赖

    build.gradle

    dependencies {
        compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
    }

    外部依赖包含 group,name 和 version 几个属性。根据选取仓库的不同,group 和 version 也可能是可选的。

    当然,也有一种更加简洁的方式来声明外部依赖。采用:将三个属性拼接在一起即可。"group:name:version"

    快速定义外部依赖

    build.gradle

    dependencies {
        compile 'org.hibernate:hibernate-core:3.6.7.Final'
    }

    仓库

    Gradle 是在一个被称之为仓库的地方找寻所需的外部依赖。仓库即是一个按 group,name 和 version 规则进行存储的一些文件。Gradle 可以支持不同的仓库存储格式,如 Maven 和 Ivy,并且还提供多种与仓库进行通信的方式,如通过本地文件系统或 HTTP。

    默认情况下,Gradle 没有定义任何仓库,你需要在使用外部依赖之前至少定义一个仓库,例如 Maven 中央仓库。

    使用 Maven 中央仓库

    build.gradle

    repositories {
        mavenCentral()
    }

    或者其它远程 Maven 仓库:

    使用 Maven 远程仓库

    build.gradle

    repositories {
        maven {
            url "http://repo.mycompany.com/maven2"
        }
    }

    或者采用 Ivy 远程仓库

    采用 Ivy 远程仓库

    build.gradle

    repositories {
        ivy {
            url "http://repo.mycompany.com/repo"
        }
    }

    或者在指定本地文件系统构建的库。

    采用本地 Ivy 目录

    build.gradle

    repositories {
        ivy {
            // URL can refer to a local directory
            url "../local-repo"
        }
    }

    一个项目可以采用多个库。Gradle 会按照顺序从各个库里寻找所需的依赖文件,并且一旦找到第一个便停止搜索。

    了解更多库相关的信息请参阅章节 50.6,“仓库”。

    打包发布

    依赖配置也被用于发布文件[3]我们称之为打包发布发布

    插件对于打包提供了完美的支持,所以通常而言无需特别告诉 Gradle 需要做什么。但是你需要告诉 Gradle 发布到哪里。这就需要在 uploadArchives 任务中添加一个仓库。下面的例子是如何发布到远程 Ivy 仓库的:

    发布到 Ivy 仓库

    build.gradle

    uploadArchives {
        repositories {
            ivy {
                credentials {
                    username "username"
                    password "pw"
                }
                url "http://repo.mycompany.com"
            }
        }
    }

    执行 gradle uploadArchives,Gradle 便会构建并上传你的 jar 包,同时会生成一个 ivy.xml 一起上传到目标仓库。

    当然你也可以发布到 Maven 仓库中。语法只需稍微一换就可以了。[4]

    p.s:发布到 Maven 仓库你需要 Maven 插件的支持,当然,Gradle 也会同时产生 pom.xml 一起上传到目标仓库。

    发布到 Maven 仓库

    build.gradle

    apply plugin: 'maven'
    uploadArchives {
        repositories {
            mavenDeployer {
                repository(url: "file://localhost/tmp/myRepo/")
            }
        }
    }
  • Java构建工具:Ant vs Maven vs Gradle

    2016-04-14 13:50:33

    http://blog.csdn.net/napolunyishi/article/details/39345995
  • TestNG 入门教程

    2016-04-13 17:04:30

    一、
    TestNG is bundled in IDEA 7 onwards, no extra plugins need to be installed. 
    run——edit configuration——testng
    二、
    http://www.cnblogs.com/TankXiao/p/3888070.html
  • junit的使用

    2016-04-13 14:45:17

    1、下载jar包
    https://github.com/junit-team/junit4/wiki/Download-and-Install
    下载junit-4.12.jar,junit-4.12-javadoc.jar(文档),junit-4.12-sources.jar(源码)。
    下载hamcrest-core-1.3.jar,hamcrest-core-1.3-javadoc.jar(文档),hamcrest-core-1.3-sources.jar(源码)。
    2、创建一个项目叫JUnit4Demo,然后创建一个lib文件夹放刚下载的junit-4.12.jarhamcrest-core-1.3.jar两个jar包并导入到项目里。
    3、创建一个类com.xuhongchuan.util.Math,然后输入一个求阶乘的方法:
    package com.xuhongchuan.util;
    
    /**
     * Created by xuhongchuan on 2015/7/18.
     */
    public class Math {
    
        /**
         * 阶乘
         * @param n
         * @return
         */
        public int factorial(int n) throws Exception {
            if (n < 0) {
                throw new Exception("负数没有阶乘");
            } else if (n <= 1) {
                return 1;
            } else {
                return n * factorial(n - 1);
            }
        }
    
    }
    好了,接下来要创建一个类来对Math类进行单元测试。
    创建一个和src同级别的文件夹叫test(逻辑代码放src里,测试代码放test里是个好习惯)。
    接着在IntelliJ IDEA里还要把这个test文件夹要设置成测试文件的根目录,右键选中
    Mark Directory As - Test Sources Root。
    然后创建com.xuhongchuan.util.MathTest类(包名一致,类名在要测试的类名后加上Test也是个好习惯)。
    在MathTest里输入以下内容:
    package com.xuhongchuan.util;
    
    import org.junit.Test;
    import static org.junit.Assert.*;
    
    /**
     * Created by xuhongchuan on 2015/7/18.
     */
    public class MathTest {
    
        @Test
        public void testFactorial() throws Exception {
    
            assertEquals(120, new Math().factorial(5));
    
        }
    
    }
    然后运行一下,绿色表示通过。
  • JUnit 4 与 TestNG 对比

    2016-04-13 14:12:40

    http://www.ituring.com.cn/article/47829

    Junit 4 和 TestNG 都是 Java 方面非常流行的单元测试框架。在功能上两个框架都非常类似。到底哪个比较好?在Java项目中我们应该选择哪个框架?

    下图将会对Junit 4 和 TestNG 做个功能特征的对比。

    junit-vs-testngjpg

    注解支持

    Junit 4 和 TestNG 在注解方面的实现非常相似。

    特性JUnit 4TestNG
    测试注解@Test@Test
    测试套件在执行之前需要执行的@BeforeSuite
    测试套件在执行之后需要执行的@AfterSuite
    在测试之前需要执行的@BeforeTest
    在测试之后需要执行的@AfterTest
    在一个测试方法所属于的任意一个组的第一个方法被调用之前执行@BeforeGroups
    在一个测试方法所属于的任意一个组的最后一个方法被调用之后执行@AfterGroups
    在当前类的第一个测试方法调用之前执行@BeforeClass@BeforeClass
    在当前类的最后一个测试方法调用之后执行@AfterClass@AfterClass
    每个测试方法之前需要执行@Before@BeforeMethod
    每个测试方法之后需要执行@After@AfterMethod
    忽略@ignore@Test(enabled=false)
    预期异常@Test(expected = ArithmeticException.class)@Test(expectedExceptions = ArithmeticException.class)
    超时@Test(timeout = 1000)@Test(timeout = 1000)

    JUnit 4 和 TestNG 之间注解方面的区别主要有以下几点:

    1. 在Junit 4 中,如果我们需要在方法前面使用@BeforeClass@AfterClass,那么该测试方法则必须是静态方法。TestNG 在方法定义部分则更加的灵活,它不需要类似的约束。
    2. 3个附加的setUp/tearDown级别:套件和分组(@Before/AfterSuite, @Before/AfterTest, @Before/AfterGroup)。想了解详细的请看这里

    JUnit 4

    @BeforeClass
    public static void oneTimeSetUp() {
        // one-time initialization code   
        System.out.println("@BeforeClass - oneTimeSetUp");
    }

    TestNG

    @BeforeClass
    public void oneTimeSetUp() {
        // one-time initialization code   
        System.out.println("@BeforeClass - oneTimeSetUp");
    }

    在Junit 4中,注解的命名是比较令人困惑的,例如 BeforeAfter and Expected,我们不是很确切的能理解在方法前面有BeforeAfter这样的注解是做什么的,同样Expected也如此。TestNG在这方面做的就好很多,注解使用了BeforeMethodAfterMethodExpectedException,这样的名字就非常好理解了。

    异常测试

    异常测试的意思是在单元测试中应该抛出什么异常是合理的,这个特性在两个框架都已经实现。

    JUnit 4

    @Test(expected = ArithmeticException.class)  
    public void divisionWithException() {  
        int i = 1/0;
    }

    TestNG

    @Test(expectedExceptions = ArithmeticException.class)  
    public void divisionWithException() {  
        int i = 1/0;
    }

    忽略测试

    忽略测试意思是在单元测试哪些是可以被忽略的,这个特性在两个框架都已经实现。

    JUnit 4

    @Ignore("Not Ready to Run")  
    @Test
    public void divisionWithException() {  
        System.out.println("Method is not ready yet");
    }

    TestNG

    @Test(enabled=false)
    public void divisionWithException() {  
        System.out.println("Method is not ready yet");
    }

    时间测试

    时间测试意思是如果一个单元测试运行的时间超过了一个指定的毫秒数,那么测试将终止并且标记为失败的测试,这个特性在两个框架都已经实现。

    JUnit 4

    @Test(timeout = 1000)  
    public void infinity() {  
        while (true);  
    }

    TestNG

    @Test(timeOut = 1000)  
    public void infinity() {  
        while (true);  
    }

    套件测试

    套件测试就是把几个单元测试组合成一个模块,然后运行,这个特性两个框架均已实现。然而却是用了两个不同的方式来实现的。

    JUnit 4

    @RunWith 和 @Suite注解被用于执行套件测试。下面的代码是所展示的是在JunitTest5被执行之后需要JunitTest1 和 JunitTest2也一起执行。所有的声明需要在类内部完成。

    @RunWith(Suite.class)
    @Suite.SuiteClasses({
        JunitTest1.class,
        JunitTest2.class
    })
    public class JunitTest5 {
    }

    TestNG

    执行套件测试是使用XML文件配置的方式来做。下面的 XML 的文件可以使得TestNGTest1TestNGTest2一起执行。

    <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
    <suite name="My test suite">
      <test name="testing">
        <classes>
           <class name="com.fsecure.demo.testng.TestNGTest1" />
           <class name="com.fsecure.demo.testng.TestNGTest2" />
        </classes>
      </test>
    </suite>

    TestNG可以在这块做的更好,使用了的概念,每个方法都可以被分配到一个组里面,可以根据功能特性来分组。例如:

    这是一个有4个方法,3个组(method1, method2 和 method4)的类

    @Test(groups="method1")
    public void testingMethod1() {  
      System.out.println("Method - testingMethod1()");
    }  
    
    @Test(groups="method2")
    public void testingMethod2() {  
        System.out.println("Method - testingMethod2()");
    }  
    
    @Test(groups="method1")
    public void testingMethod1_1() {  
        System.out.println("Method - testingMethod1_1()");
    }  
    
    @Test(groups="method4")
    public void testingMethod4() {  
        System.out.println("Method - testingMethod4()");
    }

    下面XML文件定义了一个只是执行methed1的组的单元测试

    <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
    <suite name="My test suite">
      <test name="testing">
          <groups>
          <run>
            <include name="method1"/>
          </run>
        </groups>
        <classes>
           <class name="com.fsecure.demo.testng.TestNGTest5_2_0" />
        </classes>
      </test>
    </suite>

    使用分组的概念,集成测试就会更加强大。例如,我们可以只是执行所有测试中的组名为DatabaseFuntion的测试。

    参数化测试

    参数化测试意思是给单元测试传多个参数值。这个特性在JUnit 4 和TestNG。然后两个框架实现的方式却完全不同。

    JUnit 4

    @RunWith 和 @Parameter 注解用于为单元测试提供参数值,@Parameters必须返回 List[],参数将会被作为参数传给类的构造函数。

    @RunWith(value = Parameterized.class)
    public class JunitTest6 {
    
         private int number;
    
         public JunitTest6(int number) {
            this.number = number;
         }
    
         @Parameters
         public static Collection<Object[]> data() {
           Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
           return Arrays.asList(data);
         }
    
         @Test
         public void pushTest() {
           System.out.println("Parameterized Number is : " + number);
         }
    }

    它在使用上有许多的限制;我们必须遵循 JUnit 的方式去声明参数,参数必须通过构造函数的参数去初始化类的成员来用于测试。返回的参数类型必须是List [],数据已经被限定为String或者是一个原始值。

    TestNG

    使用XML文件或者@DataProvider注解来给测试提供参数。

    XML文件配置参数化测试

    只是在方法上声明@Parameters注解,参数的数据将由 TestNG 的 XML 配置文件提供。这样做之后,我们可以使用不同的数据集甚至是不同的结果集来重用一个测试用例。另外,甚至是最终用户,QA 或者 QE 可以提供使用 XML 文件来提供他们自己的数据来做测试。

    Unit Test

      public class TestNGTest6_1_0 {
    
       @Test
       @Parameters(value="number")
       public void parameterIntTest(int number) {
          System.out.println("Parameterized Number is : " + number);
       }
    
      }

    XML 文件

    
    查看(696)
    评论(0)
    收藏
    分享
    管理
    

  • 接口自动化之Rest-Assured的使用

    2016-04-12 20:05:32

    安装和使用

    首先,读者需要访问 Rest-Assured 的官方网站下载最新版本的 Rest-Assured。写作此文时,作者使用的是 2.4.1,下载解压成功后,会发现软件包还包含了其他第三方依赖,这些都是运行期需要的类库,确保将它们都加入你的 classpath。还要加入junit-4.11.jar。

    现在我们以豆瓣 API 为例,简单介绍一下 Rest-Assured 的使用方法。为此,我们需要安装一个 REST 客户端插件方便调试。如果使用 FireFox 浏览器,可安装 RESTClient 插件,安装成功后,在地址一栏输入:http://api.douban.com/v2/book/1220562,方法选择 GET,请求发送成功后,会返回如下 JSON 字符串:


    package RestAssured;

    import com.jayway.restassured.RestAssured;

    import org.junit.Before;

    import org.junit.Test;


    import static com.jayway.restassured.RestAssured.*;

    import static com.jayway.restassured.matcher.RestAssuredMatchers.*;

    import static org.hamcrest.Matchers.*;


    public class DouBanTest {

        @Before

        public void setUP(){

            //指定 URL 和端口号

            RestAssured.baseURI = "http://api.douban.com/v2/book";

            RestAssured.port = 80;

        }


        @Test

        public void testGETBook()

        {

            get("/1220562").then().body("title", equalTo("满月之夜白鲸现"));

        }

    }


  • IntelliJ IDEA java项目中添加jar包

    2016-04-12 19:39:00

    1、点击 File ->  Project Structure(快捷键 Ctrl + Alt + Shift + s),点击Project Structure界面左侧的“Modules”显示下图界面。
    2、在 “Dependencies” 标签界面下,点击右边绿色的 “+”号,选择第一个选项“JARs or directories...”,选择相应的jar包,点“OK”,jar包添加成功。
  • Map

    2016-04-08 16:00:10

    Map是通过key-value键值对来存储数据的,一个key对应一个value。常用实现类有:HashMap和TreeMap类
    package Map;

    import java.util.Date;
    import java.util.HashMap;
    import java.util.Iterator;

    public class Test_Map {
        public static void main(String[] args) {
            HashMap map = new HashMap();//创建HashMap对象
            //往HashMap中存放数据,aaa是键的名称,
            //对象new Date()是值
            map.put("aaa",new Date());
            map.put(new Integer(23),"hello");
            map.put("work", "good");
            //通过键名work来取数据,由于存入map里的数据
            //会变成Object类型,所以取数据时要强制类型转换
            String a = (String)map.get("work");
            System.out.println(a);
            //调用keySet方法返回一个包含HashMap所有键名的set视图
            //Set all = map.keySet();
            //map.values()
            //通过set接口的iterator方法返回一个迭代器
            Iterator it = map.keySet().iterator();
            //输出所有的键名
            while(it.hasNext()){ System.out.println(it.next()); } }
    }

  • List

    2016-04-08 15:27:12

    List接口是Collection接口的子接口。List里面存放的元素是有序的,允许重复。常用的实现类有:Vector,ArrayList和LinkedList类。
    package List;

    import java.util.Date;
    import java.util.Vector;


    public class Test_Vector {
        public static void main(String[] args) {
            Vector v = new Vector();
            v.add("abc");//增加字符串abc到vector里
            v.add(new Date());
            v.add("abc");
            v.add("sdsd");
            //输出所有数据
            for(int i=0;i<v.size();i++){ System.out.println(v.get(i)); } }
    }

  • set

    2016-04-08 15:25:32

    set接口是Collection接口的子接口。不允许在set里面的存放重复的元素。通过迭代器(Iterator)返回的元素的顺序是不确定的。set接口常用的实现类有HashSet和TreeSet类
    package Set;

    import java.util.Date;
    import java.util.HashSet;
    import java.util.Iterator;


    public class Test_HashSet {
        public static void main(String[] args) {
            HashSet hs = new HashSet();//创建HashSet对象
            hs.add("abc");//在HashSet里增加字符串
            hs.add(new Date());//在HashSet里增加日期对象
            hs.add("abc");//若增加重复的元素,则自动覆盖
            hs.add(new Integer(12));
            Iterator it = hs.iterator();//返回一个迭代器
            // 输出HashSet里的所有元素
            while(it.hasNext()){ System.out.println(it.next()); } }
    }

  • 泛型类

    2016-04-08 14:51:47

    public class Box<T> {
        private T t;

        public void add(T t) {
            this.t = t;
        }

        public T get() {
            return t;
        }

        public static void main(String[] args) {
            Box<Integer> integerBox = new Box<Integer>();
            Box<String> stringBox = new Box<String>();

            integerBox.add(new Integer(10));
            stringBox.add(new String("菜鸟教程"));

            System.out.printf("整型值为 :%d\n\n", integerBox.get());
            System.out.printf("字符串为 :%s\n", stringBox.get());
        }
    }
  • 泛型方法

    2016-04-08 14:51:02

    class Demo{
        public <T> T fun(T t){            // 可以接收任意类型的数据
            return t ;                  // 直接把参数返回
        }
    };
    public class GenericsDemo26 {
        public static void main(String args[]){
            Demo d = new Demo() ;   // 实例化Demo对象
            String str = d.fun("李兴华") ; //  传递字符串
            int i = d.fun(30) ;     // 传递数字,自动装箱
            System.out.println(str) ;   // 输出内容
            System.out.println(i) ;     // 输出内容
        }
    }

  • 泛型接口

    2016-04-08 14:33:32

    public interface Info<T> {// 在接口上定义泛型
        public T getVar() ; // 定义抽象方法,抽象方法的返回值就是泛型类型

    }
    class InfoImpl<T> implements Info<T>{   // 定义泛型接口的子类
        private T var ;             // 定义属性
        public InfoImpl(T var){     // 通过构造方法设置属性内容
            this.setVar(var) ;
        }
        public void setVar(T var){
            this.var = var ;
        }
        public T getVar(){
            return this.var ;
        }
    };
    public class GenericsDemo24 {
        public static void main(String arsg[]){
            Info<String> i = null;        // 声明接口对象
            i = new InfoImpl<String>("李兴华") ; // 通过子类实例化对象
            System.out.println("内容:" + i.getVar()) ;
        }
    }

  • map的使用

    2016-04-08 14:21:38

    1. 首先是创建map,在java中的map是一个接口,不能直接实例化,所以需要把实现了map的实现类对象给map赋值。比如可以这样实例化一个map:
    2. Map map<Object,Object> = new HashMap<Object,Object>();

    3. 2

      当map中不存在对应的键时返回的是什么值?

      例如:

      map.get("test")

      如果key=test的键不存在,那么返回null,所以在代码中可以这样判断:

      if(map.get("test") != null){

           //to do something

      }

    4. 3

      HashMap实现的map实例是无序的,那么怎样通过循环去获取map中的值呢?

      可以通过map的keySet()方法获取键的集合,然后再通过循环即可获取所有的map中的值。具体示例如下:

      Map<Object,Object>map=new HashMap<Object, Object>();

      map.put( "test", "test");

      map.put( "test1", "test1");

      //获取map中的key

      Set<Object>set=map .keySet()

        for(Object obj:set)

       {

             map.get(obj);

       }

782/4<1234>
Open Toolbar