关于spring-data-jpa:spring-data-jpa-关于父实体保存而子实体存在id会进行多余查询的问题

先对题目给个具体的解释,其实是个级联保留的问题,我上一段实体代码 @Table(name="open_app_user")@Entitypublic class OpenAppUser extends BaseEntity implements UserDetails { /** * 所属利用id */ @ApiModelProperty(value="所属利用id") @ManyToOne @JoinColumn(name = "app_id") //private Integer appId; private OpenApp openApp; // ...}@Table(name="open_app")@Entitypublic class OpenApp extends BaseEntity { // ...}这里有两个实体,一个是父实体OpenAppUser,一个是子实体OpenApp,我遇到的一个问题是,我须要保留OpenAppUser,然而须要一个OpenApp对象,我在前端传了一个id映射到OpenApp里了,然而在保留的时候appUserRepository.save(appUser);因为openApp是一个瞬态实体,会报找不到app_id异样(这是我app_user表里的app_id字段)。 起初我试了一下在save之前,我先应用appRepository.findById(appId);把openApp对象通过查问的形式变成了长久化实体,再去save(appUser);这时候是能够的。 不过看打印的sql日志,这种保留形式,在这之前都要进行查问,这里是依赖了利用,可能还有其余的,比方用户所属部门等等,那样的效率就低了,我想着在我保留的时候,我只须要传其余依赖的id就行了,不须要一个残缺的对象,我就开始看hibernate官网文档,发现了entityManager有个getReference(id)办法能够返回一个实体代理,获取这个实体代理的时候并不一定就会查询数据库。 而后我就发现spring data jpa的实现类里JpaRepository的getById(id)就是调用的entityManager.getReference(id),而后把appRepository.findById(appId)改成appRepository.getById(appId),再去看sql打印的时候,这次就没有再查问了,而是间接用的openApp代理实体里的id属性(我也只有这个属性,是通过前端传的)。这个插入效率就高很多了,一下子优化了查问。 spring data jpa 对于存在id保留,不存在id则新增的解决,有个AbstractPersistable类,能够通过设置它来实现,spring外面是通过判断id是不是null来走entityManager.persist还是merg的。

November 6, 2021 · 1 min · jiezi

关于spring-data-jpa:SpringData-JPA解决将Map等集合类型映射到数据库的问题

1.Map汇合映射到数据库借助AtrributeConverter目前我的需要是将汇合类中的信息存储到数据库中,例如有Map字段的formBody,最好是应用JSON格局,而SpringDateJpa也为咱们提供了相干的办法,通过自定义对象转换器,并通过注解的模式对须要转换的字段进行标注即可。该接口位于javax.persistence.AtrributeConverter。咱们通过自定义类实现该接口重写其中的办法实现须要的性能,本次具体的实现如下: import com.alibaba.fastjson.JSONObject;import javax.persistence.AttributeConverter;/** * @create :Created in 2021 * @description :Jpa映射转换器,存储时对象转JsonString, 读取时相同 */public class JpaConverterObjectJson implements AttributeConverter<Object, String> { @Override public String convertToDatabaseColumn(Object o) { return o==null?null: JSONObject.toJSONString(o); } @Override public Object convertToEntityAttribute(String s) { return s==null?null:JSONObject.parseObject(s); }}实体类中 @Entity@DynamicUpdate@Datapublic class Item extends BaseEntity{ /** 物品主键 */ @Id private Long itemId; /** 源物品信息 */ private String sourceItemId; /** 物品信息 */ @Convert(converter = JpaConverterObjectJson.class) @Column(columnDefinition = "TEXT") private Map<String,Object> itemInfo;}这样存的时候就是String,取出来主动为Map。 ...

January 28, 2021 · 1 min · jiezi

关于spring-data-jpa:SpringData-JPASpecification实现mysql中json字段查询

1.mysql中实现json字段查问select * from item where is_remove = 0 and json_extract(item_info,'$.GoodType') ='cat'2.JPA @Query实现mysql中json字段查问@Query(value = "select * from item where json_extract(item_info,?1) =?2 and item_id in (?3)",nativeQuery = true)List<Item> selectItems( String featuresKey,String featuresValue,List<Long> itemIds);List<Item> items = itemRepository.selectItemListByFeatures("$.GoodType","cat",ids);3.Specification实现mysql中json字段查问items=itemRepository.findAll(new Specification<Item>() { @Override public Predicate toPredicate(Root<Item> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<>(); for(Features fea:features){ if( fea.getFeaturesAliasName()!=null && fea.getFeaturesValue()!= null){ list.add(cb.equal( cb.function( "JSON_EXTRACT", String.class, root.get("itemInfo"), cb.literal("$."+fea.getFeaturesAliasName()) ), fea.getFeaturesValue()) ); } } list.add(cb.in(root.get("itemId")).value(itemIds)); Predicate[] p = new Predicate[list.size()]; query.where(cb.and(list.toArray(p))); return query.getGroupRestriction(); }});4.备注类Item{ "itemId":"1", "itemInfo":{"GoodId":"1002","GoodType":"cat","GoodName":"catyeall"}}Features{"featuresName":"GoodType","featuresValue":"cat"}5.附录深入浅出学Spring Data JPASpring Data JPA与PostgreSQL的jsonb类型集成与反对 ...

January 26, 2021 · 1 min · jiezi

关于spring-data-jpa:解决Spring中使用Example无法查询到Mongodb中的数据问题

1 问题形容在Spring Boot中应用Mongodb中的Example查问数据时查问不到,示例代码如下: ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("username", ExampleMatcher.GenericPropertyMatchers.exact()).withIgnorePaths("id","password");2 问题剖析在Spring Data中应用Mongodb时,插入数据会增加一个_class字段,这个字段是用来映射POJO的,也就是说,如果一个实体类如下: @Document(collection = "user")class User{ @Id private String id; private String username; private String password;}则存进数据库的字段如下: _id,_class,username,password而应用ExampleMatcher,默认状况下会匹配所有字段,因而,如果实体类的包名扭转了,_class字段就不会匹配,这样就无奈正确地失去查问后果。 3 解决方案把_class增加进IgnorePath即可: .withIgnorePaths("_class","id","password")如果不想在插入数据时主动增加_class字段,能够批改MongoTemplate或者MappingMongoConverter,因为此超出本文范畴,仅给出参考链接,戳这里或这里。

December 11, 2020 · 1 min · jiezi