首页 文章 精选 留言 我的

精选列表

搜索[快速],共10000篇文章
优秀的个人博客,低调大师

JeeSite 平台 Spring Boot 3 体验版发布,一个 Java 快速开发平台

引言 是时候为 Spring Boot 3 做准备了,2018年2月 Spring Boot 进入 2.0 时代,距今已经 5 年了。2022 年 11 月 Spring Boot 3.0 正式发布,它将基于 Spring Framework 6.0,并且需要 Java 17 版本,同时它也将是 Jakarta EE 9 的第一个 Spring Boot 版本。如今 Spring Boot 3.1 已经发布,也带来了非常好的新特性,同时也支持了 Java 20。 为跟近技术时代,周边生态依赖库大部分也对 Spring Boot 3 做了相应支持,所以JeeSite 是时候发布Spring Boot 3 版本了。 同时 JeeSite 对 Spring Boot 2 的版本将持续更新,请大家放心使用。 技术栈 JDK 17+ Servlet 5.0+ Jakarta 6.0.0 Spring Boot 3.1.1 Apache Shiro 2.0.0 Spring Cloud 2022.0.3 Spring Cloud Alibaba 2022.0.0 Spring Framework 6.0.10 OpenAPI 3 and Springdoc 2.0 Atomiko Transactions 6.0 Spring Boot Admin 3.1 Flowable 7.0.0 等等众多依赖更新 Vue分离端 Ant Design Vue 4.0.0 功能国际化语言包完善 等等众多依赖更新 下载地址 JeeSite:https://gitee.com/thinkgem/jeesite4/tree/v5.springboot3/ JeeSite Cloud:https://gitee.com/thinkgem/jeesite4-cloud/tree/v5.springboot3.cloud/ JeeSite Vue:https://gitee.com/thinkgem/jeesite-vue/tree/next/ 我可以升级上来吗? 可以,自JeeSite 4版本开始,JeeSite团队就非常重视从旧版本升级的问题,除了向下兼容,我们也抛弃一些必要的变更。如果你对JeeSite改动不大,业务代码上升级是比较容易的,后面我们将在官方文档补充升级方法。

优秀的个人博客,低调大师

投放视频广告时,如何快速与第三方播放器兼容?

