Phone 设置项中可以模拟来电和短信:From:选择或输入电话号码;CALL DEVICE:点击来电;HOLD CALL:点击保持通话;END CALL:点击结束通话;SMS message:输入模拟消息的正文内容;SEND MESSAGE:点击发送短信。
上述例子发现输出的结果是英文的,显然是不适合在国内环境使用,moment.js 提供了国际化支持,在现有的库中,moment 支持的语言可以说是相对完备了。通过引入对应的国际化资源(语言文件),来切换语言。<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.min.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/locale/zh-cn.min.js"></script><script> var now = moment().calendar(); console.log(now);// 输出当前日历时间 moment().startOf('hour').fromNow(); // 相对这个小时过去了多少分钟 var timestamp = 1593933593236; // 2020年7曰5日下午15点20分38秒 moment(timestamp).fromNow(); // 相对时间戳多久前</script>有关国际化的更多内容可以参考文档。
国际化的功能离不开错误码的支持,客户端指定语言到服务端去请求,当出错了服务端会根据错误码和语言找到对应的国际化提示语。从上面图中我们发现,错误码不仅仅是客户端与服务端的交互,后台各个服务间的交互也需要约定的一套错误码。一般一个系统的错误码 code 都是唯一确定的。msg 不同场景下可能不一样,提供给用户的肯定是需要友好且不能暴露底层细节,给开发人员看的就要详细专业的错误内容。网关服务上面维护着多套不同语言的错误码提示语,响应的时候会根据客户端带的 Lang 信息进行国际化转译。模块模块编码错误编码底层描述中文提示语英文提示语库存10001商品规格表关联有误商品不存在goods don’t exist一般国际化的系统中会有多份 xxx_lang.properties文件,每一份代表一种语言的消息提示语。中文一般会转为 Unicode 编码进行存储(这个过程一般开发工具可以设置自动转),这样的处理可以规避不同开发环境下不同编码导致中文乱码。
其实真实的原因是因为雪碧的英文名字是Sprite,而雪碧图的英文名是CSS Sprites,他俩同样都有Sprite这个词。左边是雪碧在国内的 Logo,右边是国外的 Logo。可以看到本来在没进入中国市场之前人家就叫Sprite(精灵),只不过进入了中国市场之后,中国区的负责人表示:用户去商店买汽水的时候如果对老板说:老板你这里有没有精灵?听起来就会感觉很奇怪,所以咱们不要被Sprite这个单词给限制住了,咱们应该起一个更符合中文语义的名字,于是乎“雪碧”诞生了。而雪碧图在国外叫做 CSS Sprite(CSS精灵)反正 Sprite 在国内被叫雪碧,那干脆不如咱们就叫它雪碧图吧!——来自最先接触到这项技术的人。所以后来接触这项技术的人也就跟随前人一起叫它雪碧图了。
模拟10086来电;gsm call 10086模拟接听来电;gsm accept 10086模拟挂断来电;gsm cancel 10086下面是完整会话示例。pt@Win10-Panda:~$ telnet localhost 5554Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.Android Console: Authentication requiredAndroid Console: type 'auth <auth_token>' to authenticateAndroid Console: you can find your <auth_token> in'C:\Users\panda\.emulator_console_auth_token'OKauth KeGgPVHDN7YifXfZAndroid Console: type 'help' for a list of commandsOKgsm call 10086OKgsm accept 10086OKgsm cancel 10086OK
事件日志中包含屏幕电源状态,其中 0 表示屏幕关闭,1 表示屏幕打开,2 表示已锁屏。日志范例如下:grep screen_toggled bugreport-2015-10-18-16-52-22.txt10-18 15:05:04.383 992 992 I screen_toggled: 110-18 15:05:07.010 992 992 I screen_toggled: 010-18 15:23:15.063 992 992 I screen_toggled: 110-18 15:23:25.684 992 992 I screen_toggled: 010-18 15:36:31.623 992 992 I screen_toggled: 110-18 15:36:37.660 3283 3283 I screen_toggled: 2错误报告中还包含关于唤醒锁的统计信息,唤醒锁是应用开发者采用的一种机制,用于表明其应用需要设备保持开启状态。唤醒锁总时长统计信息仅跟踪唤醒锁实际负责使设备保持唤醒状态的时间,不包括屏幕处于开启状态的时间。此外,如果同时持有多个唤醒锁,系统会在它们之间分配唤醒锁时长。
命令说明gsm {call\accept\cancel\busy} phonenumber模拟电话的呼入、接听、挂断、繁忙。gsm {data\voice} statedata state 命令用于更改 GPRS 数据连接的状态,data voice state 则用于更改 GPRS 语音连接的状态。gsm hold将通话状态更改为 hold。只有在当前状态为 active 或 waiting 时,才能将通话状态更改为 hold。gsm list列出所有呼入电话和外拨电话及其通话状态。gsm status报告当前的 GSM 语音/数据连接状态。相关的值就是前述 voice 和 data 命令的值。
uni-app 的 API 与微信小程序 API 基本一致。掌握微信小程序 API 对后面的开发很有帮助。微信小程序 API 文档:https://developers.weixin.qq.com/miniprogram/dev/api/
模板方法模式是定义一个操作中的算法的骨架,从而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。通常对于一些重要的复杂方法和多个子类共有的方法且逻辑相同的情况下会使用模板方法模式。比如用户第三方用户认证的时候就比较适合使用模板方法。我们来看一个例子:假设我们现在需要用到微信、微博的第三方用户授权来获取用户的信息。//使用模板方法模式描述获取第三方用户信息的过程 public abstract class Authentication{ public void checkUserAuthentication(){ checkIdentity(); fetchInfo(); } protected abstract void checkIdentity(); protected abstract void fetchInfo(); } //微信用户 public class WechatAuthenication extends Authentication{ @Override protected void checkIdentity() { System.out.println("获得微信用户授权"); } @Override protected void fetchInfo() { System.out.println("获取微信用信息"); } } //微信用户 public class WeiboAuthenication extends Authentication{ @Override protected void checkIdentity() { System.out.println("获得微博用户授权"); } @Override protected void fetchInfo() { System.out.println("获取微博用信息"); } } //调用模板方法 public class Demo{ public static void main(String...s){ Authentication auth = new WechatAuthenication(); auth.checkUserAuthentication(); auth = new WeiboAuthenication(); auth.checkUserAuthentication(); } }输出结果:获得微信用户授权 获取微信用信信息 获得微博用户授权 获取微博用信信息现在我们使用 Lambda 表达式换个角度来思考模板方法模式。如果我们用函数式接口来组织模板方法中的调用过程,相比使用继承来构建要显得灵活的多。//定义一个处理接口,用来处理一项事务,如授权或者获取信息。 public interface Processer{ public void process(); } //封装调用过程 public class Authentication{ private final Processer identity; private final Processer userinfo; public Authentication(Criteria identity,Criteria userinfo){ this.identity = identity; this.userinfo = userinfo; } public void checkUserAuthentication(){ identity.process(); userinfo.process(); } } //使用模板方法 public class Demo{ Authentication auth = new Authentication(()->System.out.println("获得微信用户授权"), ()->System.out.println("获取微信用户信息")); auth.checkUserAuthentication(); auth = new Authentication(()->System.out.println("获得微博用户授权"), ()->System.out.println("获取微博用户信息")); auth.checkUserAuthentication(); }输出结果:获得微信用户授权 获取微信用信信息 获得微博用户授权 获取微博用信信息此时,我们的模板方法得到了大幅的简化,同时通过函数接口让模板方法获得了极大的灵活性。
注册微信小程序账号,获取到 AppID,我们后面配置的时候会用到。在 HBuilderX 工具栏,点击发行,选择小程序-微信。输入小程序名称和 AppID,单击发行就可以了。这样我们就会获得一个微信小程序的打包文件,接下来我们来发布微信小程序项目,打开微信小程序开发者工具,导入刚刚生成的微信小程序项目的打包文件,在微信小程序开发者工具中先测试一下,项目运行是否正常,项目测试没有问题后,点击右上角>>按钮,上传代码就可以发布微信小程序了,最后等待微信团队审核通过,别人就可以在线上访问到你的项目了。
数据转换成电信号还是比较简单的,将字符根据指定的编码转换成唯一的二进制编码,然后将二进制的 01 映射成高低电平就可以传输出去了。
通过传输层,建立了数据的传输通道。不同应用有自己不同的会话标识,所以传输过来的数据根据会话标识能够知道跟电脑的哪个应用在通信的。
产生原因:包管理器源在国外,网络不好就很难打开甚至打不开。// 国外的源https://packagecontrol.io/channel_v3.json解决方案:设置国内源,步骤如下:Preferences > Package Settings > Package Control > Settings User,添加如下代码并保存,解决。Tips: 如果你的电脑不能科学上网的话,这一步骤还是比较重要的,原因你懂的!类似 npm,google"channels": [ "http://packagecontrol.cn/channel_v3.json"]
Flask 是一个 Python 实现的 Web 开发微框架,但是这个“微”并不代表着 Flask 功能比较简陋、有所欠缺。微框架中的 “微” 意味着:Flask 旨在保持核心简单而易于扩展;Flask 不会替用户做出太多决策,比如使用何种数据库;Flask 的选项(比如使用何种模板引擎) 通常有多个,用户很容易替换。默认情况下,Flask 不包含数据库抽象层、模板引擎、身份认证或其它任何已有多种库可以胜任的功能,如下图所示。然而,Flask 支持用扩展来给应用添加这些功能,应用程序可以很方便的集成这些扩展。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。
IP 地址,物理地址网站后台访问地址,密码信息家庭成员信息,电话信息生日(很多人的秘密是生日日期)公司信息,同事信息
命令说明power display显示电池和充电器状态。power ac {on\off}将交流电充电状态设为 on 或 off。power status {unknown\charging\discharging\not-charging\full}按照说明更改电池状态。power present {true\false}设置电池存在状态。power health {unknown\good\overheat\dead\overvoltage\failure}设置电池运行状况。power capacity percent将电池剩余电量状态设为 0 到 100 之间的百分比。
pip 工具会从网站自动下载 Python 的第三方模块,提供下载 Python 第三方模块的网站被称为源。默认情况下,pip 从国外网站下载 Python 的第三方模块,速度非常的慢。为了加快下载速度,可以将 pip 的源改为国内的镜像源。国内常用的源如下:源的提供方源的 URL阿里云https://mirrors.aliyun.com/pypi/simple清华https://pypi.tuna.tsinghua.edu.cn/simple中国科技大学https://pypi.mirrors.ustc.edu.cn/simple华中理工大学http://pypi.hustunique.com豆瓣http://pypi.douban.com/simple
浮动面板组,除了上述我们说的之外的所有面板就是浮动面板,所有浮动面板编一个组的话就叫浮动面板组。
Battery 设置中共用4项参数可以调节,模拟设备的电池属性,了解应用在不同条件下的运行情况:Charge level:设置当前电量值,百分比;Charger connection:设置充电器连接状态,是否连接充电器;battery health:设置电池监控状态,正常或者损坏等;Battery status:设置电池状态,正在充电或者已经充满等。
结构体内嵌结构体是用的最多的一种内嵌方式。它有点类似于面向对向语言中的继承,但是面向对象的设计原则中最好不要有多继承。甚至于 java 这个面向对象语言的老大哥,直接就是不允许多继承的。所以 Go 语言中的内嵌结构体更好理解为组合。代码示例:package mainimport "fmt"type Callable struct{}func (c Callable) Call() { fmt.Println("can call")}type Photographic struct{}func (p Photographic) Photograph() { fmt.Println("can take photos")}type Moblie struct { Callable Photographic}type Pad struct { Photographic}func main() { var m Moblie fmt.Println("Moblie Function:") m.Call() m.Photograph() var p Pad fmt.Println("Pad Function:") p.Photograph()}第 5~15 行:定义了两个功能结构体:打电话和拍照;第 17~20 行:用打电话和拍照两个功能结构体,组合成为手机结构体;第 22~24 行:用拍照功能结构体,组合成为平板电脑结构体;第 26~34 行:初始化两个结构体,并打印它们的功能。执行结果:
Python 中比较出名的模板库有 2 个,分别是 Mako 和 Jinja2。下面分别来说一说这两个模板库的用法和一些特点。Mako 是一个高性能的 Python 模板库,它的语法和 API 借鉴了很多其他的模板库,如 Django、Jinja2 等等。它声称有比 Jinja2 更快的解析速度以及更多的语法支持。我们来简单过一遍 Mako 中模板语法并用一个案例进行测试:变量写法:${variable},在花括号中还可以执行一些 Python 的语法,如:${name.upper()} 会将 name 的值转换成大写;注释:单行注释用 ##,多行注释用 <%doc></%doc>;## 两个#号表示单行注释<%doc>多行注释</%doc>if 条件语句:控制结构的语法都是以 % name 开头,以 % end 结尾;% if i == 1: ${i}% endiffor 循环:for 循环的语法是以 % for 开头,以 % endfor 结尾;% for a in [1, 2, 3, 4, 5]: % if a[0] == 1: its one % elif a[0] == 2: two % else: others % endif% endforPython 代码块:Mako 中嵌入 python 代码块时,使用标签 <% 和 %>:<%x=1000y='imooc'z=y.upper()%>${x}${y}${z}接下来,我们用编写简单的 Python 代码测试下前面用的这些模板语法,基于 Mako 模板引擎来将如下的模板文件渲染成完整的内容:## coding=utf-8<html><head></head><style type="text/css"></style><body><h1>${title}</h1>## 打印告警信息 % if has_warn == 'warning': ${warn_msg} % endif ## 打印动物列表 <ul> % for animal in animals: <li>${animal}</li>% endfor </ul> ## 测试 python 代码块<%x='imooc'y=x.upper()%><div>小写:${x}</div><div>大写:${y}</div> </body></html>测试的 Python 代码如下:# 先要安装 mako 模块: pip install mako# 代码文件名为 test_mako.pyfrom mako.template import Templatefrom mako.lookup import TemplateLookuphtml_path = '/root/spyinx'lookup = TemplateLookup( directories=[html_path], output_encoding='utf-8', input_encoding='utf-8', default_filters=['decode.utf8'], encoding_errors='replace')# 文件的全路径为/root/spyinx/index.htmltp = lookup.get_template("/index.html")values = { 'title': '测试模板转换', 'has_warn': 'warning', 'warn_msg': '这是一条告警信息', 'animals': ['狮子', '老虎', '蛇']}print(str(tp.render(**values), encoding="utf-8"))执行的结果如下:(env-3.8.1) [root@server spyinx]# lsindex.html test_mako.py(env-3.8.1) [root@server spyinx]# python test_mako.py <html><head></head><style type="text/css"></style><body><h1>测试模板转换</h1> 这是一条告警信息 <ul> <li>狮子</li> <li>老虎</li> <li>蛇</li></ul> <div>小写:imooc</div><div>大写:IMOOC</div> </body></html>可以看到这里的模板文本已经被 Mako 引擎进行了更新,替换了其中的模板变量,去掉了注释部分,形成了最终的文本。接下来,我们也简单介绍下 Jinja2 模板库,它的用法和 Mako 几乎是类似的,只不过支持的模板语法略有不同。我们会在后面详细介绍 Jinja2,这里简单介绍一些常用的语法并使用 Python 代码进行测试。变量写法:{{ variable }};注释:注释的语句是 {# 注释部分 #};条件语句:条件语句大多使用 if 语句,它也具有单分支,多分支等多种结构。使用时需要以 endif 关键字结尾,而且 if 、elif、else 和 endif 都需要用 {% 和 %} 包裹;{% if spyinx.age < 18 %}spyinx is a minor{% elif spyinx.age > 50 %}spyinx is an old man{% else %}spyinx is an adult{% endif %}循环语句:循环语句大部分使用 for 语句,它的写法如下,和 mako 十分类似,使用 {% 和 %} 包裹循环语句,还需要 {% endfor %} 结尾。{% for animal in animals %}{{ animal }}{% endfor %}除了这些之外,还有过滤器、宏、模板的继承等等各种强大的功能,全方位满足各种场景。这些会留到后面详细介绍,下面来完成一个实验,使用 Jinja2 模板库完成对一个 Jinja2 模板文件的转换:准备好一个模板文件 index.html.j2,内容如下:<html><head></head><style type="text/css"></style><body><h1>{{ title }}</h1>{# 打印告警信息 #}{%- if has_warn == 'warning' -%}{{ warn_msg }}{%- endif -%}{# 打印动物列#}<ul>{%- for animal in animals %} <li>{{ animal }}</li>{%- endfor %}</ul><div>首字母大写:{{ 'imooc' | capitalize }}</div><div>大写:{{ 'imooc' | upper }}</div></body></html>注意:这里使用 {%- 的写法是为了去掉类似 {% if|for|endif|endfor ... %} 这样的语句产生的空格。准备好测试的 python 代码,如下:"""测试 jinja2 模块"""from jinja2 import Environment, FileSystemLoaderdef render_template(path, file_name, vars): env = Environment(loader=FileSystemLoader('./')) # 加载模板 template = env.get_template(file_name) content = template.render(vars) print(content) if __name__ == '__main__': values = { 'title': '测试模板转换', 'has_warn': 'warning', 'warn_msg': '这是一条告警信息', 'animals': ['狮子', '老虎', '蛇'] } render_template('./', 'index.html.j2', values)执行该 python 代码,我们可以得到和前面 Mako 模板库一样的结果:(env-3.8.1) [root@server spyinx]# python test_jinja2.py <html><head></head><style type="text/css"></style><body><h1>测试模板转换</h1>这是一条告警信息<ul> <li>狮子</li> <li>老虎</li> <li>蛇</li></ul> <div>首字母大写:Imooc</div><div>大写:IMOOC</div> </body></html>至此,我们对 Python 中的模板库有了初步的认识,接下来就来看看 Django 中的模板系统,包括如何配置和使用。
可以给用户备注 名称、办公、办公电话、住宅电话,命令如下:su rootchfn user_name01执行结果如下图:
会话工厂的核心作用:建立和数据库系统的连接,创建会话对象。创建时需要依赖 Configuration 组件解析出来的信息。Hiberante 的会话工厂的源代码实现比较复杂,代码具有良好的结构性,会衍生出很多辅助性组件。因为只是说明问题,本文中的工厂仅仅用来创建会话对象,不考虑性能、缓存、事务等各方面问题,也不刻意讲究代码的结构性。简易框架中的会话工厂的代码简单但具有说明力:public class SessionFactory { private Map<String, String> pros; private List<String> mappings; private ThreadLocal<Session> threadLocal; public SessionFactory(Map<String, String> pros, List<String> mappings) { this.pros = pros; this.mappings = mappings; this.threadLocal = new ThreadLocal<Session>(); } public Connection getConn() { String driverClass = this.pros.get("connection.driver_class"); String url = this.pros.get("connection.url"); String userName = this.pros.get("connection.username"); String password = this.pros.get("connection.password"); try { Class.forName(driverClass); return DriverManager.getConnection(url, userName, password); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } return null; } public Session openSession() { return new Session(this.getConn(), this.mappings); } public Session getCurrentSession() { Session session = this.threadLocal.get(); if (session == null) { session = this.openSession(); this.threadLocal.set(session); } return session; }}会话工厂类中有 2 个创建 Session 的方法,一个是普通的创建方法,另一个是从线程上下文中检查是否已经存在 Session 对象。
Nginx 和老大哥 Apache 一样开源且免费。在如今的时代,开源才能有力地成长,免费才能让更多的企业和个人开发者使用。 当然 Nginx 也有它的商业版本 Nginx plus,它有着更为丰富的功能和应用场景。然而免费版本的功能已经足够强大,加上第三方层出不穷的插件模块,几乎能实现各种业务功能,再加上配合第三方的语言集成(perl、lua等),对于绝大多数企业和个人来说已经完全足够。当然,Nginx 的优点绝对不止于此。它最核心地功能是:在支持高并发请求的同时保持高效的服务。而这一点正是广大开发者,也是各大企业迫切需要满足的需求,以应对日益庞大的国内互联网用户群体。
什么是标准?标准是对重复性事物和概念所做的统一规定,他以科学技术和实践经验的结合成果为基础,经有关方面协商一致,由主管机构批准,以特定形式发布作为共同遵守的准则和依据。在这个标准概念大行其道的今天,如果大家在生活中稍微注意一下,其实可以很容易发现,我们生活在一个标准化的世界里,每个产品的外包装或者标签上都会注明相应的执行标准。标准贯穿着我们的衣食住行。。总而言之,标准无处不在。当然标准具有行业性与地域性。每个国家基本都有自己的标准,这些标准有些是自己独立创造的,但更多的,为了与国际上大部分标准兼容,基本上会使用国际上一些通用的标准,只是改一下名字就可以了。作为软件行业中的老大哥级人物。C 语言也有自己的标准,而且是国际标准。如果大家遵循同一个标准,那么就会避免分歧的产生,避免出现很多不必要的麻烦和困扰。按照这统一标准就不会出现不兼容的问题。我们先来看下 C 语言标准的发展历史:
计算机的网络模型定义了计算机数据的传输过程,当前有以下 2 种主流模型:国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为 OSI 参考模型或七层模型;工业生产中实际用到的 TCP/IP 四层模型。这两者者的关系就好比,车间里面一个贴在墙上很规范的流程图,一个是实际生产中因为成本/便捷/效率等因素最终采用的流程。但是不管是七层模型还是四层模型,他们实现的目无非是为了解决两个问题:数据转成电信号;目标主机的寻址。
利用起始模板更快地启动并运行您的网站,您可以通过自定义这些模板来构建 HTML 电子邮件、“关于”页面、博客、电子商务页面、新闻稿和作品集。—Adobe 公司中国区官网这里的意思是说 Dreamweaver 这个软件本身提供了很多“成熟例子”供你选择使用。这些“例子”不但设计成熟,而且能适应你常见的用途,比如网页、博客、电商网站、新闻页面等。这一点好用到甚至你在刚开始学习 Dreamweaver 的时候,就能挥手间创造出市面上很成熟的页面,毕竟 Dreamweaver 自带的模版都是符合当下主流设计风格的网页。
通过配置文件,设置数据源信息。由于我们不再使用默认数据源,所以此处需要指定数据源类型为 DruidDataSource 。实例:# 指定数据源类型spring.datasource.type=com.alibaba.druid.pool.DruidDataSource# 配置数据库驱动spring.datasource.driver-class-name=com.mysql.jdbc.Driver# 配置数据库urlspring.datasource.url=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC# 配置数据库用户名spring.datasource.username=root# 配置数据库密码spring.datasource.password=Easy@0122
模板在生活中也是非常常见的,比如我们上学时向老师请假,会有请假条的模板,只需在请假条模板中填写请假人以及请假原因就可以。HTML 的模板也是如此,只不过我们会有特殊的语法来完成一个模板,接下来会有对应的模板引擎来帮我们将传入的数据和模板中变量进行一一对应并最终形成一个完整的 HTML 文件。例如下面的一个最简单的模板文件:<html><head></head><style type="text/css"></style><body><h1>{{ title }}</h1></body></html>这个简单的模板中,我们只有一个模板变量 title,用 {{ 和 }} 括起来。模板引擎会对这些变量进行数据替换,比如传入数据 {'title':'标题1'},那么模板引擎就会将 {{ title }} 直接替换成 标题1 字符串。不同的模板引擎支持不同的语法格式。在 Django 中应用最为广泛的模板引擎当属 Jinja2 了,当然它也是 Flask 框架默认使用的模板系统。
我们只需要通过配置文件指定数据源信息, Spring Boot 就可以识别配置,并加载到数据源组件中。 JdbcTemplate 也可以自动识别该数据源,从而实现对数据库的操作。配置文件信息如下:实例:# 配置数据库驱动spring.datasource.driver-class-name=com.mysql.jdbc.Driver# 配置数据库urlspring.datasource.url=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8# 配置数据库用户名spring.datasource.username=root# 配置数据库密码spring.datasource.password=123456需要注意的是,我们在 URL 配置中指定了编码方式,这样可以防止出现数据库中文乱码情况。同时指定了时区为北京时间所在的东八区(GMT%2B8),避免因时区问题导致错误。此时再次启动 Spring Boot 应用,正常运行,说明我们的数据源配置生效了。