Java SpringBoot中json转换的正确方式和位置

Java SpringBoot中json转换的正确方式和位置,java,postgresql,hibernate,spring-boot,jpa,Java,Postgresql,Hibernate,Spring Boot,Jpa,我在做一个小的SpringBoot项目。在postgres数据库中存储订单数据。我有一个API,它为我的前端返回json。 我在问自己应该在哪个位置将数据转换为实际的json。我知道有几种方法可以做到这一点,但我想学习专业的方法 假设订单包含id、日期、customername、productid。在本例中,当询问特定名称时,我只需要将日期作为订单日期,将productid作为前端的产品id 可能的方式: 1) 在my Crudepository中使用本机postgres查询: @Query(v

我在做一个小的SpringBoot项目。在postgres数据库中存储订单数据。我有一个API,它为我的前端返回json。 我在问自己应该在哪个位置将数据转换为实际的json。我知道有几种方法可以做到这一点,但我想学习专业的方法

假设订单包含id、日期、customername、productid。在本例中,当询问特定名称时,我只需要将日期作为订单日期,将productid作为前端的产品id

可能的方式:

1) 在my Crudepository中使用本机postgres查询:

@Query(value="SELECT json_build_object('order_date', o.date, 'product_id', productid) 
       from order where name=:name", nativeQuery = true)
List<Object> getOrderByName(@Param("name") String name);
在控制器中,我将创建一个HashMap并返回它,假设 方法具有返回类型ResponseEntity>

Order order = orderRepository.findByName("John Doe");
HashMap<String, String> jsonResult = new HashMap<>();
jsonResult.put("order_date", order.getName());
jsonResult.put("product_id", order.getProductId());
return jsonResult;
Order-Order=orderRepository.findByName(“John Doe”);
HashMap jsonResult=新HashMap();
jsonResult.put(“order_date”,order.getName());
jsonResult.put(“product_id”,order.getProductId());
返回jsonResult;
这样做的好处是,我可以对从数据库获得的order对象进行计算。我不必使用难看的sql查询,可以利用我的ORM系统的优点。最大的缺点是,我总是必须在每个感觉不正确的控制器方法的末尾创建这个定制json

3) 使用JPA预测。我没有试过,但我读到了()


做这个标准动作的专业方法是什么?在更大的企业应用程序中是如何实现的?大型企业应用程序是否使用jpa CRUDepository或如何与java中的数据库交互?

您首先需要一个可以映射到表的实体以及该实体的crud/jpa存储库。您可以查询存储库(在controller中)并控制API要发回的字段(映射到表的列)

下面是一个示例(您需要包含SpringWeb依赖项以启用自动配置)。在这里@JsonIgnore注释,忽略JSON响应的字段。但它将在java对象中可用

@Entity
public class Order {

    @Column(name = "product_id")
    protected Long productId;

    @Column(name = "order_date")
    protected Date orderDate;

    @JsonIgnore
    @Column(name = "order_number")
    protected Date orderNumber;

    //setters and getters

}

@Transactional
public interface OrderRepo extends JpaRepository<Order, Long>{
}

@Controller
public class OrderController
{

  public OrderController(){}

  @Autowired
  OrderRepo orderRepo;

  @GetMapping(/orders/{id})
  public Order findOrder(@PathVariable("id")long id)
  {
   return orderRepo.findById(id);
  }
}

@实体
公共阶级秩序{
@列(name=“product\u id”)
受保护的长productId;
@列(name=“订单日期”)
受保护日期orderDate;
@杰索尼奥雷
@列(name=“订单号”)
受保护日期订单号;
//二传手和接球手
}
@交易的
公共接口OrderRepo扩展了JpaRepository{
}
@控制器
公共类OrderController
{
公共OrderController(){}
@自动连线
OrderRepo OrderRepo;
@GetMapping(/orders/{id})
公共秩序查找器(@PathVariable(“id”)长id)
{
returnorderepo.findById(id);
}
}
假设您有一个“标准”项目结构:控制器、服务、存储库和域模型-
import
s为简洁起见被省略

控制员
@控制器
@请求映射(“/entities”)
公共最终类控制器{
私有静态最终记录器log=LoggerFactory.getLogger(controller.class);
私人最终服务;
公共控制器(最终服务服务){
服务=服务;
}
@GetMapping(products=MediaType.APPLICATION\u JSON\u值)
公共响应getAll(最终HttpServletRequest请求){
log.info(“{}{}”,request.getMethod(),request.getRequestURI());
返回ResponseEntity.ok(service.searchAll());
}
@GetMapping(path=“{entity id}”,products=MediaType.APPLICATION\u JSON\u VALUE)
公共响应属性getById(final@PathVariable(“实体id”)字符串id,final HttpServletRequest){
log.info(“{}{}”,request.getMethod(),request.getRequestURI());
最终可选结果=service.searchById(UUID.fromString(id));
if(result.isPresent()){
返回ResponseEntity.ok(result.get());
}
返回ResponseEntity.notFound().build();
}
@PostMapping(consumes=MediaType.APPLICATION\u JSON\u值)
公共响应帖子(@RequestBody@Valid final JpaEntity body,final HttpServletRequest){
log.info(“{}{}”,request.getMethod(),request.getRequestURI());
final URI=URI.create(String.format(“%s/%s”、request.getRequestURI()、service.save(body.getId())).normalize();
返回ResponseEntity.created(uri.build();
}
}
服务
@服务
@交易的
公共类服务{
私有静态最终记录器log=LoggerFactory.getLogger(service.class);
私有存储库;
公共服务(最终存储库){
this.repository=存储库;
}
@事务(只读=真)
公共集合searchAll(){
log.info(“检索所有记录…”);
返回repository.findAll();
}
@事务(只读=真)
公共可选searchById(最终UUID id){
log.info(“正在检索ID为[{}]”,ID为的记录);
返回repository.findById(id);
}
公共JPA实体保存(最终JPA实体){
log.info(“持久记录[{}]”,实体);
返回repository.save(实体);
}
}
存储库
公共接口TheRepository扩展了JpaRepository{}
域模型
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
抽象类AbstractPersistable实现了可序列化{
私有静态最终长serialVersionUID=-537959523291969928L;
@身份证
@JsonProperty(“\u id”)
@GeneratedValue(generator=“uuid2”)
@GenericGenerator(name=“uuid2”,strategy=“uuid2”)
@列(name=“id”,nullable=false,updateable=false,unique=true)
私人T-id;
@创建数据
@列(name=“created_on”,nullable=false,updateable=false)
私人即时createdOn;
@创造的
@列(name=“created_by”,nullable=false)
创建的私有字符串;
@最后修改日期
@列(name=“modified_on”,nullable=false)
私人即时修改;
@最后修改
@列(name=“modified_by”,nullable=false)
私有字符串被修改;
@版本
@JsonProperty(“U版本”)
私有整数版本;
抽象派
@Entity
public class Order {

    @Column(name = "product_id")
    protected Long productId;

    @Column(name = "order_date")
    protected Date orderDate;

    @JsonIgnore
    @Column(name = "order_number")
    protected Date orderNumber;

    //setters and getters

}

@Transactional
public interface OrderRepo extends JpaRepository<Order, Long>{
}

@Controller
public class OrderController
{

  public OrderController(){}

  @Autowired
  OrderRepo orderRepo;

  @GetMapping(/orders/{id})
  public Order findOrder(@PathVariable("id")long id)
  {
   return orderRepo.findById(id);
  }
}