新媒体时代,广告样式越来越丰富。相较于传统的图文信息,视频类广告更具有直观性,能够让消费者在了解产品知识和功能的同时加深对产品的印象。 因此在各类网站或App上投放视频类广告是个很好的宣传方式,但广告商们如果想在网站上展示视频广告,必须确保视频广告投放协议与发布渠道的播放器兼容;如果不能兼容,广告商或者视频广告投放平台必须创建不同的响应,来与特定视频播放器兼容。为此,互联网广告署(IAB)开发了视频广告投放模板 (VAST)这种 XML 模式,允许通过视频广告服务器提供流内视频广告,并在多个网站和设备上的视频播放器中播放,不仅解决兼容性问题,还提高了视频广告投放的效率和可扩展性。 为帮助广告商们更好投放广告,华为鲸鸿动能平台提供了HUAWEI VAST SDK的集成,目前仅支持符合VAST协议的线性广告(投放形式为前、中、后贴片广告)。 开发准备 集成SDK 使用VAST协议时需要集成HUAWEI VAST SDK。同时如果您需要使用默认的播放器,请集成HUAWEI Player SDK。 配置Maven仓地址。 Android Studio的代码库配置在Gradle 插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请根据您当前的Gradle 插件版本,选择对应的配置过程。 以7.0版本为例: a) 打开Android Studio项目级“build.gradle”文件。 b) 添加Maven代码库。 在“buildscript > repositories”中配置Maven仓地址。 buildscript { repositories { google() jcenter() // 配置鲸鸿动能SDK的Maven仓地址 maven {url 'https://developer.huawei.com/repo/'} } } c) 打开项目级“settings.gradle”文件,配置Maven仓地址。 dependencyResolutionManagement { ... repositories { google() jcenter() // 配置鲸鸿动能SDK的Maven仓地址 maven {url 'https://developer.huawei.com/repo/'} } } 配置网络权限 在targetSdkVersion 28及以上的手机上允许HTTP(S)网络请求,在“AndroidManifest.xml”做以下配置。 <application ... android:usesCleartextTraffic="true" > ... </application> 配置混淆脚本 您编译APK前需要配置混淆配置文件,避免混淆HUAWEI VAST SDK导致功能异常。 打开Android工程应用级根目录下的“proguard-rules.pro”混淆配置文件,加入排除HUAWEI VAST SDK的混淆配置。 -keep class com.huawei.openalliance.ad.** { *; } -keep class com.huawei.hms.ads.** { *; } 初始化SDK 初始化HUAWEI VAST SDK 集成HUAWEI VAST SDK后,在应用的DemoApplication类中,初始化HUAWEI VAST SDK。 // 当用户同意广告服务获取数据时,调用下面的方法 SdkFactory.userAcceptAdLicense(true); 开发步骤 实现VAST广告 使用默认播放器播放线性广告 播放线性广告可以使用默认的播放器,也可使用您实现的自定义播放器。 在XML文件中,初始化播放器的布局。示例代码如下: <FrameLayout android:id="@+id/fl_linear_ad" android:layout_width="match_parent" android:layout_height="250dp" android:background="@android:color/black" android:visibility="gone" android:layout_alignParentEnd="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" /> ``` 2. 生成默认的广告播放控制器,注册线性广告视图。示例代码如下: private void registerLinearAdView() { mLinearAdView = findViewById(R.id.fl_linear_ad); mProgressBar = findViewById(R.id.progress); VastAdPlayer.getInstance().registerLinearAdView(mLinearAdView, getController()); } private BaseVideoController getController() { return mAdConfig.isCustomVideoPlayer() ? new DefaultVideoController(this) : new CustomVideoController(this); } 3. 请求播放线性广告。示例代码如下: VastAdPlayer.getInstance().startLinearAd(linearAdSlot, new AdsRequestListener() { @Override public void onSuccess(View view, int responseCode) { } @Override public void onFailed(View view, int responseCode) { } @Override public void playAdReady() { mLinearAdView.setVisibility(View.VISIBLE); } @Override public void playAdFinish() { mLinearAdView.setVisibility(View.INVISIBLE); } @Override public void onBufferStart() { mProgressBar.setVisibility(View.VISIBLE); } @Override public void onBufferEnd() { mProgressBar.setVisibility(View.INVISIBLE); } }); #### 使用自定义播放器播放线性广告 1. 在XML文件中,初始化播放器的布局。示例代码如下: <FrameLayout android:id="@+id/fl_linear_ad" android:layout_width="match_parent" android:layout_height="250dp" android:background="@android:color/black" android:visibility="gone" android:layout_alignParentEnd="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" /> ``` 实现自定义的广告播放器控制器。示例代码如下: public class CustomVideoController extends BaseVideoController implements VastPlayerListener { public CustomVideoController(Context context) { this(context, null); } public CustomVideoController(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomVideoController(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } @Override public int getLayoutId() { return R.layout.activity_video_player; } private void initView(){ ... } } 生成自定义的广告播放器控制器,注册线性广告视图。示例代码如下: private void registerLinearAdView() { mLinearAdView = findViewById(R.id.fl_linear_ad); mProgressBar = findViewById(R.id.progress); VastAdPlayer.getInstance().registerLinearAdView(mLinearAdView, getController()); } private BaseVideoController getController() { return mAdConfig.isCustomVideoPlayer() ? new DefaultVideoController(this) : new CustomVideoController(this); } 请求播放线性广告。示例代码如下: VastAdPlayer.getInstance().startLinearAd(linearAdSlot, new AdsRequestListener() { @Override public void onSuccess(View view, int responseCode) { } @Override public void onFailed(View view, int responseCode) { } @Override public void playAdReady() { mLinearAdView.setVisibility(View.VISIBLE); } @Override public void playAdFinish() { mLinearAdView.setVisibility(View.INVISIBLE); } @Override public void onBufferStart() { mProgressBar.setVisibility(View.VISIBLE); } @Override public void onBufferEnd() { mProgressBar.setVisibility(View.INVISIBLE); } }); 播放广告荚 广告荚的播放与线性广告的播放,只在使用自定义播放器请求播放广告步骤4中有区别,请求播放广告荚的示例代码如下: VastAdPlayer.getInstance().startAdPods(linearAdSlot, new AdsRequestListener() { @Override public void onSuccess(View view, int responseCode) { } @Override public void onFailed(View view, int responseCode) { } @Override public void playAdReady() { mLinearAdView.setVisibility(View.VISIBLE); } @Override public void playAdFinish() { mLinearAdView.setVisibility(View.INVISIBLE); } @Override public void onBufferStart() { mProgressBar.setVisibility(View.VISIBLE); } @Override public void onBufferEnd() { mProgressBar.setVisibility(View.INVISIBLE); } }); 测试VAST广告 您需要使用专门的测试广告位ID来获取测试广告,以避免在测试过程中产生无效的广告点击量。测试广告位ID,仅可用于调测广告功能,不可用于广告变现,在应用正式发布前需替换为正式的广告位ID。您应在应用发布前先进入流量变现官网,点击“开始变现”,登录鲸鸿动能媒体服务平台,申请正式的广告位ID并替换测试广告位ID,具体操作详情请参见展示位创建。以下表格中提供了VAST广告的专用测试广告位ID: 下载VAST广告的示例代码并运行,可以看到如下效果图: 了解更多详情>> 访问华为开发者联盟官网 获取开发指导文档 华为移动服务开源仓库地址:GitHub、Gitee 关注我们,第一时间了解 HMS Core 最新技术资讯~

优秀的个人博客,低调大师

ShopWind V3.4.4 更新,一键采集淘宝天猫京东商品快速迁移

ShopWind 是一款开源多商户电商系统,支持商家入驻开店,可以做社区团购系统,拼团系统,搭建积分商城系统等。展示端有PC电脑端、手机H5端、可发布微信小程序、上架APP安卓端和iOS端、搭建自己的微信公众号号等。各种营销功能完备,可以作为基础源码进行二次开发,减少重复造轮子的烦恼。系统现在已经更新到V3.4.4,从淘宝、京东下来的商家支持一键采集淘宝京东等平台的产品,可以通过ShopWind系统搭建自己的电商系统平台。 官网网址:https://www.shopwind.net 开发文档:https://developer.shopwind.net API 接口文档:http://docs.shopwind.net 开发者社区:https://forum.shopwind.net PC 体验 前台体验:http://test.shopwind.net买家测试账号:buyer 密码:123456 支付密码:123456 后台体验:http://test.shopwind.net/admin平台管理员账号:admin 密码:123456 商家体验:http://test.shopwind.net/seller/login.html商家测试账号:seller 密码:123456 移动端体验(商业版) H5 端体验:https://h5.shopwind.net买家测试账号:18978189192 密码:111111 支付密码:111111 移动端体验 商品采集功能介绍 ShopWind 电商系统在 v3.4.x 版本加入了数据采集功能,支持淘宝、天猫、京东、1688、拼多多商品一键采集到平台的功能,你只需要输入商品详情页链接,就可以批量实现导入,导入的数据包括:商品标题,价格,库存,主图,规格(包括规格图),描述等字段。 一、使用采集功能前,您需要先配置数据采集组件秘钥,秘钥申请:https://www.99api.com/Login?log=5&referee=19843 二、进入商家后台 -》商品管理 -》采集商品 三、输入淘宝京东等商品详情页地址(支持批量),选择数据来源平台后提交 四、导入后如图 3 所示 页面展示 首页 / 用户中心 / 分类页 产品详情 / 购物车 / 下单页 平台后台管理 丰富的功能插件 可视化模板编辑 / DIY 页面布局 更新内容 【新增】数据采集淘宝天猫京东商品模块 【新增】商品长图和主图视频功能 【新增】详情页显示最近买家评价信息 【新增】即时提现到支付宝余额功能 【新增】查看买家评价页 【新增】商品新品标识 【优化】商品规格字段 【优化】移动端支付方式传值 【优化】商品价格货币化显示方式 【优化】在线支付订单不在额外新增财务收支记录 【修复】移动端商品详情页商品属性弹窗显示异常 【修复】商品评价统计数据有误的问题 【修复】优惠券在多个订单可重复使用的问题 【修复】详情页商品规格图显示有误等问题 【修复】退款模块一处错误

优秀的个人博客,低调大师

TLv8 IDE v2.4.3 已经发布,基于 Eclipse 的快速开发工具

TLv8 IDE v2.4.3 已经发布,此版本更新内容包括: 1、Studio透视图默认展示项目资源管理器和包资源管理器; 2、放弃自定义资源视图,直接使用项目资源管理器; 3、补充源码说明; 4、表编辑器增加编辑默认值功能; 5、优化功能树编辑器:添加layui图标属性编辑; 6、解决win10及以下版本无法运行cef的问题(报表编辑器)。 --------------------一些已知bug-------------------

优秀的个人博客,低调大师

太厉害了,通过文档内容快速查找文件,1行Python代码实现

大家好,这里是程序员晚枫。 之前给大家分享了:一行Python代码,如何成为办公小助手?这5个操作,超实用! 1、项目说明 Python是一个非常好用的工具,除了可以用来开发,还可以用于日常生活。 今天给大家分享:通过文件里面的内容,查找文件的存放位置。 你有没有遇到过这种情况:想查找一个文件,但是不记得文件的名字了,只记得文件里的内容? 这种情况下,文件搜索软件也是无能为力的,因为它们只能根据文件名称进行搜索。 今天我们一起用1行Python代码来实现一下。 2、代码实现 ① 安装python-office 安装很简单,在有python环境的电脑上,只需要执行下面这一行命令。 如果你之前使用过python-office这个库,也需要执行一下,可以下载到最新版本~ 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-office -U ② 查找文件的代码 直接上代码! 代码 # 导入这个库:python-office,简写为office import office # 1行代码,实现 office.file.search_by_content(r'你的文件夹,例如:c:\' , content='你需要查找的文件里面的内容') 运行这行代码后,控制栏会出现该路径下,所有包含指定内容的文件存放的位置。 3、关于python-office Python-office 是一个 Python 自动化办公第三方库,能解决大部分自动化办公的问题。而且每个功能只需一行代码,不需要小白用户学习 Python 知识,做到了真正的开箱即用。 🏎项目下载 开源中国 🍺特点 一键搭建所有 Python + 自动化办公的编程环境。 使用一行代码解决大部分自动化办公的问题,不需要小白学习 Python 知识 贴合职场办公需求 极简编程,学习成本极低,工作效率提升显著 4、推荐阅读 用 Python 爬虫,寻找这个夏天最凉快的地方。

优秀的个人博客,低调大师

TLv8 IDE v2.2.1 已经发布,基于 Eclipse 的快速开发工具

TLv8 IDE v2.2.1 已经发布,此版本更新内容包括: 1、解决报表设计器(ureport)兼容问题: Windows系统下使用Edge浏览器内核在win10以下系统不支持,改为chromium存在无法初始化的问题; Linux和macOS下使用swt自带的浏览器。 2、优化页面设计器右键菜单方法; 3、基础插件的jdk兼容到1.6; 4、解决流程设计器model类型转换问题; 5、添加js编辑器功能部件【可选】; 6、解决页面设计器在低版本的Linux系统下无法显示的问题; 7、修改移动版页面设计器资源引用及屏幕适应问题; 8、插件和功能部件重新梳理,按照用途重新组装; 9、修改项目结构,集成了平台必要的插件(tern和chromium-swt); 10、添加【数据库】功能部件描述,数据库插件可以单独安装; 11、补充了各个插件的说明; 12、补充了插件的汉化文件。 ---测试完善v2.2.0修改的内容---

优秀的个人博客,低调大师

通过简单例子 | 快速理清 UML 中类与类的六大关系

类与类之间的六大关系 泛化 ( Generalization ) ---> 表继承关系 实现 ( Realization ) 关联 ( Association ) 聚合 ( Aggregation ) 组合 ( Compostion ) 依赖 ( Dependency ) 前言: 最近学校在上统一建模语言 UML ,也是毕业设计中需要用到,做个小记录。 希望这篇文章能够给大家带来些许收获,让大家趁兴而归。 一、单个类的类图 一步一步来,我们先学学如何使用 UML 图来表示单个类。 我先把类贴下面: package uml; /** * @Author: crush * @Date: 2021-09-30 15:00 * version 1.0 */ public class Person { private String name; private Integer age; private static String school="某小学"; public static String nationality="中国"; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public static String getSchool() { return school; } public static void setSchool(String school) { Person.school = school; } public static String getNationality() { return nationality; } public static void setNationality(String nationality) { Person.nationality = nationality; } public void selfIntroduction(String name, Integer age, String school){ System.out.println("做一个自我介绍,我的名字是:"+name+",今年"+age+"岁了,来自于"+school); } } 这个类还是非常简单的哈,接下来就是要如何用一个类图来进行描述呢? 如下图: 解释: 上半部分是 Person 类的属性,下半部分是 Person 类的方法 - name:String 描述的是:private String name; -号:表示为私有属性( private ),反过来 + :就表示 public name:为属性名称 :xxx :是表示属性的类型的。此处为 String 类型 <u>-School:String="某幼儿园"</u> :描述的是 private static String school="某小学"; <u>下划线</u>是表示此属性为 static(静态属性) "某幼儿园" 表示有默认值。 其他同上。 <u>+ getNationality():String</u> 描述的是 public static void setNationality(String nationality) { Person.nationality = nationality; } 和上面基本一样,+ 表示 public ,下划线表示 static 修饰,getNationality() 表示方法名,String 表示返回值为String类型。 但是平时中,我们通常都是多个类之间有关系,不是个孤零零的孤寡老人。 二、多个类之间的关系 表达多个类之间的关系有以下六种: 泛化 ( Generalization ) ---> 表述继承关系 ( 三角箭头的实线,箭头指向父类 ) 实现 ( Realization ) ( 三角箭头的虚线,箭头指向接口 ) 关联 ( Association ) ( 普通箭头的实心线,指向被拥有者 ) 聚合 ( Aggregation ) ( 空心菱形的实心线,菱形指向整体 ) 组合 ( Compostion ) ( 实心菱形的实线,菱形指向整体) 依赖 ( Dependency ) ( 箭头的虚线,指向被使用者 ) 三、继承和实现的类图 3.1、继承 【泛化关系】:是一种继承关系,表示一般与特殊的关系,它指定了子类如何特化父类的所有特征和行为。例如:老虎是动物的一种,即有老虎的特性也有动物的共性 1)代码 动物类: public class Animal { private String name; private Integer age; public Animal() { } public Animal(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } 猫类继承动物类: public class Cat extends Animal { private String breeds; public Cat(String name, Integer age, String breeds) { super(name, age); this.breeds = breeds; } public String getBreeds() { return breeds; } public void setBreeds(String breeds) { this.breeds = breeds; } public void selfIntroduction(String name,Integer age,String breeds){ System.out.println("我叫"+name+",是一只"+breeds+"品种的猫,今年"+age+"岁了,"); } } 我们用类图来表示这个关系。 4)图示 箭头要用对,不然关系就完全不一样拉。 3.2、实现 【实现关系】:是一种类与接口的关系,表示类是接口所有特征和行为的实现. 1) 代码 吃睡接口,我们再让动物类来实现他两。 public interface Eat { void eat(); } public interface Sleep { void sleep(); } public class Animal implements Eat,Sleep{ private String name; private Integer age; public Animal() { } public Animal(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public void eat() { System.out.println("吃东西"); } @Override public void sleep() { System.out.println("睡觉"); } } 2) 图示 四、关联关系的类图 【关联关系】:是一种拥有的关系,它使一个类知道另一个类的属性和方法;如:老师与学生,丈夫与妻子关联可以是双向的,也可以是单向的。双向的关联可以有两个箭头或者没有箭头,单向的关联有一个箭头。 我们增添一个出身地的类,每个动物都会有一个出生地的地方。 我们将这个出生地和动物关联起来。 4.1、代码 /** * @Author: crush * @Date: 2021-09-30 19:11 * version 1.0 * 出生地 */ public class Birthplace { private String birthplace; public Birthplace(String birthplace) { this.birthplace = birthplace; } public String getBirthplace() { return birthplace; } public void setBirthplace(String birthplace) { this.birthplace = birthplace; } } 与动物类关联起来: public class Animal implements Eat,Sleep{ private String name; private Integer age; private Birthplace birthplace; public Animal() { } public Animal(String name, Integer age, Birthplace birthplace) { this.name = name; this.age = age; this.birthplace = birthplace; } public Birthplace getBirthplace() { return birthplace; } public void setBirthplace(Birthplace birthplace) { this.birthplace = birthplace; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public void eat() { System.out.println("吃东西"); } @Override public void sleep() { System.out.println("睡觉"); } } 在自我介绍方法中增添输出。 public class Cat extends Animal { private String breeds; public Cat(String name, Integer age,Birthplace birthplace, String breeds) { super(name, age,birthplace); this.breeds = breeds; } public String getBreeds() { return breeds; } public void setBreeds(String breeds) { this.breeds = breeds; } public void selfIntroduction(String name,Integer age,String breeds,Birthplace birthplace){ System.out.println("我叫"+name+",是一只"+breeds+"品种的猫,今年"+age+"岁了,出生于"+birthplace.getBirthplace()); } } 4.2、图示 五、聚合和组合关系的类图 5.1、聚合 聚合 ( Aggregation ) : 是整体与部分的关系,且部分可以离开整体而单独存在。如车和轮胎是整体和部分的关系,轮胎离开车仍然可以存在。 聚合关系是关联关系的一种,是强的关联关系;关联和聚合在语法上无法区分,必须考察具体的逻辑关系。 先说说我这个例子,我们再写代码。 【例子】每台车都会有四个轮胎和一个引擎,轮胎离开车可以单独存在的,引擎同样也是。 1)代码 public class Wheel { private String type; public Wheel(String type) { this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } public void move(){ System.out.println("滚动!!!"); } } public class Engine { private String type; public Engine(String type) { this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } public void start(){ System.out.println("启动引擎!!!"); } } public class Car { private Wheel wheel; private Engine engine; public Car(Wheel wheel, Engine engine) { this.wheel = wheel; this.engine = engine; } public Wheel getWheel() { return wheel; } public void setWheel(Wheel wheel) { this.wheel = wheel; } public Engine getEngine() { return engine; } public void setEngine(Engine engine) { this.engine = engine; } public void go(){ System.out.println("开车出去浪;啊"); } } 用类图如何表示勒,接着往下看👇 2)图示 5.2、组合 组合 ( Composition ) : 是整体与部分的关系,但部分不能离开整体而单独存在。如公司和部门是整体和部分的关系,没有公司就不存在部门。还有如人由头和身体组成,没有了人,头和身体还咋存在勒。 组合关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。 1)代码 public class Body { private double size; public Body(double size) { this.size = size; } public double getSize() { return size; } public void setSize(double size) { this.size = size; } } public class Head { private double size; public Head(double size) { this.size = size; } public double getType() { return size; } public void setType(double size) { this.size = size; } } public class Person2 { private String name; private Head head; private Body body; public Person2(String name, Head head, Body body) { this.name = name; this.head = head; this.body = body; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Head getHead() { return head; } public void setHead(Head head) { this.head = head; } public Body getBody() { return body; } public void setBody(Body body) { this.body = body; } public void say(){ System.out.println("我会说话"); } } 2)图示 六、依赖关系的类图 依赖(Dependency): 关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。 在 UML 类图中,依赖关系使用带箭头的虚线来表示,箭头从使用类指向被依赖的类。如人与手机的关系图,人通过手机的语音传送方法打电话。 1、代码 public class Phone { public void callUp(){ System.out.println("与人通话"); } } public class Person3 { private String name; public Person3(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void callUp(Phone phone){ System.out.println("使用手机打电话"); phone.callUp(); } // 下面这种方式也是依赖关系 // public void callUp(){ // Phone phone=new Phone(); // System.out.println("使用手机打电话"); // phone.callUp(); // } } 2、图示 七、类关系的强弱 强弱关系:泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖 另外我们常常说的降低耦合性,也是降低类与类之间的关系。 八、自言自语 今天的文章就到这里了。 如若在文章中遇到疑惑,请留言或私信,或者加主页联系方式,都会尽快回复。 如若发现文章中存在问题,望你能够指正,不胜感谢。 如果觉得对你有所帮助的话,请点个赞再走吧!. 知乎 | 宁在春 简书 | 宁在春 CSDN | 宁在春 掘金 | 宁在春 博客园 | 宁在春

优秀的个人博客,低调大师

开源的傻瓜搜索引擎,帮你快速实现搜索功能

傻瓜一词借鉴自傻瓜相机,又称轻便相机、全自动相机,通常指容易操作针对一般人而设计的小型全自动相机。 在 HelloGitHub 找到有趣、入门级的开源项目,大家好我是卤蛋。说到开源搜索引擎第一个想到的应该是鼎鼎大名的 ElasticSearch,但 ES 对于个人项目有些重。 今天给大家带来一款轻盈、人人都会用的开源傻瓜搜索引擎——MeiliSearch https://github.com/meilisearch/MeiliSearch 在介绍 MeiliSearch 的功能之前,我想先聊下我是怎么找到它并喜欢上它的。 我的要求并不高 我开发的 HelloGitHub 小程序:支持关键字搜索往期月刊中的开源项目。 小程序的搜索功能是用 Rust 写的开源搜索引擎 Sonic,它虽然搜索速度快但使用过程中发现: 不支持中文分词,导致搜索结果较差 没有官方的 Python 客户端,三方开源客户端问题较多 搜索返回的结果仅有 ID,需要再去数据库关联其他数据 这些问题直接影响了搜索的体验,让我十分苦恼一边看搜索相关的知识,另外也在寻找新的开源解决方案。想找一个: 部署+配置简单、支持中文分词、搜索速度快、轻量级开源搜索引擎项目。 俗称:傻瓜中文搜索引擎。 它有个美丽的名字 它有个“美丽”(meili)的名字「MeiliSearch」,同样是用 Rust 写的开源搜索引擎,支持: 概述功能:搜索速度快、全文搜索、支持汉字、容易安装和维护,这不就是我在找的:傻瓜中文搜索引擎吗? 我已经摩拳擦掌的跃跃欲试了,话不多说搞起! 简单的开始 纸上得来终觉浅,得上手试试效果。 1、安装和启动 Linux & Mac OS 的一键安装和启动的命令: curl -L https://install.meilisearch.com | sh ./meilisearch 这个安装够不够傻瓜🤪 启动成功如下图: 用浏览器访问:http://127.0.0.1:7700/ 就可以看到 MeiliSearch 提供的 Web 搜索页面。我提前写入了一些数据,用来演示搜索: 2、基本操作 MeiliSearch 就是一个搜索的服务,提供 RESTful API 通讯协议更加通用,官方提供了多种编程语言的客户端: JavaScript Python PHP Go ... 后面的演示将采用 Python 代码作为示例,安装 Python SDK: # 要求 Python3.6+ pip3/pip install meilisearch 用 Python 实现连接、写入、查询、删除等基本操作: import meilisearch client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey') # masterKey 是密码 # index 相当于数据库的表 index = client.index('books') # 准备写入搜索的数据 documents = [ { 'book_id': 123, 'title': 'Pride and Prejudice' }, { 'book_id': 456, 'title': 'Le Petit Prince' }, { 'book_id': 1, 'title': 'Alice In Wonderland' }, { 'book_id': 1344, 'title': 'The Hobbit' }, { 'book_id': 4, 'title': 'Harry Potter and the Half-Blood Prince' }, { 'book_id': 42, 'title': 'The Hitchhiker\'s Guide to the Galaxy' } ] # 删:清空指定 index index.delete_all_documents() # 写: result = index.add_documents(documents) # 该引擎会根据写入数据 ID 做替换或者新增的操作 # 写入后并不代表搜索引擎处理完成,可以查看返回 updateId 的状态 index.get_update_status(result.get('updateId')) # enqueued, processed or failed 三种状态(processed 代表完成) # 查: index.search('harry pottre') # 结果: # 包含丰富的字段 """ { // 命中的结果 "hits" => [{ "book_id" => 4, "title" => "Harry Potter and the Half-Blood Prince" }], // 页 "offset" => 0, // 每页条数 "limit" => 20, // 处理耗时 "processingTimeMs" => 1, // 查询的内容 "query" => "harry pottre" } """ 至此已经实现了搜索的最基本的功能,但探索不止于此。 3、优化搜索效果 MeiliSearch 可通过配置规则来提高搜索结果: synonyms:同义词 stopWords:停用词(为节省存储空间和提高搜索效率,自动过滤掉某些字或词) rankingRules:排序规则 ... 可以用 Python 客户端更新 MeiliSearch 配置,示例代码: # 停用词 client.index('movies').update_settings({ 'stopWords': [ 'the', 'a', 'an' ], }) # 排序规则 client.index('movies').update_ranking_rules([ "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", "asc(publish_time)", "desc(watch)" ]) # 查看 stop words client.index('movies').get_stop_words() # 重置设置 # index.reset_settings() # 除了搜索其它操作都是异步,会直接返回一个 updateId 需要通过 ID 查询处理状态 # wait_for_pending_update 可阻塞等待处理结果 这些设置可以有效的提高搜索效果,比如使用停用词之前,搜索“开源的书籍”命中不了“开源书籍”,加了停用词即可命中,因为匹配时忽略了输入内容包含的停用词(无用词)。 说一个我遇到的坑,我测试搜索效果时发现:go 搜不到,但是 golang 就可以搜索到,排查了半天最后发现是因为 go 在上面的停用词字典中😅 另外,功能上对比 sonic 没有词联想(suggest),可以通过新建 index+searchableAttributes 实现。 同义词集合我没有找到,如果大家有现成的 中/英文 同义词词典,欢迎留言告诉我~感谢 4、部署 MeiliSearch 部署很简单,增加到系统的 systemd 服务就行了。 cat << EOF > /etc/systemd/system/meilisearch.service [Unit] Description=MeiliSearch After=systemd-user-sessions.service [Service] Type=simple ExecStart=/usr/bin/meilisearch --http-addr 127.0.0.1:7700 --env production --master-key xxxxxx [Install] WantedBy=default.target EOF # Set the service meilisearch systemctl enable meilisearch # Start the meilisearch service systemctl start meilisearch # Verify that the service is actually running systemctl status meilisearch 但部署正式环境,需要注意以下几点: 生产环境必须设置密码,开发环境无强制 生产环境 Web 页面会关闭 没有远程访问和权限控制,可以通过 Nginx 实现 IP 白名单+ Cerbot 实现 HTTPS,提高安全性 可通过 curl 地址 查看服务状态 以上就是我使用 MeiliSearch 的一些心得,总体给我的感觉: 安装简单,没有复杂的配置:省心 数据写入方便,功能丰富:傻瓜 查询快 一条命令即可启动搜索服务,一行代码实现搜索功能,有了它我这个搜索小白都能分分钟实现一个搜索服务,舒服~ 爱的结晶(实战) 我用 MeiliSearch 重写了 HelloGitHub 小程序的搜索功能,后端用的 FastAPI 框架。除此之外还增加了一些新功能: 热门搜索词 项目详情页 项目镜像地址提高访问速度 新的界面 HelloGitHub 小程序第二版效果图如下: 已上线,微信搜:HelloGitHub 小程序,即可使用 后面计划增加:信息流、评论、打分、用户系统、积分系统,因为只有我一个人开发,所以进度会很慢...但我不会半途而废哒 💪 最后 如果说 MeiliSearch 缺点的话,我觉得搜索准确度还有待提高,一方面我需要学习下分词和 NLP 的一些知识,另一方面需要再熟悉下它的 API 和原理,然后再找一些词典辅助,应该能提高准确度,但心急吃不了热豆腐慢慢来吧。 最后,希望本文的分享有帮助到你,今天的文章就到这里了。 优秀的开源项目像散落在海边的贝壳,需要发现它的人。 HelloGitHub 就是拾贝者,找开源项目来 HelloGitHub 就对了! 关注 HelloGitHub 公众号 第一时间收到更新。 还有更多开源项目的介绍和宝藏项目等待你的发现。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册