groovy 的常用操作

Posted 阿拉的梦想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了groovy 的常用操作相关的知识,希望对你有一定的参考价值。

groovy 的常用操作


推荐阅读:Springboot中使用Groovy的各种方式

全局变量

方式1:static 定义的全局变量可以在不同的类使用

class Globals 
   //定义全局变量
   static Integer NUM;

if(Globals.NUM == null)
   //初始化
  Globals.NUM = 1;
  println "初始化";

//日志输出
println show();

//自定义方法,访问变量
Integer show()
    return Globals.NUM;

方式2:使用@Field 定义的全局变量可以在不通的方法间共用

import groovy.transform.Field
//定义全局变量
@Field Integer NUM;
if(NUM == null)
   //初始化
    NUM = 1;
    println '初始化';

//日志输出
println show();

//自定义方法,访问变量
Integer show()
    return NUM;

JSON操作

字符串转json对象:
jsonSlpuer.parse()方法,可以从字符串、文件、byte[]、url、输入流等直接解析为对象。

def jsonSlpuer = new JsonSlurper()
def jsonObj=jsonSlpuer.parseText(str)

对象转json字符串:

package file
 
import groovy.json.JsonOutput
import objectorention.Person
 
def list = [new Person(name: 'John', age: 25),
            new Person(name: 'Major', age: 26)]
println JsonOutput.toJson(list)

发送http

1.get 超简单

def res1 = new URL('http://www.baidu.com').text
// or 
def res2 = 'http://www.baidu.com'.toURL().text
//设置超时时间 ms
def res3 = new URL('http://www.baidu.com').getText(readTimeout: 200000)

2. get 自带请求头

    /**
     * 发送httpGet请求,自带请求头
     * @param url 必填
     * @param headerMap 非必填
     * @return
     */
    static def httpGet(url, headerMap) 
        def conn = new URL(url).openConnection()
        conn.setRequestMethod("GET")

        if (headerMap) 
            headerMap.each  header ->
                conn.setRequestProperty(header.key, header.value)
            
        
        return conn.content.text
    

3. post 传入header和body返回json

    static void main(String[] args) 
        def url = "http://demo.com:8088/user/special/list/2/10"
        def data = [:]
        def isJson = true

        def headerMap = [:]
        headerMap.put("Content-Type", "application/json")
        headerMap.put("Cookie", "MS_SESSION_ID=123456")
        headerMap.put("CSRF-TOKEN", "12345")

        def post = httpPostJson(url, data, headerMap, isJson)
        println(post)
    
	
	//工具方法
    static def httpPostJson(url, body = null, headerMap, isJson = false) 
        def conn = new URL(url).openConnection()
        conn.setRequestMethod("POST")

        if(headerMap)
            headerMap.eachheader->
                conn.setRequestProperty(header.key, header.value)
            
        
        if (body!=null) 
            // 写入body
            conn.doOutput = true
            def writer = new OutputStreamWriter(conn.outputStream)
            writer.write(JsonOutput.toJson(body))
            writer.flush()
            writer.close()
        

        if(isJson)
            def json = new JsonSlurper()
            def result = json.parseText(conn.content.text)
            return result

        else 
            return conn.content.text
        

    

SQL操作

sql查询、新增、更新

//数据库连接
def sql = Sql.newInstance('jdbc:mysql://10.0.0.1:3306/demo?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false', 'root', '123456', 'com.mysql.jdbc.Driver')

def saveSumary(String fullName, BigDecimal cost, def sql) 
    cost.setScale(2, BigDecimal.ROUND_HALF_UP)
    def percent='10%'
    def row = sql.firstRow('select * from apportion_summary where full_name=?', [fullName])
    if (row == null) 
        def insertSql = "insert into apportion_summary(full_name,`final_cost_" + percent + "`) values(?,?)"
        try 
            sql.executeInsert(insertSql, [fullName, cost])
         catch (Exception e) 
            log.error("保存数据到Mysql异常,fullName=,cost=", fullName, cost)
            throw new Exception()
        

     else 
        def updateSql = "update apportion_summary set `final_cost_" + percent + "`=? where full_name=?"
        sql.executeUpdate(updateSql, [cost, fullName])
    
    sql.close()


