golang 常用函数

1. 获取当前时间 时间戳(秒):time.Now().Unix 日期:time.Now().Format("2006-01-02 15:04:05") 注意:参数必须是 2006-01-02 15:04:05 而不能是自定义的年月日时间 2. 字符串与int转换 i,_ := strconv.Atoi("3") a := strconv.Itoa(32) 3.结构体json序列化 chatMsg := &ChatMsg{} err := json.Unmarshal([]byte(msg), chatMsg) //json转结构体 buf, _ := json.Marshal(chatMsg) //结构体转json return string(buf) 4.删除切片元素 mySlice := make([]int, 5) //创建一个初始元素个数为5的数组切片,元素初始值为0 mySlice = append(mySlice[:i], mySlice[i+1:]...) //删除下标为i的元素 mySlice = append(mySlice[:0], mySlice[1:]...) //删除第1个元素 5. url encode/decode encodeUrl:= url.QueryEscape(urltest) decodeUrl,err := url.QueryUnescape(encodeUrl) 6. base64编码 encodeString := base64.StdEncoding.EncodeToString(input) decodeBytes, err := base64.StdEncoding.DecodeString(encodeString) 7. 获取字符串长度 tips := "忍者" len := len(tips) //len=6 len := utf8.RuneCountInString(tips) //len=2 8. SubString func SubString(str string, start int32, end int32) string { result := []rune(str) length := int32(len(result)) if start < 0 || start > length { return str } if end < 0 || end > length { return str } return string(result[start:end]) } result = SubString(result, 0, int32(len([]rune(result)))-1)//注意end参数的取值 9....

October 10, 2020

mybatis 增加自定义拦截器

MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。 拦截器 import java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Properties; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.type.TypeHandlerRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }), @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) }) public class MybatisInterceptor implements Interceptor { private static final Logger log = LoggerFactory.getLogger(MybatisInterceptor.class); @Override public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation....

September 27, 2020

搜索引擎 及 elastic search

搜索引擎是对数据的检索,所以我们先从生活中的数据说起。我们生活中的数据总体分为两种: 结构化数据 非结构化数据 **结构化数据:**也称作行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。指具有固定格式或有限长度的数据,如数据库,元数据等。 **非结构化数据:**又可称为全文数据,不定长或无固定格式,不适于由数据库二维表来表现,包括所有格式的办公文档、XML、HTML、Word 文档,邮件,各类报表、图片和咅频、视频信息等。 **说明:**如果要更细致的区分的话,XML、HTML 可划分为半结构化数据。因为它们也具有自己特定的标签格式,所以既可以根据需要按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。 根据两种数据分类,搜索也相应的分为两种: 结构化数据搜索 非结构化数据搜索 **对于结构化数据,**因为它们具有特定的结构,所以我们一般都是可以通过关系型数据库(MySQL,Oracle 等)的二维表(Table)的方式存储和搜索,也可以建立索引。 对于非结构化数据,也即对全文数据的搜索主要有两种方法: 顺序扫描 全文检索 **顺序扫描:**通过文字名称也可了解到它的大概搜索方式,即按照顺序扫描的方式查询特定的关键字。 例如给你一张报纸,让你找到该报纸中“平安”的文字在哪些地方出现过。你肯定需要从头到尾把报纸阅读扫描一遍然后标记出关键字在哪些版块出现过以及它的出现位置。 这种方式无疑是最耗时的最低效的,如果报纸排版字体小,而且版块较多甚至有多份报纸,等你扫描完你的眼睛也差不多了。 **全文搜索:**对非结构化数据顺序扫描很慢,我们是否可以进行优化?把我们的非结构化数据想办法弄得有一定结构不就行了吗? 将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。 这种方式就构成了全文检索的基本思路。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之为索引。 这种方式的主要工作量在前期索引的创建,但是对于后期搜索却是快速高效的。 先说说 Lucene 通过对生活中数据的类型作了一个简短了解之后,我们知道关系型数据库的 SQL 检索是处理不了这种非结构化数据的。 这种非结构化数据的处理需要依赖全文搜索,而目前市场上开放源代码的最好全文检索引擎工具包就属于 Apache 的 Lucene了。 但是 Lucene 只是一个工具包,它不是一个完整的全文检索引擎。Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。 目前以 Lucene 为基础建立的开源可用全文搜索引擎主要是 Solr 和 Elasticsearch。 Solr 和 Elasticsearch 都是比较成熟的全文搜索引擎,能完成的功能和性能也基本一样。 但是 ES 本身就具有分布式的特性和易安装使用的特点,而 Solr 的分布式需要借助第三方来实现,例如通过使用 ZooKeeper 来达到分布式协调管理。 不管是 Solr 还是 Elasticsearch 底层都是依赖于 Lucene,而 Lucene 能实现全文搜索主要是因为它实现了倒排索引的查询结构。 如何理解倒排索引呢?假如现有三份数据文档,文档的内容如下分别是: Java is the best programming language. PHP is the best programming language. Javascript is the best programming language. 为了创建倒排索引,我们通过分词器将每个文档的内容域拆分成单独的词(我们称它为词条或 Term),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。 结果如下所示: Term Doc_1 Doc_2 Doc_3 ------------------------------------- Java | X | | is | X | X | X the | X | X | X best | X | X | X programming | x | X | X language | X | X | X PHP | | X | Javascript | | | X ------------------------------------- 这种结构由文档中所有不重复词的列表构成,对于其中每个词都有一个文档列表与之关联。...

September 23, 2020

https 原理简介

HTTPS 的整个通信过程可以分为两大阶段:证书验证和数据传输阶段,数据传输阶段又可以分为非对称加密和对称加密两个阶段。具体流程按图中的序号讲解。 客户端请求 HTTPS 网址,然后连接到 server 的 443 端口 (HTTPS 默认端口,类似于 HTTP 的80端口)。 采用 HTTPS 协议的服务器必须要有一套数字 CA (Certification Authority)证书,证书是需要申请的,并由专门的数字证书认证机构(CA)通过非常严格的审核之后颁发的电子证书 (当然了是要钱的,安全级别越高价格越贵)。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被篡改。 服务器响应客户端请求,将证书传递给客户端,证书包含公钥和大量其他信息,比如证书颁发机构信息,公司信息和证书有效期等。Chrome 浏览器点击地址栏的锁标志再点击证书就可以看到证书详细信息。 客户端解析证书并对其进行验证。如果证书不是可信机构颁布,或者证书中的域名与实际域名不一致,或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥A。然后客户端还会生成一个随机码 KEY,并使用公钥A将其加密。 客户端把加密后的随机码 KEY 发送给服务器,作为后面对称加密的密钥。 服务器在收到随机码 KEY 之后会使用私钥B将其解密。经过以上这些步骤,客户端和服务器终于建立了安全连接,完美解决了对称加密的密钥泄露问题,接下来就可以用对称加密愉快地进行通信了。 服务器使用密钥 (随机码 KEY)对数据进行对称加密并发送给客户端,客户端使用相同的密钥 (随机码 KEY)解密数据。 双方使用对称加密愉快地传输所有数据。

September 23, 2020

golang 计算文件和字符串的 md5 值

go MD5 所需要的包在”crypto/md5”包中,需要先实例化一个MD5对象,然后在此基础上调用sum方法即可 文件的MD5 md5 := md5.New() io.Copy(md5,file) MD5Str := hex.EncodeToString(md5.Sum(nil)) 上面的代码实现了计算了文件MD5,其中file是multipart.File类型的,也可以是其他的已打开的其他文件类型。 当然也可以不使用io.copy,而是直接使用sum函数来计算: md5 := md5.New() MD5Str := hex.EncodeToString(md5.Sum(file)) 这样是直接调用了sum函数来计算文件的值可能要比io.copy稍微慢一些。 字符串的MD5 有时候需要将已知的一段字符串加密,其实和文件加密大概是类似的,只需要调用write方法将字符串写入hash中: md5 := md5.New() md5.Write([]byte("hello,world!")) MD5Str := hex.EncodeToString(md5.Sum(nil))

September 19, 2020

S3协议

S3是Simple Storage Service的缩写,即简单存储服务。亚马逊的名词缩写也都遵循这个习惯,例如Elastic Compute Cloud缩写为EC2等等。 S3说的玄乎一点可以叫云存储,通俗一点就是大网盘。其概念类似于分布式文家系统,同Google的GFS应该在一个层面。 目前的阿里的oss,腾讯的cos,七牛云存储都兼容aws的S3,所以要更换这些服务商之间提供的云存储非常容易,只需要简单的修改Access Key, Secrect Key等就行。 S3的定义如下 Amazon S3 is a web service that enables you to store data in the cloud. You can then download the data or use the data with other AWS services, such as Amazon Elastic Cloud Computer (EC2). 看来除了做网盘只用,S3存储的数据还可以被其他的亚马逊高层服务直接引用,这一点比国内的简单的网盘提供商高不少,亚马逊大网盘是其整体Solution中的有机组成部分。 基本概念 1. bucket – 类比于文件系统的目录 A bucket is a Container for objects stored in Amazon S3. Every object is contained in a bucket. For example, if the object named photos/puppy.jpg is stored in the johnsmith bucket, then it is addressable using the URL http://johnsmith.s3.amazonaws.com/photos/puppy.jpg 似乎目录不能嵌套,也就是不能有子目录,官方的说法是起到namespace的作用,是访问控制的基本单位,其实丫还是个目录。 2. Object – 类比文件系统的文件 对象中带有对象名名,对象属性,对象本身最大5G,其实也还是个文件。 目前object有Versioning的属性(即对象不同历史版本的cache概念),这个是文件系统不具备的,在早期看到的S3资料中没有这一概念,应该是演进的结果,其面对的应该是有版本控制的需求的用户。 3. Keys – 类比文件名 key的样式也是URL,记住亚马逊的服务都是使用Web Service或REST方式访问的。...

September 18, 2020

golang 判断目录或文件是否存在

golang 判断目录或文件是否存在: func Exist(path string) bool { _, err := os.Stat(path) return err == nil || os.IsExist(err) }

September 17, 2020

beego bee 工具使用简介

bee 工具是一个为了协助快速开发 beego 项目而创建的项目,通过 bee 您可以很容易的进行 beego 项目的创建、热编译、开发、测试、和部署。 bee 工具的安装 您可以通过如下的方式安装 bee 工具: go get github.com/beego/bee 安装完之后,bee 可执行文件默认存放在 $GOPATH/bin 里面,所以您需要把 $GOPATH/bin 添加到您的环境变量中,才可以进行下一步。 如何添加环境变量,请自行搜索 如果你本机设置了 GOBIN,那么上面的命令就会安装到 GOBIN 下,请添加 GOBIN 到你的环境变量中 bee 工具命令详解 我们在命令行输入 bee,可以看到如下的信息: Bee is a Fast and Flexible tool for managing your Beego Web Application. Usage: bee command [arguments] The commands are: version show the bee & beego version migrate run database migrations api create an api application base on beego framework bale packs non-Go files to Go source files new create an application base on beego framework run run the app which can hot compile pack compress an beego project fix Fixes your application by making it compatible with newer versions of Beego dlv Start a debugging session using Delve dockerize Generates a Dockerfile for your Beego application generate Source code generator hprose Creates an RPC application based on Hprose and Beego frameworks pack Compresses a Beego application into a single file rs Run customized scripts run Run the application by starting a local development server server serving static content over HTTP on port Use bee help [command] for more information about a command....

September 16, 2020

beego 日志配置

beego logs 的设计思路来自于 database/sql,目前支持的引擎有 file、console、net、smtp,可以通过如下方式进行安装: go get github.com/astaxie/beego/logs 如何使用 通用方式 首先引入包: import ( "github.com/astaxie/beego/logs" ) 然后添加输出引擎(log 支持同时输出到多个引擎),这里我们以 console 为例,第一个参数是引擎名(包括:console、file、conn、smtp、es、multifile) logs.SetLogger("console") 添加输出引擎也支持第二个参数,用来表示配置信息,详细的配置请看下面介绍: logs.SetLogger(logs.AdapterFile,`{"filename":"project.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`) 然后我们就可以在我们的逻辑中开始任意的使用了: package main import ( "github.com/astaxie/beego/logs" ) func main() { //an official log.Logger l := logs.GetLogger() l.Println("this is a message of http") //an official log.Logger with prefix ORM logs.GetLogger("ORM").Println("this is a message of orm") logs.Debug("my book is bought in the year of ", 2016) logs.Info("this %s cat is %v years old", "yellow", 3) logs.Warn("json is a type of kv like", map[string]int{"key": 2016}) logs.Error(1024, "is a very", "good game") logs.Critical("oh,crash") } 多个实例 一般推荐使用通用方式进行日志,但依然支持单独声明来使用独立的日志 package main import ( "github.com/astaxie/beego/logs" ) func main() { log := logs....

September 16, 2020

beego 日志处理

beego 的日志处理是基于 logs 模块搭建的,内置了一个变量 BeeLogger,默认已经是 logs.BeeLogger 类型,初始化了 console,也就是默认输出到 console。 使用入门 一般在程序中我们使用如下的方式进行输出: beego.Emergency("this is emergency") beego.Alert("this is alert") beego.Critical("this is critical") beego.Error("this is error") beego.Warning("this is warning") beego.Notice("this is notice") beego.Informational("this is informational") beego.Debug("this is debug") 设置输出 我们的程序往往期望把信息输出到 log 中,现在设置输出到文件很方便,如下所示: beego.SetLogger("file", `{"filename":"logs/test.log"}`) 更多详细的日志配置请查看 beego 日志配置 这个默认情况就会同时输出到两个地方,一个 console,一个 file,如果只想输出到文件,就需要调用删除操作: beego.BeeLogger.DelLogger("console") 设置级别 日志的级别如上所示的代码这样分为八个级别: LevelEmergency LevelAlert LevelCritical LevelError LevelWarning LevelNotice LevelInformational LevelDebug 级别依次降低,默认全部打印,但是一般我们在部署环境,可以通过设置级别设置日志级别: beego.SetLevel(beego.LevelInformational) 输出文件名和行号 日志默认不输出调用的文件名和文件行号,如果你期望输出调用的文件名和文件行号,可以如下设置 beego.SetLogFuncCall(true) 开启传入参数 true, 关闭传入参数 false, 默认是关闭的. 完整示例 func internalCalculationFunc(x, y int) (result int, err error) { beego.Debug("calculating z. x:", x, " y:", y) z := y switch { case x == 3: beego.Debug("x == 3") panic("Failure.") case y == 1: beego....

September 16, 2020