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);