{"id":25437663,"url":"https://github.com/wycst/wast","last_synced_at":"2025-04-09T15:02:11.001Z","repository":{"id":52344128,"uuid":"497479870","full_name":"wycst/wast","owner":"wycst","description":"WAST is a high-performance Java toolset library package that includes JSON, YAML, CSV, HttpClient, JDBC and EL engines","archived":false,"fork":false,"pushed_at":"2025-03-28T04:22:30.000Z","size":2196,"stargazers_count":66,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-02T10:44:33.060Z","etag":null,"topics":["csv","expression","httpclient","jdbc","json","yaml"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wycst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"supports/json-springmvc/JSONHttpMessageConverter.java","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-29T03:25:03.000Z","updated_at":"2025-03-28T04:22:34.000Z","dependencies_parsed_at":"2024-06-01T10:55:55.391Z","dependency_job_id":"005df02f-5519-47a7-9cb1-1eaf597e62f6","html_url":"https://github.com/wycst/wast","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wycst%2Fwast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wycst%2Fwast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wycst%2Fwast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wycst%2Fwast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wycst","download_url":"https://codeload.github.com/wycst/wast/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248055281,"owners_count":21040156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csv","expression","httpclient","jdbc","json","yaml"],"created_at":"2025-02-17T09:19:07.550Z","updated_at":"2025-04-09T15:02:10.967Z","avatar_url":"https://github.com/wycst.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"## 介绍\n\nWAST是一个高性能Java工具集库包，包括JSON、YAML、CSV、HttpClient、JDBC和EL引擎.\n\n性能评测数据(github: https://github.com/wycst/wast-jmh-test) \u003cbr\u003e\n[https://gitee.com/xiaoch0209/wast-jmh-test](https://gitee.com/xiaoch0209/wast-jmh-test)\n\n2022-09-25 json性能测试数据 \u003cbr\u003e\n[https://gitee.com/xiaoch0209/wast-jmh-test/blob/main/README_0925_json.md](https://gitee.com/xiaoch0209/wast-jmh-test/blob/main/README_0925_json.md)\n\n2022-12-14 表达式引擎\u003cbr\u003e\n[https://gitee.com/xiaoch0209/wast-jmh-test/blob/main/README_1214_EL.md](https://gitee.com/xiaoch0209/wast-jmh-test/blob/main/README_1214_EL.md)\n\n此库不依赖任何第三方库，对JDK版本要求1.6及以上即可。\n\n## Maven\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.wycst\u003c/groupId\u003e\n    \u003cartifactId\u003ewast\u003c/artifactId\u003e\n    \u003cversion\u003e0.0.25\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## JSON\n\n\u003e 1 java语言整体性能最快的json库之一；\u003cbr\u003e\n\u003e 2 支持IO流文件读写，JSON节点树按需解析，序列化格式化，驼峰下划线自动转换,实体类解析绑定；\u003cbr\u003e\n\u003e 3 支持自定义序列化和反序列化；\u003cbr\u003e\n\u003e 4 支持JSON的xpath提取功能；\u003cbr\u003e\n\u003e 5 没有漏洞风险；\u003cbr\u003e\n\n## YAML\n\n\u003e 1 目前java语言解析yaml最快的库之一；\u003cbr\u003e\n\u003e 2 支持文件流，URL, 字符数组，字符串等解析；\u003cbr\u003e\n\u003e 3 支持常用yaml语法以及类型转换；\u003cbr\u003e\n\u003e 4 内置Yaml节点模型，支持路径查找(v0.0.4+)；\u003cbr\u003e\n\u003e 5 支持yaml反向转换为字符串或者文件(v0.0.4+)；\u003cbr\u003e\n\n## 表达式引擎\n\n\u003e 1 java表达式引擎性能最快之一；\u003cbr\u003e\n\u003e 2 支持java中所有的操作运算符（加减乘除余，位运算，逻辑运算，字符串+）；\u003cbr\u003e\n\u003e 3 支持**指数运算(java本身不支持)； \u003cbr\u003e\n\u003e 4 支持函数以及自定义函数实现； \u003cbr\u003e\n\u003e 5 科学记数法支持，16进制，8进制等解析，支持大数运算(BigDecimal)；\u003cbr\u003e\n\u003e 6 支持三目运算；\u003cbr\u003e\n\u003e 7 没有漏洞风险；\u003cbr\u003e\n\u003e 8 支持超长文本表达式执行；\u003cbr\u003e\n\u003e 9 支持表达式编译模式运行；\u003cbr\u003e\n\n## JDBC\n\n\u003e 1 集成了类似JdbcTemplate,Mybatis-Plus或者JPA等操作习惯的api; \u003cbr\u003e\n\u003e 2 代码轻量，简单易用；\u003cbr\u003e\n\u003e 3 支持面向原始sql,sql模版,对象管理等三种操作模式用，后两种模式完全能避免SQL注入漏洞（根源解决）；\u003cbr\u003e\n\u003e 4 理论上支持所有提供JDBC协议的数据库；\u003cbr\u003e\n\n## HttpClient\n\n\u003e 1 当前只支持http/1.1;\u003cbr\u003e\n\u003e 2 底层核心为URLConnection，封装了http客户端常用的API；\u003cbr\u003e\n\u003e 3 支持文件上传(已封装API)，文件下载也能轻松处理支持；\u003cbr\u003e\n\u003e 4 支持nacos和consul作为ServerZone提供源，可以通过服务实例来访问请求；\u003cbr\u003e\n\u003e 5 支持负载均衡(客户端)和高可用访问调用；\u003cbr\u003e\n\n## JSON\n\n### 常用对象json序列化\n\n```\nMap map = new HashMap();\nmap.put(\"msg\", \"hello, wastjson !\");\nString result = JSON.toJsonString(map);\n```\n\n### 对象序列化到文件\n\n```\nMap map = new HashMap();\nmap.put(\"msg\", \"hello, wastjson !\");\nJSON.writeJsonTo(map, new File(\"/tmp/test.json\"));\n```\n\n### 格式序列化\n\n```\nMap map = new HashMap();\nmap.put(\"name\", \"zhangsan\");\nmap.put(\"msg\", \"hello, wastjson !\");\nJSON.toJsonString(map, WriteOption.FormatOut);\n\n{\n\t\"msg\":\"hello, wastjson !\",\n\t\"name\":\"zhangsan\"\n}\n```\n\n### 反序列化\n\n```\nString json = \"{\\\"msg\\\":\\\"hello, wastjson !\\\",\\\"name\\\":\\\"zhangsan\\\"}\";\nMap map = (Map) JSON.parse(json);\nSystem.out.println(map);\n{msg=hello, wastjson !, name=zhangsan}\n```\n\n### 指定类型反序列化\n\n```\n    String json = \"{\\\"msg\\\":\\\"hello, wastjson !\\\",\\\"name\\\":\\\"zhangsan\\\"}\";\n    Map map = JSON.parseObject(json, Map.class);\n    System.out.println(map);\n    {msg=hello, wastjson !, name=zhangsan}\n```\n\n### 个性化支持\n\n1.针对实体bean的属性可以添加注解@JsonSerialize和@JsonDeserialize来实现定制化(使用见test模块custom目录例子)。\n\u003c/br\u003e\n\n2.通过JSON静态方法针对不同的类型来做个性化支持或者功能支持,非常方便;\n\n```\n    JSON.registerTypeMapper(java.time.ZoneId.class, new JSONTypeMapper\u003cZoneId\u003e() {\n        @Override\n        public ZoneId readOf(Object any) {\n            return any == null ? null : ZoneId.of((String) any);\n        }\n\n        @Override\n        public JSONValue\u003c?\u003e writeAs(ZoneId zoneId, JSONConfig jsonConfig) throws Exception {\n            return zoneId == null ? null : JSONValue.of(zoneId.getId());\n        }\n    });\n```\n\n### 基于输入流的读取解析\n\n```\n    Map result = null;\n    \n    // 1 url\n    result = JSON.read(new URL(\"https://developer.aliyun.com/artifact/aliyunMaven/searchArtifactByGav?groupId=spring\u0026artifactId=\u0026version=\u0026repoId=all\u0026_input_charset=utf-8\"), Map.class);\n    \n    // 2 stream\n    InputStream inputStream = InputStreamTest.class.getResourceAsStream(\"/sample.json\");\n    result = JSON.read(inputStream, Map.class);\n    \n    // 3 file\n    result = JSON.read(new File(\"/tmp/smaple.json\"), Map.class);\n```\n\n### 基于输入流的按需解析\n\n提供JSONReader类可按需解析一个输入流，自定义解析，可随时终止(不用将整个文件流读完)。\n\n```\n        final JSONReader reader = JSONReader.from(new File(f));\n        reader.read(new JSONReaderHook() {\n            @Override\n            public void parseValue(String key, Object value, Object host, int elementIndex, String path, int type) throws Exception {\n                if(path.equals(\"/features/1/properties/STREET\")) {\n                    System.out.println(value);\n                    abort();\n                }\n            }\n        }, true);\n```\n\n### 强大的JSONNode功能\n\n\u003e 1、支持对大文本json的懒加载按需解析功能，当需要读取一个大文本json中一个或多个属性值时非常有用；\u003cbr\u003e\n\u003e 2、支持上下文查找；\u003cbr\u003e\n\u003e 3、支持在大文本json中提取部分内容作为解析上下文结果，使用JSONNode.from(source, path)；\u003cbr\u003e\n\u003e 4、支持对节点的属性修改，删除等，节点的JSON反向序列化；\u003cbr\u003e\n\u003e 5、支持提取功能(v0.0.2+支持)，参考JSONPath；\n\n使用'/'作为路径的分隔符，数组下标使用n访问支持*, n+, n-,n等复合下标访问，例如/store/book/*/author\n\n```\n  String json = \"{\\\"name\\\": \\\"li lei\\\", \\”properties\\\": {\\\"age\\\": 23}}\";\n  JSONNode node = JSONNode.parse(json);\n  // 获取当前节点（根节点）的name属性\n  String name = node.getChildValue(\"name\", String.class);\n  \n  // 通过getPathValue方法可以获取任意路径上的值\n  int age = node.getPathValue(\"/properties/age\", int.class);\n  \n  // 通过path可以定位到任何路径节点\n  JSONNode anyNode = JSONNode.get(path);\n  \n  // 通过root方法可以在任何节点回到根节点\n  JSONNode root = anyNode.root();\n  // root == node true\n  \n  // 根据路径局部解析\n  JSONNode propertiesRoot = JSONNode.from(json, \"/properties\");\n  // 局部解析懒加载(一般在获取某个数组的长度或者对象的keys等特别适用)\n  JSONNode propertiesRoot = JSONNode.from(json, \"/properties\", true);\n  propertiesRoot.keyNames();\n  \n  \n  String json2 = `{\n                      \"store\": {\n                        \"book\": [\n                          {\n                            \"category\": \"reference\",\n                            \"author\": \"Nigel Rees\",\n                            \"title\": \"Sayings of the Century\",\n                            \"attr\": {\n                              \"pos\": \"p1\"\n                            },\n                            \"price\": 8.95\n                          },\n                          {\n                            \"category\": \"fiction\",\n                            \"author\": \"Evelyn Waugh\",\n                            \"title\": \"Sword of Honour\",\n                            \"attr\": {\n                              \"pos\": \"p2\"\n                            },\n                            \"price\": 12.99\n                          },\n                          {\n                            \"category\": \"fiction\",\n                            \"author\": \"Herman Melville\",\n                            \"title\": \"Moby Dick\",\n                            \"isbn\": \"0-553-21311-3\",\n                            \"attr\": {\n                              \"pos\": \"p3\"\n                            },\n                            \"price\": 8.99\n                          },\n                          {\n                            \"category\": \"fiction\",\n                            \"author\": \"J. R. R. Tolkien\",\n                            \"title\": \"The Lord of the Rings\",\n                            \"isbn\": \"0-395-19395-8\",\n                            \"attr\": {\n                              \"pos\": \"p4\"\n                            },\n                            \"price\": 22.99\n                          }\n                        ],\n                        \"bicycle\": {\n                          \"color\": \"red\",\n                          \"price\": 19.95\n                        }\n                      },\n                      \"expensive\": 10\n                    }`\n;\n  \n  // 直接提取所有的author使用*\n  List authors = JSONNode.extract(json2, \"/store/book/*/author\");\n  \n  // 提取第2本书的作者author使用指定的下标n\n  String author = JSONNode.extract(json2, \"/store/book/1/author\").get(1);\n  （或者 JSONNode.from(json2, \"/store/book/1/author\").getStringValue();性能大体一致)\n  \n  // 提取前2本书的作者使用下标n-（包含n）\n  List authors = JSONNode.extract(json2, \"/store/book/1-/author\").get(1);\n  \n  // 提取从第2本书开始后面所有的作者使用下标n+（包含n）\n  List authors1 = JSONNode.extract(json2, \"/store/book/1+/author\");\n  \n  // 使用collect可以支持递归过滤\n  List authors2 = JSONNode.collect(json2, \"//book/1+/author\");\n  \n```\n\n### SpringBoot(Spring MVC) 集成\n\nsupports/json-springmvc/JSONHttpMessageConverter.java\n\n```\n  @Configuration\n  public class AppConfiguration implements WebMvcConfigurer {\n \n       @Bean\n       public HttpMessageConverters jsonHttpMessageConverters() {\n           JSONHttpMessageConverter jsonHttpMessageConverter = new JSONHttpMessageConverter();\n           jsonHttpMessageConverter.setWriteOptions(WriteOption... writeOptions);\n           jsonHttpMessageConverter.setReadOptions(ReadOption... readOptions);\n           return new HttpMessageConverters(jsonHttpMessageConverter);\n       }\n \n  }\n```\n\n### 序列化和反序列化支持配置\n\n序列化配置枚举类：WriteOption\n\n| 枚举值  | 说明                                               |\n| ------------ |--------------------------------------------------|\n| FormatOut   | 格式化缩进输出                                          |\n| FormatOutColonSpace   | 格式化缩进支持冒号后面补一个空格更加美观                             |\n| FormatIndentUseTab   | 使用tab符来缩进美化,当FormatOut启用时默认开启使用此模式               |\n| FormatIndentUseSpace   | 使用空格符(4个空格)来缩进美化JSON                             |\n| FormatIndentUseSpace8   | 使用8个空格符代表一个缩进级别进行美化JSON                          |\n| FullProperty   | 输出完整的属性字段                                        |\n| WriteDateAsTime   | 默认将日期格式化输出，配置此项可以序列化为时间戳                         |\n| SkipCircularReference  | 开始后探测序列化是否会存在循环引用造成的死循环                          |\n| BytesArrayToHex   | 默认情况下byte数组会输出为base64字符串，开启配置后将bytes数组输出为16进制字符串 |\n| BytesArrayToNative   | 默认情况下byte数组会输出为base64字符串，开启配置后将bytes数组输出原生字节数组   |\n| SkipGetterOfNoneField   | 是否跳过不存在属性域的getter方法序列化                           |\n| KeepOpenStream   | 序列化后不关闭流，默认自动关闭流，开启后不会调用close                    |\n| AllowUnquotedMapKey   | 默认情况下map的key统一加双引号输出,开启后将根据实际的key值类型序列化          |\n| UseFields   | 默认通过实体类的getter方法序列化，开启后使用field字段进行序列化            |\n\n反序列化配置枚举类：ReadOption\n\n| 枚举值  | 说明                                                                                                              |\n| ------------ |-----------------------------------------------------------------------------------------------------------------|\n| ByteArrayFromHexString   | 目标类型为byte[]，解析到字符串标记时将按16进制字符串转化为byte[]数组(2个字符转化为一个字节)                                                          |\n| AllowComment   | 非标准json特性：允许JSON存在注释，仅仅支持//和/+* *+/，默认关闭注释解析                                                                    |\n| AllowUnquotedFieldNames  | 非标准json特性：允许JSON字段的key没有双引号                                                                                     |\n| AllowSingleQuotes   | 非标准json特性：允许JSON字段的key使用单引号，注意仅仅是key                                                                            |\n| UnknownEnumAsNull   | 不存在的枚举类型解析时默认抛出异常，开启后解析为null                                                                                    |\n| UseDefaultFieldInstance   | 解析实体bean的场景下，如果其属性的类型为普通抽象类或者接口(Map和Collection极其子类接口除外)，如果指定了默认实例将使用默认实例对象,从使用上解决类型映射问题，而不用趟AutoType带来的各种安全漏洞的坑 |\n| UseBigDecimalAsDefaultNumber   | 开启后在不确定number类型情况下，统一转化为BigDecimal；默认自动判断number类型转化为int或long或者double                                            | |\n| AllowLastEndComma   | 支持对象或者数组最后一个属性或者元素后面存在逗号，比如[1,2,3,]开启后也能正常解析                                                                    |\n| UnMatchedEmptyAsNull   | 解析到空字符串但目标类型又不是字符串时，返回null，否则抛出异常                                                                               |\n\n## YAML\n\n```\n    \n    // yaml string\n    String yamlStr = StringUtils.fromResource(\"/yaml/t2.yaml\");\n    \n    // read as doc\n    YamlDocument yamlDoc = YamlDocument.parse(yamlStr);\n    \n    // as properties\n    Properties properties = yamlDoc.toProperties();\n    System.out.println(properties);\n    \n    // to map\n    yamlDoc.toMap();\n    \n    // to bean\n    YamlTest bean = yamlDoc.toEntity(YamlTest.class);\n    \n    // get root\n    YamlNode yamlRoot = yamlDoc.getRoot();\n    \n    // find node\n    YamlNode nameNode = yamlRoot.get(\"/metadata/name\");\n    \n    // get /metadata/name\n    String metadataName = yamlRoot.getPathValue(\"/metadata/name\", String.class);\n    // or nameNode.getValue();\n    System.out.println(\" metadataName \" + metadataName);\n    \n    // update\n    yamlRoot.setPathValue(\"/metadata/name\", \"this is new Value \");\n    \n    String newMetadataName = (String) nameNode.getValue();\n    System.out.println(newMetadataName.equals(\"this is new Value \"));\n    \n    // string\n    System.out.println(yamlDoc.toYamlString());\n    \n    // file\n    yamlDoc.writeTo(new File(\"/tmp/test.yaml\"));\n    \n```\n\n## 表达式引擎\n\n### 1 直接运行模式\n\n```\nExpression.eval(\"1+1\");  // 2\nExpression.eval(\"1+1+'a'\");  // 2a\n\nMap map = new HashMap();\nmap.put(\"a\", 1);\nmap.put(\"b\", 2);\nmap.put(\"c\", 3);\nExpression.eval(\"a+b+c\",map);  // 6\n```\n\n### 2 解析模式\n\n将表达式解析为模型，一般使用在动态表达式场景\n\n```\nMap map = new HashMap();\nmap.put(\"a\", 1);\nmap.put(\"b\", 2);\nmap.put(\"c\", 3);\nExpression varExpr = Expression.parse(\"a + b + c\"); \nvarExpr.evaluate(map);     // 6\n\nmap.put(\"c\", 30);\nvarExpr.evaluate(map);     // 33\n```\n\n### 3 编译模式\n\n使用原生java编译或者javassist（按需加载）将表达式动态编译为java类进行运行。\n\n```\nString el = \"arg.a+arg.b+b+c\";\nCompilerEnvironment compileEnvironment = new CompilerEnvironment();\n\n// 如果设置false会将表达式进行先解析再编译;\n// 如果设置为true将跳过解析在代码中直接return，此时最好使用setVariableType来声明变量类型\n// 不伦是否设置skipParse，使用setVariableType来声明变量类型都是不错的选择，能大大提高效率\ncompileEnvironment.setSkipParse(true);\ncompileEnvironment.setVariableType(int.class, \"arg.a\", \"arg.b\", \"b\", \"c\");\n\n// 输出编译的源代码\nSystem.out.println(CompilerExpression.generateJavaCode(el, compileEnvironment));\nCompilerExpression compiler = CompilerExpression.compile(el, compileEnvironment);\n\n\nMap aa = new HashMap();\naa.put(\"a\", 120);\naa.put(\"b\", 150);\n\nMap var = new HashMap();\nvar.put(\"arg\", aa);\nvar.put(\"b\", 8);\nvar.put(\"c\", 1);\n\n// run\nSystem.out.println(\"==== eval result \" + compiler.evaluate(var));\n\n```\n\n### 4 函数和自定义函数使用\n\n内置函数： max/min/sum/avg/abs/sqrt/lower/upper/size/ifNull/toArray \u003cbr\u003e\n源码见： BuiltInFunction \u003cbr\u003e\n自定义函数可以是全局函数不需要类名作为命名空间，使用@max(@可省略)直接调用，全局函数可以通过两种方式注册：\u003cbr\u003e\n\n```\n // mode 1\n evaluateEnvironment.registerStaticMethods(true, Math.class, String.class);\n // mode 2\n evaluateEnvironment.registerFunction(\"min\", new ExprFunction\u003cObject, Number\u003e() {\n        @Override\n        public Number call(Object... params) {\n        Arrays.sort(params);\n        return (Number) params[params.length - 1];\n        }\n});\n```\n\n也可以是命名空间函数，使用时需要添加类名简称（命名空间）如@Math.max(a,b)\n函数使用@标记+函数名称，此时@不可省略\n\n```\n        Map context = new HashMap();\n        context.put(\"tip\", \"1 \");\n        context.put(\"name\", \"zhangsan, %s\");\n        context.put(\"msg\", \"hello\");\n        context.put(\"type\", 1);\n        context.put(\"a\", 1);\n        context.put(\"b\", 12);\n        context.put(\"c\", 111);\n        context.put(\"B6_AvgCpuUsed\", 1.0);\n        context.put(\"B5_AvgCpuUsed\", 2.0);\n        context.put(\"B4_AvgCpuUsed\", 3.0);\n        context.put(\"vars\", new String[] {\"hello\"});\n        \n        EvaluateEnvironment evaluateEnvironment = EvaluateEnvironment.create(context);\n        evaluateEnvironment.registerStaticMethods(Math.class, String.class);\n\n        evaluateEnvironment.registerFunction(\"min\", new ExprFunction\u003cObject, Number\u003e() {\n            @Override\n            public Number call(Object... params) {\n                // Arrays.sort(params);\n                return (Number) params[params.length - 1];\n            }\n        });\n\n        System.out.println( Expression.eval(\"min(sum(a,b,c), 50, 125, 2, -11)\", evaluateEnvironment));\n        System.out.println( Expression.eval(\"max(sum(a,b,c), 50, 125, 55, 152)\", evaluateEnvironment));\n```\n## JDBC\n\n### 构建执行器\n```\n DefaultSqlExecuter sqlExecuter = new DefaultSqlExecuter();\n```\n\n### 设置数据源\n```\n sqlExecuter.setDataSource(datasource); // \n```\n\n至此可以像JdbcTemplate一样操作数据库了\n\n### 面向sql操作\n\n以下是sqlExecuter常用的api：\n\n```\n// 查询列表(Map)\npublic List\u003cMap\u003e queryList(final String sql, final Object... params);\n\n// 查询列表并将封装到指定类型（E）\npublic \u003cE\u003e List\u003cE\u003e queryList(final String sql, final Class\u003cE\u003e cls, final Object... params);\n\n// 插入操作\npublic Serializable insert(final String sql, final boolean returnGeneratedKeys, final Object... params) ;\n\n// 更新操作\npublic int update(final String sql, final Object... params);\n\n// 执行一个sql语句（包括ddl）\npublic int executeUpdate(final String sql);\n\n// 执行一个脚本（文件，以分号结尾换行的多条sql）\npublic void executeScript(InputStream is) throws IOException;\n\n// 批量操作（使用同一个）\nsqlExecuter.executePipelined(new SqlExecuteCall\u003cObject\u003e() {\n\n    @Override\n    public Object execute(Connection connection) throws SQLException {\n        // 使用原生的jdbc语法操作\n        // 连接在这里不用关闭\n        return null;\n    }\n});\n\n// 分页查询\npublic Page\u003cMap\u003e queryPage(final String sql, long pageNum, int limit, final Object... params);\n// 分页查询转对象\npublic \u003cE\u003e Page\u003cE\u003e queryPage(final String sql, long pageNum, int limit, final Class\u003cE\u003e cls, final Object... params);\n// 根据构造好的page进行分页查询\npublic \u003cE\u003e void queryPage(Page\u003cE\u003e page, final String sql, final Object... params);\n\n```\n\n### 面向模板操作\n\n模板语法和mybatis相似，sql中使用#{}占位替换?,使用${}占位进行值拼接\n\n比如：\n```\nselect * from fact where type = #{type} and name like '%${name}%'\n```\n在运行时将转化为(假设name=test)：\n```\nselect * from fact where type = ? and name like '%test%'\n```\n\n通过sqlExecuter获取模板执行对象(注：sqlExecuter的大部分sql操作的api都有对应的模板api)\n```\nTemplateSqlExecuter templateSqlExecuter = sqlExecuter.getTemplateExecutor();\n\n// 插入对象\nFact fact = new Fact();\nfact.setId(1);\nfact.setName(\"test\");\n\n// 插入\nsqlExecuter.getTemplateExecutor().insert(\"insert into fact(id, name) values(#{id}, #{name})\", fact);\n\n// 查询\nFact f = sqlExecuter.getTemplateExecutor().queryObject(\"select * from fact where id = #{id}\", 1, Fact.class);\n```\n\n### 面向对象操作\n\n使用过jpa(hibernate)或者mybatis-plus的可以很快就上手。\n使用前在前面初始化基础上需要设置实体的扫描包集合\n```\n EntityManagementFactory.defaultManagementFactory().scanPackages(\"com.xxx.entitys\", \"com.xxx.entitys1\");\n```\n\u003e 实体不用继承任何类或实现接口;\u003cbr\u003e\n\u003e 主键通过注解@Id来标识，支持自增（数据库自增策略），算法生成（雪花算法）以及程序代码设置等几种策略;\u003cbr\u003e\n\u003e 其他字段通过注解@Column来映射字段名称，如果没有注解@Column，字段会默认将属性的驼峰格式转为下划线名称作为字段映射;\u003cbr\u003e\n\n获取实体对象操作执行者\n```\nEntityExecuter entityExecuter = sqlExecuter.getEntityExecuter();\n```\n\n实体对象\n```\n@Table(name = \"t_fact\")\npublic class Fact {\n    @Id\n    private String id;\n   \n    @Column\n    private String name;\n    // setter getter 省略\n}\n\n```\n常用的面向对象操作\n```\nFact fact = new Fact();\nfact.setId(1);\nfact.setName(\"test\");\n\n// 插入对象\nentityExecuter.insert(fact);\n\n// 更新对象\nentityExecuter.update(fact);\n\n// 根据主键查询\nFact record = entityExecuter.get(Fact.class, 1);\n\n// 根据主键删除\nentityExecuter.delete(Fact.class, 1);\n\n// 根据条件查询\nFact param = new Fact();\nparam.setId(1);\nList\u003cFact\u003e factList = entityExecuter.queryBy(Fact.class, param)\n\n```\n\n## HttpClient\n\n### 基本使用方法\n\n```\nHttpClient httpClient = HttpClient.create();\n\n// 1 get \nhttpClient.get(\"https://www.xxx.com\", String.class)\n\n// 2 上传 upload\nHttpClientConfig httpClientConfig = new HttpClientConfig();\nhttpClientConfig.setMultipart(true);\nhttpClientConfig.addFileParameter(\"file\", new File(\"/tmp/data.txt\"), null);\nhttpClient.upload(\"https://localhost:8999/\", httpClientConfig);\n\n// 3 下载 download\nHttpClientResponse clientResponse = client.get(\"http://devplatform-service/export/1\");\n\n// attachment;filename=FileName.txt \nString contentDisposition = clientResponse.getHeader(\"content-disposition\");\n\n// 如果知道文件名或者不关心可以跳过上面content-disposition的解析\nString fileName = \"FileName.txt\";\n\n// 文件内容（不适合文件超级大的场景下使用）\nbyte[] content = clientResponse.content();\nFileOutputStream fos = new FileOutputStream(new File(\"/tmp/FileName.txt\"));\nfos.write(content);\nfos.flush();\nfos.close();\n\n```\n\n### nacos集成案例\n\n~~~\nProperties properties = new Properties();\nproperties.put(\"cloud.nacos.server_addr\", \"192.168.1.140:8848\");\nproperties.put(\"cloud.nacos.username\", \"nacos\");\nproperties.put(\"cloud.nacos.password\", \"nacos\");\nproperties.put(\"cloud.nacos.auth.enabled\", \"true\");\nproperties.put(\"cloud.nacos.auth.tokenRefreshInterval\", \"3600\");\nproperties.put(\"cloud.nacos.instance.namespaceId\", \"hlj-cloud-platform\");\nDefaultServiceProvider serviceProvider = new NacosServiceProvider(properties);\nclient.setServiceProvider(serviceProvider);\nclient.setEnableLoadBalance(true);\n\nThread.sleep(2000); \n// 此处devplatform-service为注册在nacos里面的服务名称，如果存在多个实例会进行负载处理\nclient.get(\"http://devplatform-service/dev-platform/\");  \n\n...\n~~~\n\n更多操作可以自行发现。\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwycst%2Fwast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwycst%2Fwast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwycst%2Fwast/lists"}