рдЖрдЬ, рдХрдИ рд▓реЛрдЧ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдВрдЯрд░рдкреНрд░рд╛рдЗрдЬрд╝ рдЬрд╛рд╡рд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рджреМрд░рд╛рди, рдХрд╛рд░реНрдп рдЕрдХреНрд╕рд░ рднрд┐рдиреНрдирддрд╛ рдХреЗ рдЦреЛрдЬ рдЗрдВрдЬрди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдПрдХ рдРрд╕реА рдкреНрд░рдгрд╛рд▓реА рд╡рд┐рдХрд╕рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдФрд░ рдкреБрд╕реНрддрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреА рд╣реИ, рддреЛ рдЬрд▓реНрджреА рдпрд╛ рдмрд╛рдж рдореЗрдВ рдЗрд╕реЗ рдкреБрд╕реНрддрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдирд╛рдо / рдПрдиреЛрдЯреЗрд╢рди рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо / рдЙрдкрдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред

рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ, рдореИрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдЙрди рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ рдЬреЛ рдРрд╕реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдлрд┐рд░ рдореИрдВ рдПрдХ рдЦреЛрдЬ рд╕реЗрд╡рд╛ рдХрд╛ рдПрдХ рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкреЗрд╢ рдХрд░реВрдВрдЧрд╛, рдЬрд╣рд╛рдВ рдПрдХ рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рдЬрдЯрд┐рд▓ рд╕реБрд╡рд┐рдзрд╛ рд▓рд╛рдЧреВ рдХреА рдЧрдИ рд╣реИ - рд╕рдВрд╕реНрдерд╛рдУрдВ, рдбреАрдмреА рдФрд░ рдЦреЛрдЬ рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рдиред рдЗрд╕ рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдЦреЛрдЬ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдкреВрд░реНрдг-рдкрд╛рда рдЕрдиреБрдХреНрд░рдорд┐рдд рд╕реЛрд▓, рд▓реНрдпреВрд╕рд┐рди, рдЗрд▓рд╛рд╕реНрдЯрд┐рдХрд╕рд░реНрдЪ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ред
рдЦреЛрдЬ рдЗрдВрдЬрдиреЛрдВ рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреЗ рдФрдЬрд╛рд░реЛрдВ рдореЗрдВ, рдореИрдВ рддреАрди рдХреЛ рдмрд╛рд╣рд░ рдХрд░реВрдВрдЧрд╛ред
рд▓реНрдпреВрд╕реАрди рдПрдХ рдЬрд╛рд╡рд╛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ рдЬреЛ рдПрдХ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп, рдкреВрд░реНрдг-рдкрд╛рда рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдЕрд╕рдорд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреА рдорджрдж рд╕реЗ, рдЖрдк рдЕрдиреБрдХреНрд░рдорд┐рдд рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд░рд┐рдХреЙрд░реНрдб (рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ) рд╕реЗ рднрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реНрдпреВрд╕рд┐рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдпрд╣рд╛рдБ рдФрд░ рдкрдврд╝реЗрдВред
рд╕реЛрд▓ рдкрд░рдо рд▓реНрдпреВрд╕рд┐рди-рдЖрдзрд╛рд░рд┐рдд рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдЙрддреНрдкрд╛рдж, рдПрдХ рдкреВрд░реНрдг-рдкрд╛рда рдбреЗрдЯрд╛рдмреЗрд╕, рдПрдХ рд╕реНрдЯреИрдВрдб-рдЕрд▓реЛрди рдЕрд▓рдЧ рд╡реЗрдм рд╕рд░реНрд╡рд░ рд╣реИред рдЗрд╕рдореЗрдВ рдЕрдиреБрдХреНрд░рдордг рдФрд░ рдкреВрд░реНрдг-рдкрд╛рда рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ http-рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ, рдпрд╣ рдЖрдкрдХреЛ рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдХреЛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЦреЛрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╕реЛрд▓рд░ рдореЗрдВ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрдкреАрдЖрдИ рдФрд░ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдпреВрдЖрдИ рд╣реИ, рдЬреЛ рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рдореИрдиреБрдЕрд▓ рд╣реЗрд░рдлреЗрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред Habr├й рдкрд░ Solr рдФрд░ Lucene рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛
рддреБрд▓рдирд╛рддреНрдордХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдерд╛ред
рдЗрд▓рд╛рд╕реНрдЯрд┐рдХрд╕рд░реНрдЪ рд╕реЛрд▓рд░ рдХрд╛ рдПрдХ рдЕрдзрд┐рдХ рдЖрдзреБрдирд┐рдХ рдПрдирд╛рд▓реЙрдЧ рд╣реИред рдпрд╣ Apache Lucene рдкрд░ рднреА рдЖрдзрд╛рд░рд┐рдд рд╣реИред Solr рдХреА рддреБрд▓рдирд╛ рдореЗрдВ, ElasticSearch рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░рддреЗ рд╕рдордп рдЙрдЪреНрдЪ рднрд╛рд░ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдиреЗрдЯ рдкрд░ рдЖрдк Solr рдФрд░ ElasticSearch рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рд╡рд┐рд╕реНрддреГрдд
рддрд╛рд▓рд┐рдХрд╛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдПрдХ рдкреВрд░реА рд╕реВрдЪреА рдирд╣реАрдВ рд╣реИ; рдКрдкрд░, рдореИрдВрдиреЗ рдХреЗрд╡рд▓ рдЙрди рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЛ рдЪреБрдирд╛ рдЬреЛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИрдВред рдЦреЛрдЬ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рд┐рд╕реНрдЯрдо рд╣реИрдВред PostgreSQL рдореЗрдВ рдкреВрд░реНрдг-рдкрд╛рда рдЦреЛрдЬ рдХреНрд╖рдорддрд╛рдПрдВ рд╣реИрдВ; рд╕реНрдлрд┐рдВрдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛ред
рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рд╣реИ
рд╣рдо рдореБрдЦреНрдп рдЪреАрдЬ рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реИрдВред рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп / рд╕реБрд╕рдВрдЧрдд рдбреЗрдЯрд╛ рднрдВрдбрд╛рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрд░рдбреАрдмреА (рд╕рдВрдмрдВрдзрдкрд░рдХ рдбреЗрдЯрд╛рдмреЗрд╕) рдХрд╛ рдЖрдорддреМрд░ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ ACID рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд▓реЗрди-рджреЗрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЦреЛрдЬ рдЗрдВрдЬрди рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЗрдВрдбреЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдВрд╕реНрдерд╛рдУрдВ рдФрд░ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рдирдХреЗ рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬ рдХреА рдЬрд╛рдПрдЧреАред рдпрд╣реА рд╣реИ, рдЬрдм рдПрдХ рдирдИ рд╡рд╕реНрддреБ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреА рд╣реИ, рддреЛ рдЗрд╕реЗ рд░рд┐рд▓реЗрд╢рдирд▓ рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдкреВрд░реНрдг-рдкрд╛рда рдЗрдВрдбреЗрдХреНрд╕ рджреЛрдиреЛрдВ рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдпрджрд┐ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рднреАрддрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рд▓реЗрди-рджреЗрди рдХреА рдкреНрд░рдХреГрддрд┐ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ, рддреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдбрд┐рд╕рд┐рдиреНрдХреНрд░рд┐рдиреЗрд╢рди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдХрд┐рд╕реА рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдСрдмреНрдЬреЗрдХреНрдЯ рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рдирд╣реАрдВ рд╣реИред рдпрд╛ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд: рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рдПрдХ рд╡рд╕реНрддреБ рд░рд┐рдХреЙрд░реНрдб рд╣реИ, рдФрд░ рдЗрд╕реЗ рдЖрд░рдбреАрдмреА рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВред рдЖрдк JTA рдФрд░
рд╕реНрдкреНрд░рд┐рдВрдЧ рдЯреНрд░рд╛рдВрдЬреИрдХреНрд╢рди рдореИрдиреЗрдЬрдореЗрдВрдЯ рдореИрдХреЗрдирд┐рдЬреНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЯреНрд░рд╛рдВрдЬреЗрдХреНрд╢рдирд▓ рдмрджрд▓рд╛рд╡ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╛ рдЖрдк рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рддрд░реАрдХреЗ рд╕реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ - рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЬреЛ рдпрд╣ рд╕рдм рдЕрдкрдиреЗ рдЖрдк рд╕реЗ рдХрд░реЗрдЧрд╛ред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рд▓реНрдпреВрд╕реАрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдЕрдВрджрд░ рдЗрдВрдбреЗрдХреНрд╕ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЗрдВрдбреЗрдХреНрд╕ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм рд╕рд┐рд╕реНрдЯрдо рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЖрдк рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд╡рд┐рдзрд┐ startAndWait () рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рд╕рд┐рд╕реНрдЯрдо рдЪрд▓ рд░рд╣рд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд░рд┐рдХреЙрд░реНрдб RDB рдФрд░ рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред
рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдЦреЛрдЬ рдХреЗ рд╕рд╛рде рдПрдХ рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ред рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдкрдврд╝рдиреЗ, рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдФрд░ рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реЗрд╡рд╛ рдкрджреНрдзрддрд┐ рдмрдирд╛рдПрдВрдЧреЗред рдпрд╣ рдкрд╣рд▓реЗ рдирд╛рдо, рдЕрдВрддрд┐рдо рдирд╛рдо рдпрд╛ рдЕрдиреНрдп рдореЗрдЯрд╛-рдбреЗрдЯрд╛ рджреНрд╡рд╛рд░рд╛ рдкреВрд░реНрдг-рдкрд╛рда рдЦреЛрдЬ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрдВрддрд░рд┐рдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЖрдзрд╛рд░ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред рд╕рдВрдмрдВрдзрдкрд░рдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо
рд╕реНрдкреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ рдЬрдкрд╛ рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдХрд╛рдИ рд╡рд░реНрдЧ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
import org.hibernate.search.annotations.Field import org.hibernate.search.annotations.Indexed import javax.persistence.Entity import javax.persistence.Id import javax.persistence.Table @Entity @Table(name = "users") @Indexed internal data class User( @Id val id: Long, @Field val name: String, @Field val surname: String, @Field val phoneNumber: String)
рд╕рдм рдХреБрдЫ рдорд╛рдирдХ рд╣реИ, рд╣рдо рд╕реНрдкреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдЗрдХрд╛рдИ рдХреЛ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВред
рдЗрдХрд╛рдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
, рд╣рдо рдЗрдХрд╛рдИ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ,
рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд▓реЗрдмрд▓ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рдЕрдиреБрдХреНрд░рдорд┐рдд рдПрдиреЛрдЯреЗрд╢рди рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдЗрдХрд╛рдИ рдЕрдиреБрдХреНрд░рдорд┐рдд рд╣реИ рдФрд░ рдПрдХ рдкреВрд░реНрдг-рдкрд╛рда рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рдЖ рдЬрд╛рдПрдЧреАред
рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдкрд░ CRUD рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ JPA рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА:
internal interface UserRepository: JpaRepository<User, Long>
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛, UserService.java:
import org.springframework.stereotype.Service import javax.transaction.Transactional @Service @Transactional internal class UserService(private val userRepository: UserRepository, private val userSearch: UserSearch) { fun findAll(): List<User> { return userRepository.findAll() } fun search(text: String): List<User> { return userSearch.searchUsers(text) } fun saveUser(user: User): User { return userRepository.save(user) } }
FindAll рдХреЛ рд╕рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕реАрдзреЗ рдорд┐рд▓рддреЗ рд╣реИрдВред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдбреЗрдХреНрд╕ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЦреЛрдЬ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЦреЛрдЬ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдШрдЯрдХ:
@Repository @Transactional internal class UserSearch(@PersistenceContext val entityManager: EntityManager) { fun searchUsers(text: String): List<User> { // fullTextEntityManager, entityManager val fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager) // Hibernate Search query DSL val queryBuilder = fullTextEntityManager.searchFactory .buildQueryBuilder().forEntity(User::class.java).get() // , val query = queryBuilder .keyword() .onFields("name") .matching(text) .createQuery() // Lucene Query Hibernate Query object val jpaQuery: FullTextQuery = fullTextEntityManager.createFullTextQuery(query, User::class.java) // return jpaQuery.resultList.map { result -> result as User }.toList() } }
рдЕрдиреНрдп рдирд┐рдпрдВрддреНрд░рдХ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рдпрдВрддреНрд░рдгрдХрд░реНрддрд╛: рдЬрд╛рд╡рд╛:
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController import java.util.* @RestController internal class UserController(private val userService: UserService) { @GetMapping("/users") fun getAll(): List<User> { return userService.findAll() } @GetMapping("/users/search") fun search(text: String): List<User> { return userService.search(text) } @PostMapping("/users") fun insertUser(@RequestBody user: User): User { return userService.saveUser(user) } }
рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдирд┐рдХрд╛рд▓рдиреЗ рдФрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдЖрд╡реЗрджрди рдХреЗ рдЪрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рдЖрд░рдВрднреАрдХреГрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рд╣рдо ApplicationListener рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВред
package ru.rti import org.hibernate.search.jpa.Search import org.springframework.boot.context.event.ApplicationReadyEvent import org.springframework.context.ApplicationListener import org.springframework.stereotype.Component import javax.persistence.EntityManager import javax.persistence.PersistenceContext import javax.transaction.Transactional @Component @Transactional class BuildSearchService( @PersistenceContext val entityManager: EntityManager) : ApplicationListener<ApplicationReadyEvent> { override fun onApplicationEvent(event: ApplicationReadyEvent?) { try { val fullTextEntityManager = Search.getFullTextEntityManager(entityManager) fullTextEntityManager.createIndexer().startAndWait() } catch (e: InterruptedException) { println("An error occurred trying to build the search index: " + e.toString()) } } }
рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╣рдордиреЗ PostgreSQL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛:
spring.datasource.url=jdbc:postgresql:users spring.datasource.username=postgres spring.datasource.password=postgres spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.name=users
рдЕрдВрдд рдореЗрдВ,
build.gradle
:
buildscript { ext.kotlin_version = '1.2.61' ext.spring_boot_version = '1.5.15.RELEASE' repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version" classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" } } apply plugin: 'kotlin' apply plugin: "kotlin-spring" apply plugin: "kotlin-jpa" apply plugin: 'org.springframework.boot' noArg { invokeInitializers = true } jar { baseName = 'gs-rest-service' version = '0.1.0' } repositories { jcenter() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile 'org.springframework.boot:spring-boot-starter-web' compile 'org.springframework.boot:spring-boot-starter-data-jpa' compile group: 'postgresql', name: 'postgresql', version: '9.1-901.jdbc4' compile group: 'org.hibernate', name: 'hibernate-core', version: '5.3.6.Final' compile group: 'org.hibernate', name: 'hibernate-search-orm', version: '5.10.3.Final' compile group: 'com.h2database', name: 'h2', version: '1.3.148' testCompile('org.springframework.boot:spring-boot-starter-test') }
рдпрд╣ рдбреЗрдореЛ рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдЦреЛрдЬ рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЖрдк рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ рджреЛрд╕реНрддреЛрдВ рдЕрдкрд╛рдЪреЗ рд▓реНрдпреВрд╕рд┐рди рдФрд░ рд╕реНрдкреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ рдПрдордкреАрдП рдмрдирд╛рдпрд╛ рдЬрд╛рдПред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЗрд╕ рдбреЗрдореЛ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ Apache Solr рдпрд╛ ElasticSearch рд╕реЗ рдЬреБрдбрд╝реА рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рджрд┐рд╢рд╛ рдмрдбрд╝реЗ рд╕реВрдЪрдХрд╛рдВрдХ (> 10 рдЬреАрдмреА) рдХреА рдЦреЛрдЬ рдХрд░рдирд╛ рдФрд░ рдЙрдирдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдирд╛ рд╣реИред рдЖрдк рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдЦреЛрдЬ рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреА рдЧрд╣рди рд╕реНрддрд░ рдкрд░ рдЦреЛрдЬ рдХрд░рдХреЗ ElasticSearch рдпрд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╕реВрдЪрдХрд╛рдВрдХ рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рд▓рд┐рдП рд╡рд┐рдиреНрдпрд╛рд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдЙрдкрдпреЛрдЧреА рд▓рд┐рдВрдХ: