SpringBoot集成ES實現存儲、查詢
- 2019 年 10 月 5 日
- 筆記
5分鐘_SpringBoot集成ES實現存儲、查詢
當前文章使用ES版本為6.4.3, SpringBoot版本為:2.1.8.RELEASE spring-boot-starter-data-elasticsearch版本為:2.1.8.RELEASE
spring-boot-starter-data-elasticsearch介紹
spring-boot-starter-data-elasticsearch:是springboot整合es的一個快速開發包。用過JPA的朋友應該知道,springdata是通過解析方法名來實現查詢資料庫的。同樣的這個快速開發包也是大大簡化了Java使用es的流程。
ik分詞器
IKAnalyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包。也可以引入其他的中文分詞器,本文使用IK分詞器,注意:IK分詞器的版本號,要與ES的版本一致,如不一致則無法啟動。如果不引入中文分詞器,那麼ES會默認將每一個中文都會進行分詞,不會智慧組詞。
下載地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
源程式碼:https://github.com/medcl/elasticsearch-analysis-ik
搭建springBoot工程
導入依賴
可以在創建工程時候進行選擇web、ES的依賴,也可以手動進行添加。
- 創建工程時候勾選



- 手動添加
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 可以只添加上方兩個依賴即可 推薦添加下方依賴,可以簡化程式碼,不需要在實體類中書寫getter和setter方法。如果idea/eclipse報錯,請安裝lombok插件。 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
編寫配置
application.yml
主要配置ES集群名稱,集群節點。
與es安裝目錄下的config/elasticsearch.yml一致
spring: data: elasticsearch: cluster-name: myes # cluster-nodes: 127.0.0.1:9300 cluster-nodes: hadoop137:9300,hadoop138:9300,hadoop139:9300
編寫程式碼
實體類 TestBean
import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import java.io.Serializable; import java.util.List; import lombok.Data; //通過這個註解,可以不用寫gettersetter方法 @Data //通過這個註解可以聲明一個文檔,指定其所在的索引庫和type @Document(indexName = "testdoct", type = "testbean") public class TestBean implements Serializable { public TestBean() { } public TestBean(long id, String name, Integer age, String sex, String desc) { this.id = id; this.name = name; this.age = age; this.sex = sex; this.desc = desc; } // 必須指定一個id, @Id private long id; // 這裡配置了分詞器,欄位類型,可以不配置,默認也可 @Field(analyzer = "ik_smart", type = FieldType.Text) private String name; private Integer age; @Field(analyzer = "ik_smart", type = FieldType.Text) private String sex; @Field(analyzer = "ik_smart", type = FieldType.Text) private String desc; }
DAO層 TestDao
import org.springframework.data.domain.Page; import org.springframework.data.repository.CrudRepository; import java.util.List; import top.wintp.estestboot.estestboot.bean.TestBean; /** * @author: pyfysf * <p> * @qq: 337081267 * <p> * @CSDN: http://blog.csdn.net/pyfysf * <p> * @blog: http://wintp.top * <p> * @email: [email protected] * <p> * 繼承CRUD,第一個泛型是實體類類型,第二個泛型是id的類型 */ public interface TestDao extends CrudRepository<TestBean, Long> { List<TestBean> findByName(String name); List<TestBean> findByNameOrDesc(String text); }
Service層,TestService (面向介面編程)
import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import java.util.List; import top.wintp.estestboot.estestboot.bean.TestBean; /** * @author: pyfysf * <p> * @qq: 337081267 * <p> * @CSDN: http://blog.csdn.net/pyfysf * <p> * @blog: http://wintp.top * <p> * @email: [email protected] * <p> * @time: 2019/9/17 */ public interface TestService { Iterable<TestBean> findAll(); void save(List<TestBean> list); void save(TestBean bean); List<TestBean> findByName(String text); List<TestBean> findByNameOrDesc(String name,String desc); }
service的實現 TestServiceImpl
import org.apache.poi.ss.usermodel.Sheet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Random; import cn.hutool.core.io.FileUtil; import cn.hutool.poi.excel.BigExcelWriter; import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import top.wintp.estestboot.estestboot.bean.TestBean; import top.wintp.estestboot.estestboot.dao.TestDao; import top.wintp.estestboot.estestboot.service.TestService; /** * @author: pyfysf * <p> * @qq: 337081267 * <p> * @CSDN: http://blog.csdn.net/pyfysf * <p> * @blog: http://wintp.top * <p> * @email: [email protected] * <p> * 添加數據是模擬的 */ @Service public class TestServiceImpl implements TestService { @Autowired TestDao testDao; @Override public Iterable<TestBean> findAll() { return testDao.findAll(); } @Override public void save(List<TestBean> list) { list = new ArrayList<>(); String namess = "帆乘 楷棟 鋒楓 海勇 康帆 安禮 曉平 良帆 瑞翱 濤錕 恆勇 鴻馳 帆強 桓柏 鋒寅 博槐 騫琛 桓釗 傑桓 裕楓 福暉 槐仕 奇鵬 駿偉 允濰 乘初 杞郁 柏安 皓宇 駿俠 禮德 哲曉 偉權 祥恆 澄震 浩浩 瑞權 延升 翱楷 鋒軒 馳鵬 杞翱 康鶴 材福 暉銳 信恆 凱錦 誠翱 震福 龍宇 祥帆 梓瑞 林龍 日延 槐翰 日寅 起鴻 杞允 瑞銳 仕星 權銘 吉楷 寅星 林帝 皓仕 卓禮 家盛 海寅 盛胤 年禧 暢安 炳龍 柏暉 誠年 彬坤 禮誠 濡凱 馳晨 恆邦 帆暉 誠華 暉星 恆梓 祿彬 鶴華 錕升 桓浩 振堯 祥寅 楷辰 暄帝 銳梓 恆佑 文安 傑暢 加琛 俊澤 乘馳 祿家 中鶴 家錦 皓初 凱震 文韋 彬澄 起哲 海炳 鶴鋒 賢逸 哲佑 海信 逸俊 炳年 禮郁 濡寅 曉澤 然延 喆加 天梓 澤錕 軒諦 盛翱 晨子 誠吉 梁鶴 仕逸 昇平 奇琛 杞沛 胤邦 辰佑 騫佳 鴻鵬 翱坤 釗峰 哲銳 騰鑫 海陽 爍奇 安芃 浩瑞 星堯 馳炳 安沛 權成 華文 杞晨 柏柔 權彬 禎晨 諦濰 馳安 安日 谷沛 帆華 林翰 然震 琛星 澤杞 澄濤 龍欣 嘉辰 海祿 誠家 帆韋 澄濡 濰延 郁邦 銳禮 蔓材 暢震 騰誠 峰賢 軒濰 凡信 翱年 祜帆 睿吉 禎博 強延 震鑫 邦郁 禧禎 良梁 爍諦 成震 翱顏 加升 榮俊 晨騫 錦槐 爍安 鑫平 沛凱 德升 炳宇 遠俠 暉鵬 騰谷 初帆 林然 中祿 斌顏 顏浩 遠帆 胤然 祜沛 允錕 暢梁 棟材 澤柔 遠銳 杞梁 凱濡 郁槐 家澤 暄乘 年權 文柏 濰禧 澄禧 奇錦 逸然 翰弘 華海 柏辭 瑞星 胤佑 芃嘉 祜胤 逸傑 傑逸 材龍 允升 加韋 逸福 桓辭 楓濡 信然 棟禎" + "蓓菡 娜嘉 碧珊 菲昕 芸帆 怡莉 鴻蓮 曦靜 靈玥 橘婧 家曼 鶴麗 嵐琳 格梅 呈夢 璇嘉 月欣 楠敏 瑤麗 茹蓮 杉歆 帆珍 琬彬 蓓昭 函璇 凌歡 歆蔚 妮萱 琛靈 婷媛 琳凌 嵐冬 靜鴻 珍倩 桂楓 玉嵐 紫涵 桃婧 芳璟 韻珠 香萱 冰梅 桂寒 呈曼 梅茹 雯帆 芙明 紫桂 霞玲 蓓莉 霞可 琪香 菲春 美俊 夢梔 鶴婧 帛菲 靜芝 琳沛 玥薇 璟漫 弦茹 彥茜 花梓 歆曦 寒潔 莉梓 穎芙 梓露 玉詩 桃橘 鶴霞 沛漫 月婧 玲陽 雅歡 珍月 璟紫 歆淑 韻琬 月玉 歡彥 寒婭 妍彤 夢萱 蕾芳 心彤 彩妮 寒玲 淑漫 茜桐 春楠 洲茜 月嘉 欣雲 珠香 嵐韻 娜呈 妮弦 芸函 芳寒 萱林 雲琳 蓮菡 碧婭 莉凌 梔茜 蔚妮 惠婧 香心 初莉 穎淑 凡芝 璇靈 可蕾 靜文 彩鶴 芙鑫 花楠 雲夢 菲茹 蓓玥 惠婭 凌芳 柔旭 琛楠 雪娜 蕾詩 芸珠 菡桂 蕾文 桃花 彩詩 彬潔 帆馨 雯春 芝韻 春雅 靜紫 寒橘 冰淑 韻露 昭蓮 詩晨 鈺花 彩月 昕歡 香可 菲婧 橘靜 鈺韻 霞心 彬雅 芙春 菲惠 萱曦 惠楓 舒薇 楠麗 梔珍 琳惠 歆冬 漫月 蓮琛 琬梓 雨美 夢家 倩慧 俊薇 彬璇 敏玉 梔曼 曦倩 蓓蔚 月茜 俊珍 茹帆 璐歡 芝珊 昕舒 婭璐 慧玉 春玥 舒靜 穎楠 淑紫 漫彩 歡曼 芳歆 桂冰 芙薇 旭雅 璇冰 嵐欣 嵐玲 慧錦 克霞 萱麗 采碧 潔昭 采彩 珊雲 漫夢 萱凌 怡文 霞杉 敏怡 莉怡 怡露 格漫 瑤薇 沛菲 彥夢 妮馨 菲萱 敏桐 鶴菡 彬蓓 凌彤 珊莉 漫依 琪蓮 欣霞 璟心 梅薇 寒蓓 倩梓 采娜 琬雯 楓梅 花格 馨可 杉璐 舒婭 沛香 穎茹 格玲 花柏 雨璟 欣薇"; String[] names = namess.split("\s+"); String[] descArr = {"大家好,我是雨天,因為剛好出生在雨天,老爸又剛好姓夏,於是「下雨天」就首發出場了,而且媽媽也希望我如雨後春筍、天天向上哦!呵呵後來因為一部分人實在不忍心在晴朗的天氣里叫我雨天,為避免引起「混亂」,就只好捨棄了這個頗有個性的簡單名字,退而成「小名「了。我的大名也簡單,其實就一個「翌」字,因為我出生的日子剛好是爸爸媽媽結婚2周年紀念日的第二日。「夏翌」諧音寧波話「暇意」,大家希望我暇暇意意,呵呵,有點嫌」翌」字太文縐縐,就把它給拆了,一分為二成羽立了。" , "大家都說我是個陽光女孩,因為我是開心果啊。我老是坐不住,呵呵,能跟小椅子成為好朋友,是老師和爸爸媽媽現在的最大心愿。我喜歡跳舞,但最好能跟著音樂自己起舞,不用按老師的要求練基本功;我喜歡畫畫,但最好是信手塗鴉,把小朋友的臉畫成綠色也沒關係;我喜歡溜冰,但最有趣的還是約上三五好友,一起練習如何摔跤……" , "昀昀是我在媽媽肚子里時的小名哦,我的大名叫曹鐵瀛,媽媽懷我的時候和單位里的阿姨們玩牌經常是百戰百勝,阿姨們說是因為我的緣故,乾脆就叫「天贏」好了,爸媽取其諧音,就變成了「鐵瀛」" , "嘿!我——21號來報到了!智誥、誥誥、阿誥,你們愛怎麼叫就怎麼叫吧!反正都是我!我的名字是奶奶請一名先生取的,雖然有點迷信,但寄託了全家人的祝福!" , "還是汽車發燒友,小轎車、大卡車、集裝箱、大客車、翻斗車、壓路機……應有盡有(就差拖拉機還沒有報到)。我常在家練習倒車、移庫、爬坡、過單軌橋,考取駕照不成問題!!當然我也模擬製造幾起車禍,掉進大河,深溝,追尾事故,因為那時我又能大顯身手,汽車的零件裝了又拆,拆了又裝……哈哈!!角角落落都是我的傑作,缺胳膊少腿的,七零八落的,儘管汽車多,可完完整整的沒幾輛!這下,又有理由去買車啦!" , "我還喜歡畫畫。從小我就拿著筆畫一個個的大圓圈,每天樂此不疲,整整畫了半年多圓圈呢!夠有毅力的吧!老師說我構圖線條流暢,就是那樣練出來的哦!以後我一定會繼續努力的!可是我不太喜歡看書,媽媽讓我看書,我老是心不在焉,左顧右盼,常常惹她不高興,可我就是不喜歡嘛!" , "我的性格有點內向、靦腆、不喜歡「顯山露水」。我最喜歡體育項目了,最「痴迷」的就是體育頻道:乒乓球、羽毛球、撞球、足球、籃球、跳水~~,當然我也喜歡打牌(這可是遺傳)。" , "我的個子很高,被稱為「帥哥」,因此彼得女孩子的歡心哦,等我長大了,我要娶七個「老婆」,其中三個為:外婆、爸爸和媽媽。我的目標是考上北大。n" , "我當時的第一反應是:這兩個字可以跟名人的名字做一個聯繫,然後做一個介紹。我說你介紹的時候可以跟別人講:" }; Random random = new Random(); //模擬數據 for (int i = 0; i < 100; i++) { int i1 = random.nextInt(names.length); int i2 = random.nextInt(descArr.length); //注意這裡 第一個參數是id 所以無論你運行多少次,都只會添加100條數據,如果id存在es更新,不存在添加 TestBean testBean = new TestBean(i, names[i1], i, String.valueOf(i % 2), descArr[i2]); list.add(testBean); } testDao.saveAll(list); } @Override public void save(TestBean bean) { testDao.save(bean); } @Override public List<TestBean> findByName(String text) { return testDao.findByName(text); } @Override public List<TestBean> findByNameOrDesc(String text) { return testDao.findByNameOrDesc(text,text); } }
TestController
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; import top.wintp.estestboot.estestboot.bean.TestBean; import top.wintp.estestboot.estestboot.service.TestService; /** * @author: pyfysf * <p> * @qq: 337081267 * <p> * @CSDN: http://blog.csdn.net/pyfysf * <p> * @blog: http://wintp.top * <p> * @email: [email protected] * <p> */ @RestController @RequestMapping("/testes") public class TestController { @Autowired TestService testService; @RequestMapping("findAll") public Iterable<TestBean> findAll() { return testService.findAll(); } @RequestMapping("list") public String save() { List<TestBean> list = null; testService.save(list); return "success"; } @RequestMapping("save") public void save(TestBean bean) { testService.save(bean); } @RequestMapping("findByName") public List<TestBean> findByName(String name) { return testService.findByName(name); } @RequestMapping("findByNameOrDesc") public List<TestBean> findByNameOrDesc(String text) { return testService.findByNameOrDesc(text); } }
測試
啟動程式會自動創建testdoc索引庫
通過kibana查看:

調用項目介面:http://localhost:8080/testes/list

表示添加成功。
可以通過kibana介面查看並搜索數據,也可以直接調用我們自己寫的findAll介面進行查詢。


測試findByName: http://localhost:8080/testes/findByName

測試findByNameOrDesc:http://localhost:8080/testes/findByNameOrDesc?text=浩
查詢名字中或者desc中含有「浩」的數據

結語
這就是SpringBoot集成ES的基本步驟,相比較於自己引入ES的依賴要簡單的很多。如果對你有幫助,請分享出去吧。對於更多的JPA的方法命名規則請查看JPA官方介紹。大致上都和SQL語句差不多。