Backend Development 9 min read

Generate SQL with Spring AI: LLM‑Powered Queries in Spring Boot 3

This article demonstrates how to use Spring AI with a large language model to automatically generate and execute SELECT SQL statements in a Spring Boot 3 application, covering dependency setup, configuration files, prompt templates, controller implementation, and testing with example scripts.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Generate SQL with Spring AI: LLM‑Powered Queries in Spring Boot 3

1. Introduction

Large language models (LLMs) can generate source code when given sufficient context and clear instructions. By providing DDL statements and a prompt that specifies the desired SQL output format, LLMs can also construct SQL queries.

The following example shows how to interact with an LLM via Spring AI to generate a SELECT query and execute it against a database.

2. Practical Example

2.1 Dependency Management

<code>&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-data-jdbc&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;com.alibaba.cloud.ai&lt;/groupId&gt;
  &lt;artifactId&gt;spring-ai-alibaba-starter&lt;/artifactId&gt;
  &lt;version&gt;1.0.0-M6.1&lt;/version&gt;
&lt;/dependency&gt;</code>

The Alibaba model platform is used; the JDBC starter allows execution of the generated SQL.

2.2 Configuration Files

Application properties for Spring AI:

<code>spring:
  ai:
    dashscope:
      api-key: sk-xxxooo
      base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
      chat:
        options:
          model: qwen-turbo</code>

DDL and data scripts (schema.sql and data.sql) are placed in classpath:script/ and automatically executed on startup:

<code>spring:
  sql:
    init:
      schema-locations: classpath:script/schema.sql
      data-locations: classpath:script/data.sql
      platform: mysql
      mode: always</code>

2.3 Prompt Template

<code>Based on the provided DDL, write a SQL query to answer the QUESTION.
Only generate a SELECT query. Do not add any surrounding text or markers.
If the question is not a query (e.g., INSERT, UPDATE, DELETE), reply that the operation is not supported.
If the question cannot be answered, state that the DDL does not support it.

QUESTION
{question}

DDL
{ddl}</code>

2.4 Controller Implementation

<code>@RestController
public class SqlController {
  @Value("classpath:script/schema.sql")
  private Resource ddlResource;
  @Value("classpath:/sql-prompt-template.tml")
  private Resource sqlPromptTemplateResource;

  private final ChatClient aiClient;
  private final JdbcTemplate jdbcTemplate;

  public SqlController(ChatClient.Builder aiClientBuilder, JdbcTemplate jdbcTemplate) {
    this.aiClient = aiClientBuilder.build();
    this.jdbcTemplate = jdbcTemplate;
  }

  @PostMapping(path = "/sql")
  public AiResponse sql(@RequestBody AiRequest request) throws IOException {
    String schema = ddlResource.getContentAsString(Charset.defaultCharset());
    String query = aiClient.prompt()
        .advisors(new SimpleLoggerAdvisor())
        .user(userSpec -> userSpec
            .text(sqlPromptTemplateResource)
            .param("question", request.text())
            .param("ddl", schema))
        .call().content();
    if (query.toLowerCase().startsWith("select")) {
      return new AiResponse(query, jdbcTemplate.queryForList(query));
    }
    throw new AiException(query);
  }

  public static record AiRequest(String text) {}
  public static record AiResponse(String sqlQuery, List<Map<String, Object>> results) {}
}
</code>

The controller uses ChatClient to send the prompt to the LLM and JdbcTemplate to execute the returned SELECT query.

2.5 Logging Configuration

<code>logging:
  level:
    '[org.springframework.ai.chat.client.advisor]': debug</code>

2.6 Testing

A two‑table join query is sent to the API; the LLM generates a correct SELECT statement, which is executed and the results are returned. Screenshots of the console output confirm successful execution. When a non‑SELECT operation (e.g., INSERT) is submitted, the service responds with a message indicating the operation is not supported, as defined by the prompt template.

All steps together provide a complete workflow for LLM‑driven SQL generation and execution within a Spring Boot 3 application.

Flow diagram
Flow diagram
backendJavaLLMSpring BootSpring AISQL generation
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.