查询并新建字段

    /**
     * 新建字段
     * @return
     */
    def createColumn(def sql) 
        //def sql = Sql.newInstance('jdbc:mysql://10.0.0.1:3306/demo?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false','root', '123456', 'com.mysql.jdbc.Driver')
        //def execute = sql.execute("desc apportion_summary ")
        def columns = []
        sql.eachRow("desc apportion_summary",  it -> columns.add(it[0]) )
        if (!columns.contains("final_cost_" + percent)) 
            def str = "ALTER TABLE demo.apportion_summary ADD `final_cost_" + percent + "` DECIMAL(10,2) comment '去掉调用占比" + percent + "后的'"
            sql.execute(str)
        
        //sql.close()
    

批量新增

    def saveMembers(List<Member> members) 
        def conn = Sql.newInstance('jdbc:mysql://10.0.0.1:3306/demo?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false', 'root', '123456', 'com.mysql.jdbc.Driver')

        conn.withTransaction 
            def updateCounts = conn.withBatch  stmt ->
                for(member in members)
                    stmt.addBatch("INSERT INTO `member` (member_name, pinyin, member_key, member_type, dept_code, full_dept_name, full_dept_code) VALUES( '"+member.memberName+"', '"+member.pinyin+"', '"+member.memberKey+"', "+member.memberType+", '"+member.deptCode+"', '"+member.fullDeptName+"', '"+member.fullDeptCode+"')")
                
            
            println("新增数据="+updateCounts.size())
        
        conn.close()
    

列表查询

    def getAllMembers()
        def conn = Sql.newInstance('jdbc:mysql://10.0.0.1:3306/demo?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false', 'root', '123456', 'com.mysql.jdbc.Driver')
        def map=[:]
        conn.eachRow('select * from member')  row ->
            def member = new Member()
            member.memberName=row.member_name
            member.pinyin=row.pinyin
            member.memberKey=row.member_key
            member.memberType=row.member_type
            member.deptCode=row.dept_code
            member.fullDeptName=row.full_dept_name
            member.fullDeptCode=row.full_dept_code
            map.put(member.memberKey,member)
        
        conn.close()
        return map
    

多线程

groovy没有提供自己语法的线程和线程池书写方法,所以,需要使用java语法实现。兼容上有些许问题,就是传入线程的变量必须用闭包,否则多个线程间执行的数据会乱套。

不要使用普通循环将变量传递到线程,要使用闭包

如下:

package other

import java.util.concurrent.*


class demo 

    static void main(String[] args) throws ExecutionException, InterruptedException 
        ThreadPoolExecutor pool = new ThreadPoolExecutor(20, 20, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20), new ThreadPoolExecutor.CallerRunsPolicy());
        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
        ArrayList<Future> fs = new ArrayList<>();
        //正确总数是200
        //for(def info in getInfoList()) //错误,线程不安全
        //getInfoList().collect  info ->//正确,线程安全
        //getInfoList().forEach() info->//正确,线程安全
        getInfoList().each info->//正确,线程安全
            Future<?> future = pool.submit( ->
                map.put(info.id + "-A", "1");
                println(info.id + "==" + Thread.currentThread().getId())
                sleep(20);
                map.put(info.id + "-B", "1");
             as Callable);
            fs.add(future);
        
        for (Future f : fs) 
            f.get();
        
        System.out.println(map.size());
    

    static List<Info> getInfoList() 
        ArrayList<Info> list = new ArrayList<>();
        for (int it = 0; it < 100; it++) 
            Info info = new Info();
            info.id = UUID.randomUUID().toString();
            list.add(info);
        
        return list;
    

    static class Info 
        String id;
    


集合操作

collect

收集操作,传入闭包的值变化后不影响原值
相当于java的stream().collect(Collectors.toList())

        def cl = it*2
        def res =IntStream.range(0,10).collect cl
        println(res)//[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

findAll

可以去除负面元素,如0、false、空字符串、空数组、null

 def items = [1, 2, 0, false, true, '', 'foo', [], [4, 5], null]
  assert items.findAll() == [1, 2, true, 'foo', [4, 5]]

正则

def a= ~/\\s(USG.*?)\\s/
用//包括正则,可以不转义
用~放字符串前面,可以得到Pattern对象,注意左侧距离=有一个空格

str =~ reg
用=~ 中间无空格,可以得到Matcher对象

	def reg=/\\s(USG.*?)\\s/
	def str="abcUSG9000"
	regFind(str, reg, 0)

	def regFind(String str, String reg, int index) 
		def matcher = str =~ reg
		if (matcher.find()) 
			return matcher.group(index)
		
	

以上是关于groovy 的常用操作的主要内容,如果未能解决你的问题,请参考以下文章

groovy 的常用操作

Groovy03_集合

jenkins2 -pipeline 常用groovy脚本

Groovy常用编程知识点简明教程

groovy常用模块

Gradle入门--Groovy常用语法