当前位置: 首页 > 知识库问答 >
问题:

JavaSpringBoot是否提供了像php CodeIgniter查询生成器这样的查询生成器

段干茂实
2023-03-14

我们正在SpringBoot中开发一个应用程序,我们将在运行时创建动态表单并将其发布到应用程序中,以JSON格式将表单数据发布到db(MySql)中。我们希望创建一个通用api来处理所有动态表单的CRUD操作。

我们知道php code-igniter框架查询生成器,它能够构建和执行查询。

https://www.codeigniter.com/userguide3/database/query_builder.html#inserting-data

例如:

$query=$this-

        $data = array(
    'title' => 'My title',
    'name' => 'My Name',
    'date' => 'My date'

); $这个-

在JavaSpring Boot中是否有任何方法(任何插件或maven依赖项)可以实现相同的功能(如php代码点火器)。

        Map<String, String> map = new TreeMap<>();
    map.put("name","User Name");
    map.put("dob", "30-3-1995");
    map.put("address", "Address Line");
    map.put("city", "Jaipur");
    /* insert into user table */
    db.insert("user",map);

共有1个答案

卫飞
2023-03-14

实现类似功能的方法很少:

>

此模块根据约定从方法生成(或派生)查询,例如:

interface UsersRepository extends CrudRepository<User, Long> {
  List<User> findByLastname(String lastname);
}

调用personRepository。findByLastName(“Doe”)可以翻译为:

SELECT * FROM users WHERE last_name = 'Doe'

然而,为了让Spring发挥这种魔力,它需要将“原始”SQL查询返回的结果集映射到一个对象。这就是ORM概念的由来。因此,您需要执行另外一个步骤:配置实体(即您的对象)并设置它们之间所需的关系。例如:

@Entity
@Table(name = "users")
public class User {
  @Id
  private String id;
  @Column(name = "first_name")
  private String firstName;
  @Column(name = "last_name")
  private String lastName;
  //constructor, getters and setters
}

现在Spring知道如何将列映射到对象,并会自动为您生成查询。更准确地说,它是由hibernate(ORM框架)在引擎盖下完成的,但是不要让术语混淆你。我建议多搜索一下Spring Data JPA vs JPA vs Hibernate,因为它不在这个问题的范围内。

Spring指南中提供了一个很好的初学者教程。您还可以在这里的官方文档中了解更多信息。

使用Spring JdbcTemboard

它可能更类似于CodeIgniter所做的,但jdbcTemplate使用“原始”SQL语句,而不是使用“内部API”:

jdbcTemplate.query(
    "SELECT id, first_name, last_name FROM customers WHERE first_name = ?", new Object[] { "Josh" },
    (rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name"))
).forEach(customer -> log.info(customer.toString()));

但是,如您所见,它返回一个结果集,您需要在其中手动映射域对象。

该代码示例可在Spring导轨上找到。这里有更多的文档。

还有其他的替代品,如jOOQ、MyBatis和QueryDSL。

就我个人而言,除了在我所从事的“生产”应用程序中遇到的“SpringDataJPA”之外,我没有遇到过任何其他方法(可能是因为它更接近Java代码,并且隐藏了很多SQL内部代码),尽管我非常熟悉前两种方法。我会推荐第一个,因为它很受欢迎,但最终取决于你。

由于不在回答范围内,无法决定您应该选择哪一个,因此我将发布一些附加链接:

  • JPA vs Spring JdbcTemplate
  • Spring数据vs Spring数据JPA vs JdbcTemplate

更新:(针对评论)

我仍然认为,即使你的表单是“动态的”,你的表模式本质上是“固定的”。您可以:

>

  • 使用JPA实体映射固定字段(如id、时间戳等)。创建动态表单字段作为这个实体的一部分-它将包含一个json字符串-

    @Entity
    @Table(name = "forms")
    public class FormEntity {
      @Id
      private String id;
      private LocalDateTime created;
      @Column(name = "dynamic_form")
      private String dynamicForm;
      //constructor, getters and setters
    }
    

    在Java中,将映射(使用示例中的任何键值)创建为一个单独的类

    使用Jackson的ObjectMapper将其序列化为string(可能是json)。

    将其映射到实体的“dynamicForm”字段:

    public class MyBusinessLogicService {
      public void processForm(Map<String, String> map) {
          FormEntity formEntity = new FormEntity();
          formEntity.setDynamicForm(objectMapper.writeValueAsString(yourMap));
          //.... setting other values
          formEntityRepository.save(formEntity);
      }
    }
    

    读取表单时,您将反序列化dynamicForm字段。

    解决方案不受地图的限制,但可以存储任何类型的对象。你这边的挑战是要知道里面有什么类型的“物体”。如果它是一个映射,您将不知道映射中的键值。

  •  类似资料:
    • 我想不出如何使用TypeOrm查询生成器编写以下MySql语句 从farm.reg中选择reg.id,其中grpId=“abc”; 这个选择返回的只是ID的,但我的查询生成器返回的是整个对象。 现在,我在我的NestJs服务中有这个函数,但我需要使用'map',我不想… 谢谢

    • 我正在构建一个简单的元数据表,从查询中获取数据。我希望能够查询“type”变量的两个选项。然而| |不起作用;当我使用这个时,页面崩溃。

    • 我试图从一个表中选择所有结果,并在用户ID匹配时与另一个表合并。 我有三个表:runs、users和一个run\u用户透视表。我想从数据透视表中的“运行”和其他列(即“已完成”、“粘性”、“上次测试”和“难度”)中选择所有结果,但只从当前用户的“运行用户”中提取数据。 在原始SQL中,我通过一个带有AND语句的左连接成功地做到了这一点: 如何通过查询生成器执行此操作,有何建议?我可以在Larave

    • 我有以下工作查询 它在整个路径=/content/dam上运行,所以它遍历所有节点大约20分钟,并给出结果。 当以编程方式使用查询生成器api时,我如何才能批量使用它,比如-遍历1000个节点并按代码执行某些操作,然后继续查询并遍历下1000个节点等等?这可能吗? 谢谢。

    • 我有一个问题,使laravel查询: 我想举个例子: 我有这个但不起作用:

    • Laravel Eloquent的save()方法实质上是执行查询生成器的工作吗? 查询生成器: 雄辩的: 如果这是真的,那么Eloquent的也是如此吗?我正在看Laravel的官方视频教程,我看到作者在控制器中使用了雄辩的和。这就是查询生成器和雄辩的区别吗?我们可以使用雄辩的内部控制器?