免费招聘网站推荐,网站建设制作方法,自己的电脑怎么做网站,3d建模自学教程原本项目是基于MYSQL的#xff0c;现因需求将其转换为MYSQLElasticsearch#xff0c;MYSQL的ORM使用的是Spring Data Jpa#xff0c;Mybatis的转换与其类似#xff0c;有人看再更先看原项目原项目的DAO层Repository
public interface UserRepository extends JpaRepository…原本项目是基于MYSQL的现因需求将其转换为MYSQLElasticsearchMYSQL的ORM使用的是Spring Data JpaMybatis的转换与其类似有人看再更先看原项目原项目的DAO层Repository
public interface UserRepository extends JpaRepositoryUser, Long {OptionalUser findOneByActivationKey(String activationKey);ListUser findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime);OptionalUser findOneByResetKey(String resetKey);OptionalUser findOneByEmailIgnoreCase(String email);OptionalUser findOneByLogin(String login);EntityGraph(attributePaths authorities)OptionalUser findOneWithAuthoritiesById(Long id);EntityGraph(attributePaths authorities)OptionalUser findOneWithAuthoritiesByLogin(String login);EntityGraph(attributePaths authorities)OptionalUser findOneWithAuthoritiesByEmail(String email);PageUser findAllByLoginNot(Pageable pageable, String login);
}原项目的DTO1.User.javaEntity
Table(name user)
public class User implements Serializable {private static final long serialVersionUID 1L;IdGeneratedValue(strategy GenerationType.IDENTITY)private Long id;NotNullPattern(regexp Constants.LOGIN_REGEX)Size(min 1, max 50)Column(length 50, unique true, nullable false)private String login;JsonIgnoreNotNullSize(min 60, max 60)Column(name password_hash, length 60, nullable false)private String password;EmailSize(min 5, max 254)Column(length 254, unique true)private String email;NotNullColumn(nullable false)private boolean activated false;Column(name reset_date)private Instant resetDate null;JsonIgnoreManyToManyJoinTable(name jhi_user_authority,joinColumns {JoinColumn(name user_id, referencedColumnName id)},inverseJoinColumns {JoinColumn(name authority_name, referencedColumnName name)})BatchSize(size 20)private SetAuthority authorities new HashSet();//...
}
2.Authority.javaEntity
Table(name jhi_authority)
public class Authority implements Serializable {private static final long serialVersionUID 1L;NotNullSize(max 50)IdColumn(length 50)private String name;
}可以看出原项目使用Spring data hibernate 作为ORM规范的使用其格式进行自动生成SQL语句接下来就是转换成elasticsearch的时候了这里我不采用elasticsearch官网的client依赖包而是spring-data-elasticsearch原因如下官网提供的low包就是一个httpclient做业务操作时需要自己编写json几百个接口就要编写几百次json过于麻烦官网提供的high包必须要与elasticsearch对应版本才行不然项目就运行不起来原项目是使用Spring-data-jpa的这里用spring-data-elasticsearch在更改时会方便很多①首先先配置elasticsearchpom.xml加入 dependencygroupIdorg.springframework.data/groupIdartifactIdspring-data-elasticsearch/artifactId/dependency若你是spring boot项目则在 application.yml 或者 application.properties 加入spring: data:elasticsearch:cluster-nodes: localhost:9300若你是普通spring项目则看Spring Data Elasticsearchdocs.spring.io进行配置②改造DTO把原有的spring data 注解删除掉然后替换成elasticsearch的注解Document(indexName user, type doc)
public class User {//这里的instant jackson无法直接从string转换为instant需要编写个编解码类JsonSerialize(using InstantJacksonSerializer.class)JsonDeserialize(using InstantJacksonDeserialize.class)private Instant createdDate;private String createdBy;private boolean activated;//原项目Id是使用Long类型这里不改但elasticsearch的话推荐使用String作为Id因为自动创建id的时候为随机字符串Idprivate Long id;private SetAuthority authorities;private String login;private String email;//...
}可以看到我除了删除了原项目的注解外DTO就只有添加了 Document(indexName user, type doc) Instant是原项目使用的如果是用Date的话则使用 JsonFormat(patternyyyy-MM-dd HH:mm:ss)③改造DAO层先看改造后的public interface UserRepository extends ElasticsearchRepositoryUser, Long {OptionalUser findOneByActivationKey(String activationKey);ListUser findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime);OptionalUser findOneByResetKey(String resetKey);OptionalUser findOneByEmailIgnoreCase(String email);OptionalUser findOneByLogin(String login);OptionalUser findOneByEmail(String email);PageUser findAllByLoginNot(Pageable pageable, String login);}将UserRepository 改为继承ElasticsearchRepositoryUser, Long 其中第一个参数为DTO第二个参数为Id把连表的with给去掉即可IDEA中用shiftF6可以很方便的若你需要特殊查询可以使用 Query({bool : {must : {field : {name : ?0}}}})PageBook findByName(String name,Pageable pageable);④关于join的问题Elasticsearch是不支持join操作的可以有以下几种解决方案因SQL不支持数组才把其放入其他表的Elasticsearch本身支持数组直接放入同一张表一对多一对一多对一情况下的可以考虑数据冗余直接加入同一张表中Elasticsearch本身储存的数据会进行压缩的数据冗余可以接受在不加索引情况下可能达到MYSQL十分之一的存储空间使用父子关系不推荐之前看到好像在将来的版本会被废弃两次查询解决join问题实在没办法了就只能这样做了在本项目中我用的是方案一再复杂点的情况之后再考虑⑤关于遇到的坑 //MYSQLSize(max 50)Column(name first_name, length 50)private String firstName;//Elasticsearchprivate String firstName;MYSQL数据库里储存的字段名都是first_name这样以下划线作为分词的而spring data Elasticsearch 我并没有找到转义的相应注解。。。。如果有人知道麻烦告诉下我的解决方案在导入数据源的时候把其改为驼峰法的结构⑥数据导入我使用的是logstash还有其他框架可以使用按需求自己决定吧