SpringBoot JAP 踩坑总结
一、 JSON 字段映射处理流程
1、实现类型转换接口
package com.call.show.common.utils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import javax.persistence.AttributeConverter; import javax.persistence.Converter; import java.io.IOException; import java.io.Serializable; @Converter(autoApply = true) public class JsonConverter implements AttributeConverter<Object,String>,Serializable { private final static ObjectMapper objectMapper = new ObjectMapper(); @Override public String convertToDatabaseColumn(Object meta) { try { return objectMapper.writeValueAsString(meta); } catch (JsonProcessingException ex) { return null; } } @Override public Object convertToEntityAttribute(String dbData) { try { return objectMapper.readValue(dbData, Object.class); } catch (IOException ex) { return null; } } }
2、实体类中添加注解
@Convert(converter=JsonConverter.class)
例如:
/** * 账号信息 备用字段 */ @Column(name = "account_info") @Convert(converter=JsonConverter.class) private String accountInfo ; /** * 扩展信息备用字段 */ @Column(name = "extended_info") @Convert(converter=JsonConverter.class) private String extendedInfo ;
二、JPA中的jpql-@Query的查询使用
1、单参数查询
@Query(value="select * from cst_customer where cust_name=?1",nativeQuery = true)
@Query(value="from Customer where cust_name= ?1")
@Query(value="select c from Customer c where c.custName=?1")
@Query(value="from Customer c where c.custName=:#{#custName}")
@Query(value="from Customer c where c.custName=:custName") List<Customer> findAllCustomerByName(@Param("custName") String custName);
123456
这几种方式是等价的
- @Query(value=“select * from cst_customer where cust_name= ?1”,nativeQuery = true)
- @Query(value=“from Customer where cust_name= ?1”)
- @Query(value=“select c from Customer c where c.custName=?1”)
- @Query(value=“from Customer c where c.custName=:#{#custName}”)
- @Query(value=“from Customer c where c.custName=:custName”)
2、多参数查询
@Query(value="from Customer c where c.custId=?2 and c.custName=?1")
@Query(value="from Customer c where c.custId=:#{#custId} and c.custName=:#{#custName}")
@Query(value="from Customer c where c.custId=:custId and c.custName=:custName")
List<Customer> findCustomersByNameAndIndus(@Param("custName") String name,@Param("custId") Long id);
1234
这几种方式是等价的
- @Query(value=“from Customer c where c.custId=?2 and c.custName=?1”)
- @Query(value=“from Customer c where c.custId=:#{#custId} and c.custName=:#{#custName}”)
- @Query(value=“from Customer c where c.custId=:custId and c.custName=:custName”)
3.传对象
这里需要特别注意,可能很多人会写错
传对象的语法是: :#{#对象名称.对象属性} 如下图
@Query(value="from Customer c where c.custId=:#{#customer.custId}")
Customer findCustomerByInfo(@Param("customer") Customer customer);
三、自定义的@Query报异常
org.springframework.dao.InvalidDataAccessApiUsageException: For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters
通过@Query注解返回视图对象列表 :
public interface StudentRepository extends CrudRepository<Student, Integer> { @Query( "select new com.alphathur.jpademo.model.vo.StudentVo(name, age) from Student where salary = :salary ") List<StudentVo> findStudentVo(Double salary); }
这个接口使用了‘ :参数名’ 来绑定参数,且没有对salary使用@Param参数,所以报错了。
解决问题方案:
加上@Param,将接口修改如下:
public interface StudentRepository extends CrudRepository<Student, Integer> { @Query( "select new com.alphathur.jpademo.model.vo.StudentVo(name, age) from Student where salary = :salary ") List<StudentVo> findStudentVo(@Param("salary") Double salary);