{"id":80,"date":"2025-09-03T20:25:45","date_gmt":"2025-09-03T12:25:45","guid":{"rendered":"http:\/\/caihh.top\/?p=80"},"modified":"2025-09-04T09:35:27","modified_gmt":"2025-09-04T01:35:27","slug":"%e5%9f%ba%e4%ba%8espring-boot%e4%b8%8e%e5%a4%a7%e6%a8%a1%e5%9e%8b%e7%9a%84%e8%87%aa%e7%84%b6%e8%af%ad%e8%a8%80%e6%95%b0%e6%8d%ae%e5%ba%93%e4%ba%a4%e4%ba%92%e5%ae%9e%e8%b7%b5%ef%bc%9a%e6%99%ba%e8%83%bd","status":"publish","type":"post","link":"https:\/\/caihh.top\/index.php\/2025\/09\/03\/%e5%9f%ba%e4%ba%8espring-boot%e4%b8%8e%e5%a4%a7%e6%a8%a1%e5%9e%8b%e7%9a%84%e8%87%aa%e7%84%b6%e8%af%ad%e8%a8%80%e6%95%b0%e6%8d%ae%e5%ba%93%e4%ba%a4%e4%ba%92%e5%ae%9e%e8%b7%b5%ef%bc%9a%e6%99%ba%e8%83%bd\/","title":{"rendered":"\u57fa\u4e8eSpring Boot\u4e0e\u5927\u6a21\u578b\u7684\u81ea\u7136\u8bed\u8a00\u6570\u636e\u5e93\u4ea4\u4e92\u5b9e\u8df5\uff1a\u667a\u80fd\u8bed\u4e49\u5316\u66f4\u65b0\u64cd\u4f5c\u5b9e\u73b0\uff08\u5b66\u4e60\uff09"},"content":{"rendered":"\n<p>\u672c\u6587\u57fa\u4e8eSpring Boot\u6846\u67b6\uff0c\u7ed3\u5408\u5927\u6a21\u578b\uff08\u672c\u6587\u4f7f\u7528\u4e86\u767e\u5ea6\u6587\u5fc3\u4e00\u8a00\uff09\u7684\u8bed\u4e49\u7406\u89e3\u80fd\u529b\uff0c\u6784\u5efa\u4e86\u4e00\u5957<strong>\u81ea\u7136\u8bed\u8a00\u9a71\u52a8\u7684\u6570\u636e\u5e93\u66f4\u65b0\u5b9e\u73b0(\u6570\u636e\u66f4\u65b0\u793a\u4f8b)<\/strong>&nbsp;\u3002<\/p>\n\n\n\n<p>\u7528\u6237\u53ea\u9700\u8f93\u5165&#8221;\u5c06iPhone 13\u4ef7\u683c\u964d\u4e3a4999\u5143&#8221;\u7b49\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\uff0c\u5373\u53ef\u81ea\u52a8\u5b8c\u6210\u6570\u636e\u5e93\u8bb0\u5f55\u7684\u7cbe\u51c6\u66f4\u65b0\u3002<\/p>\n\n\n\n<p>\u6253\u5f00IDEA\u65b0\u5efaSpring Boot\u9879\u76ee<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-11-1024x934.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"934\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-11-1024x934.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-82\" style=\"width:603px;height:auto\"  sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div><\/figure>\n\n\n\n<p>\u6dfb\u52a0\u4f9d\u8d56\u9879\u76ee\uff1aSpring Web\u3001Spring Data JDBC\u3001H2 Database\u3001Lombok\u3002\u6dfb\u52a0\u597d\u4e4b\u540e\u70b9\u51fb\u521b\u5efa\u3002<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-12-1024x932.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"932\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-12-1024x932.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-83\" style=\"width:558px;height:auto\"  sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div><\/figure>\n\n\n\n<p>\u4ee5\u4e0b\u662f\u5728src\/main\/java\/org.example\u7684Java\u6587\u4ef6<\/p>\n\n\n\n<p>DbApplication.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\n\n@SpringBootApplication\npublic class DbApplication {\n    public static void main(String&#91;] args) {\n        SpringApplication.run(DbApplication.class, args);\n    }\n}<\/code><\/pre>\n\n\n\n<p>DbCondition.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\npackage org.example;\n\nimport lombok.Data;\n\n@Data\npublic class DbCondition {\n    private String field;\n    private String operator;\n    private Object value;\n}<\/code><\/pre>\n\n\n\n<p>DbController.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.*;\n\n@RestController\n@RequestMapping(\"\/api\/db\")\npublic class DbController {\n\n    @Autowired\n    private LLMService LLMService;\n\n    \/\/ \u5904\u7406\u6570\u636e\u66f4\u65b0\u8bf7\u6c42\n    @PostMapping(\"\/update\")\n    public ResponseEntity&lt;UpdateOperationResponse&gt; updateData(@RequestParam String query) {\n        UpdateOperationResponse response = LLMService.processUpdateRequest(query);\n        return ResponseEntity.ok(response);\n    }\n\n}<\/code><\/pre>\n\n\n\n<p>DbExecutor.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.jdbc.core.JdbcTemplate;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class DbExecutor {\n\n    @Autowired\n    private JdbcTemplate jdbcTemplate;\n\n    \/\/ \u6267\u884cUPDATE SQL\n    public DbOperationResult executeUpdate(String sql) {\n        DbOperationResult result = new DbOperationResult();\n\n        try {\n            \/\/ \u6267\u884c\u66f4\u65b0\n            int affectedRows = jdbcTemplate.update(sql);\n\n            result.setSuccess(true);\n            result.setAffectedRows(affectedRows);\n\n            if (affectedRows == 0) {\n                result.setErrorMessage(\"No rows were updated. The condition may not match any records.\");\n            }\n        } catch (Exception e) {\n            result.setSuccess(false);\n            result.setErrorMessage(e.getMessage());\n        }\n\n        return result;\n    }\n}<\/code><\/pre>\n\n\n\n<p>DbIntent.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\n\nimport lombok.Data;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n@Data\npublic class DbIntent {\n    private DbOperationType type;\n    private String targetTable;\n    private Map&lt;String, Object&gt; updateValues = new HashMap&lt;&gt;();\n    private List&lt;DbCondition&gt; conditions = new ArrayList&lt;&gt;();\n}<\/code><\/pre>\n\n\n\n<p>DbOperationResult.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\n\nimport lombok.Data;\n\n@Data\npublic class DbOperationResult {\n    private boolean success;\n    private Integer affectedRows;\n    private String errorMessage;\n}<\/code><\/pre>\n\n\n\n<p>DbOperationType.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\n\npublic enum DbOperationType {\n    <em>SELECT<\/em>,<em>INSERT<\/em>,<em>UPDATE<\/em>,<em>DELETE\n<\/em>}<\/code><\/pre>\n\n\n\n<p>IntentParser.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\nimport java.io.IOException;\nimport java.util.List;\n\n@Service\npublic class IntentParser {\n\n   \/* @Autowired\n    private OpenAIService openAIService;*\/\n\n    @Autowired\n    private WenxinClient wenxinClient;\n\n    @Autowired\n    private SchemaManager schemaManager;\n\n    \/\/ \u89e3\u6790\u66f4\u65b0\u64cd\u4f5c\u7684\u81ea\u7136\u8bed\u8a00\u610f\u56fe\n    public DbIntent parseUpdateIntent(String naturalLanguageQuery) {\n        \/\/ \u9996\u5148\u786e\u5b9a\u76ee\u6807\u8868\n        String targetTable = determineTargetTable(naturalLanguageQuery);\n\n        \/\/ \u83b7\u53d6\u8868\u7ed3\u6784\n        SchemaManager.TableSchema tableSchema = schemaManager.getTableSchema(targetTable);\n\n        \/\/ \u6784\u5efa\u63d0\u793a\n        String prompt = buildUpdatePrompt(tableSchema, naturalLanguageQuery);\n\n        \/\/ \u89e3\u6790JSON\u54cd\u5e94\n        String response = null;\n        try {\n            \/\/ \u8c03\u7528\u5927\u6a21\u578b\u89e3\u6790\u610f\u56fe\n            response = wenxinClient.generateCompletion(prompt);\n\n            \/\/ \u63d0\u53d6JSON\u90e8\u5206\n            response = extractJsonFromResponse(response);\n\n            ObjectMapper mapper = new ObjectMapper();\n            return mapper.readValue(response, DbIntent.class);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Failed to parse model response: \" + e.getMessage() + \"\\nResponse: \" + response, e);\n        }\n    }\n\n    \/\/ \u786e\u5b9a\u76ee\u6807\u8868\n    private String determineTargetTable(String query) {\n        List&lt;String&gt; tables = schemaManager.getAllTableNames();\n\n        String tableListStr = String.<em>join<\/em>(\", \", tables);\n        String prompt = \"Based on this user request, determine which database table is being referenced. \" +\n                \"Reply with just the table name, nothing else.\\n\\n\" +\n                \"Available tables: \" + tableListStr + \"\\n\\n\" +\n                \"User request: \" + query;\n\n        String response = null;\n        try {\n            response = wenxinClient.generateCompletion(prompt);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n        return response.trim().toLowerCase();\n    }\n\n    \/\/ \u6784\u5efa\u66f4\u65b0\u64cd\u4f5c\u7684\u63d0\u793a\n    private String buildUpdatePrompt(SchemaManager.TableSchema schema, String query) {\n        StringBuilder prompt = new StringBuilder();\n\n        \/\/ \u7cfb\u7edf\u6307\u4ee4\n        prompt.append(\"Convert this natural language request into a database update operation.\\n\\n\");\n\n        \/\/ \u8868\u7ed3\u6784\u4fe1\u606f\n        prompt.append(\"Table: \").append(schema.getTableName()).append(\"\\n\");\n        prompt.append(\"Columns: \\n\");\n\n        for (SchemaManager.ColumnSchema column : schema.getColumns()) {\n            prompt.append(\"- \").append(column.getColumnName())\n                    .append(\" (\").append(column.getDataType()).append(\")\");\n\n            if (column.isPrimaryKey()) {\n                prompt.append(\" &#91;PRIMARY KEY]\");\n            }\n            prompt.append(\"\\n\");\n        }\n\n        \/\/ \u7528\u6237\u8bf7\u6c42\n        prompt.append(\"\\nUser request: \").append(query).append(\"\\n\\n\");\n\n\/\/ \u8f93\u51fa\u683c\u5f0f\u8981\u6c42\n        prompt.append(\"Return a JSON object with this exact structure:\\n\");\n        prompt.append(\"{\\n\");\n        prompt.append(\"  \\\"type\\\": \\\"UPDATE\\\",\\n\");\n        prompt.append(\"  \\\"targetTable\\\": \\\"\").append(schema.getTableName()).append(\"\\\",\\n\");\n        prompt.append(\"  \\\"updateValues\\\": {\\n\");\n        prompt.append(\"    \\\"column_name\\\": \\\"new_value\\\"\\n\");\n        prompt.append(\"  },\\n\");\n        prompt.append(\"  \\\"conditions\\\": &#91;\\n\");\n        prompt.append(\"    {\\\"field\\\": \\\"column_name\\\", \\\"operator\\\": \\\"=\\\", \\\"value\\\": \\\"value\\\"}\\n\");\n        prompt.append(\"  ]\\n\");\n        prompt.append(\"}\\n\\n\");\n\n        prompt.append(\"Make sure the field names match exactly with the table schema provided above. \" +\n                \"Convert all values to appropriate data types.\");\n\n        return prompt.toString();\n    }\n\n    \/\/ \u4ece\u54cd\u5e94\u4e2d\u63d0\u53d6JSON\u90e8\u5206\n    private String extractJsonFromResponse(String response) {\n        int startIdx = response.indexOf('{');\n        int endIdx = response.lastIndexOf('}');\n\n        if (startIdx != -1 &amp;&amp; endIdx != -1 &amp;&amp; endIdx &gt; startIdx) {\n            return response.substring(startIdx, endIdx + 1);\n        }\n\n        return response; \/\/ \u5982\u679c\u627e\u4e0d\u5230JSON\u7ed3\u6784\uff0c\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\n    }\n}<\/code><\/pre>\n\n\n\n<p>LLMService.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;<br><br>import lombok.extern.slf4j.Slf4j;<br>import org.springframework.beans.factory.annotation.Autowired;<br>import org.springframework.stereotype.Service;<br><br>import java.io.IOException;<br><br>@Service<br>@Slf4j<br>public class LLMService {<br><br>    @Autowired<br>    private IntentParser intentParser;<br><br>    @Autowired<br>    private SqlGenerator sqlGenerator;<br><br>    @Autowired<br>    private DbExecutor dbExecutor;<br><br>    \/*@Autowired<br>    private OpenAIService openAIService;*\/<br><br>    @Autowired<br>    private WenxinClient wenxinClient;<br><br>    \/\/ \u5904\u7406\u66f4\u65b0\u6570\u636e\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42<br>    public UpdateOperationResponse processUpdateRequest(String naturalLanguageQuery) {<br>        UpdateOperationResponse response = new UpdateOperationResponse();<br>        response.setOriginalQuery(naturalLanguageQuery);<br><br>        try {<br>            \/\/ 1. \u89e3\u6790\u610f\u56fe<br>            DbIntent intent = intentParser.parseUpdateIntent(naturalLanguageQuery);<br>            response.setIntent(intent);<br><br>            \/\/ 2. \u751f\u6210SQL<br>            String sql = sqlGenerator.generateUpdateSql(intent);<br>            response.setGeneratedSql(sql);<br><br>            \/\/ 3. \u6267\u884cSQL<br>            DbOperationResult result = dbExecutor.executeUpdate(sql);<br>            response.setResult(result);<br><br>            \/\/ 4. \u751f\u6210\u81ea\u7136\u8bed\u8a00\u89e3\u91ca<br>            String explanation = generateExplanation(intent, result);<br>            response.setExplanation(explanation);<br><br>        } catch (Exception e) {<br>            <em>log<\/em>.error(e.getMessage(), e);<br>            DbOperationResult errorResult = new DbOperationResult();<br>            errorResult.setSuccess(false);<br>            errorResult.setErrorMessage(e.getMessage());<br>            response.setResult(errorResult);<br>            response.setExplanation(\"\u65e0\u6cd5\u5b8c\u6210\u60a8\u7684\u8bf7\u6c42: \" + e.getMessage());<br>        }<br><br>        return response;<br>    }<br><br>    \/\/ \u751f\u6210\u81ea\u7136\u8bed\u8a00\u89e3\u91ca<br>    private String generateExplanation(DbIntent intent, DbOperationResult result) {<br>        if (!result.isSuccess()) {<br>            return \"\u64cd\u4f5c\u5931\u8d25: \" + result.getErrorMessage();<br>        }<br><br>        \/\/ \u6784\u5efa\u63d0\u793a<br>        StringBuilder prompt = new StringBuilder();<br>        prompt.append(\"\u8bf7\u7528\u7b80\u6d01\u7684\u4e2d\u6587\u89e3\u91ca\u4ee5\u4e0b\u6570\u636e\u5e93\u64cd\u4f5c\u7684\u7ed3\u679c\uff1a\\n\\n\");<br><br>        \/\/ \u6dfb\u52a0\u610f\u56fe\u548c\u7ed3\u679c\u4fe1\u606f<br>        prompt.append(\"\u8868: \").append(intent.getTargetTable()).append(\"\\n\");<br>        prompt.append(\"\u66f4\u65b0\u5185\u5bb9: \").append(intent.getUpdateValues()).append(\"\\n\");<br>        prompt.append(\"\u6761\u4ef6: \").append(intent.getConditions()).append(\"\\n\");<br>        prompt.append(\"\u53d7\u5f71\u54cd\u884c\u6570: \").append(result.getAffectedRows()).append(\"\\n\\n\");<br><br>        \/\/ \u8c03\u7528LLM\u751f\u6210\u89e3\u91ca<br>        try {<br>            return wenxinClient.generateCompletion(prompt.toString());<br>        } catch (IOException e) {<br>            throw new RuntimeException(e);<br>        }<br>    }<br>}<\/code><\/pre>\n\n\n\n<p>SchemaManager.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;<br><br>import lombok.Data;<br>import org.springframework.beans.factory.annotation.Autowired;<br>import org.springframework.jdbc.core.JdbcTemplate;<br>import org.springframework.stereotype.Service;<br>import java.util.List;<br>import java.util.stream.Collectors;<br><br>@Service<br>public class SchemaManager {<br><br>    @Autowired<br>    private JdbcTemplate jdbcTemplate;<br><br>    \/\/ \u83b7\u53d6\u8868\u7ed3\u6784 - \u6700\u7b80\u5316\u7248\u672c<br>    public TableSchema getTableSchema(String tableName) {<br>        \/\/ \u9a8c\u8bc1\u8868\u662f\u5426\u5b58\u5728<br>        List&lt;String&gt; tables = jdbcTemplate.queryForList(<br>                \"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ?\",<br>                String.class, tableName.toUpperCase()<br>        );<br><br>        if (tables.isEmpty()) {<br>            throw new RuntimeException(\"Table not found: \" + tableName);<br>        }<br><br>        \/\/ \u83b7\u53d6\u5217\u4fe1\u606f<br>        List&lt;ColumnSchema&gt; columns = jdbcTemplate.query(<br>                \"SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS \" +<br>                        \"WHERE TABLE_NAME = ?\",<br>                (rs, rowNum) -&gt; {<br>                    ColumnSchema column = new ColumnSchema();<br>                    column.setColumnName(rs.getString(\"COLUMN_NAME\").toLowerCase());<br>                    column.setDataType(rs.getString(\"DATA_TYPE\").toLowerCase());<br><br>                    \/\/ \u7b80\u5355\u5047\u8bbe\uff1aid\u5217\u662f\u4e3b\u952e\uff08\u8fd9\u5728\u5927\u591a\u6570\u5e94\u7528\u4e2d\u662f\u5e38\u89c1\u7684\u7ea6\u5b9a\uff09<br>                    String colName = rs.getString(\"COLUMN_NAME\").toLowerCase();<br>                    column.setPrimaryKey(colName.equals(\"id\"));<br><br>                    return column;<br>                },<br>                tableName.toUpperCase()<br>        );<br><br>        TableSchema schema = new TableSchema();<br>        schema.setTableName(tableName.toLowerCase());<br>        schema.setColumns(columns);<br>        return schema;<br>    }<br><br>    \/\/ \u83b7\u53d6\u6240\u6709\u8868\u540d<br>    public List&lt;String&gt; getAllTableNames() {<br>        return jdbcTemplate.queryForList(<br>                \"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC'\",<br>                String.class<br>        ).stream().map(String::toLowerCase).collect(Collectors.<em>toList<\/em>());<br>    }<br><br>    @Data<br>    public static class TableSchema {<br>        private String tableName;<br>        private List&lt;ColumnSchema&gt; columns;<br><br>        \/\/ \u68c0\u67e5\u5b57\u6bb5\u662f\u5426\u5b58\u5728<br>        public boolean hasColumn(String columnName) {<br>            return columns.stream()<br>                    .anyMatch(col -&gt; col.getColumnName().equalsIgnoreCase(columnName));<br>        }<br><br>        \/\/ \u83b7\u53d6\u4e3b\u952e\u5217<br>        public List&lt;String&gt; getPrimaryKeys() {<br>            return columns.stream()<br>                    .filter(ColumnSchema::isPrimaryKey)<br>                    .map(ColumnSchema::getColumnName)<br>                    .collect(Collectors.<em>toList<\/em>());<br>        }<br>    }<br><br>    @Data<br>    public static class ColumnSchema {<br>        private String columnName;<br>        private String dataType;<br>        private boolean primaryKey;<br>    }<br>}<\/code><\/pre>\n\n\n\n<p>SqlGenerator.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;<br><br>import org.springframework.beans.factory.annotation.Autowired;<br>import org.springframework.stereotype.Service;<br><br>import java.util.ArrayList;<br>import java.util.List;<br>import java.util.Map;<br>import java.util.stream.Collectors;<br><br>@Service<br>public class SqlGenerator {<br><br>    @Autowired<br>    private SchemaManager schemaManager;<br><br>    \/\/ \u751f\u6210UPDATE SQL\u8bed\u53e5<br>    public String generateUpdateSql(DbIntent intent) {<br>        \/\/ \u9a8c\u8bc1\u610f\u56fe<br>        validateUpdateIntent(intent);<br><br>        StringBuilder sql = new StringBuilder(\"UPDATE \");<br>        sql.append(intent.getTargetTable()).append(\" SET \");<br><br>        \/\/ \u6dfb\u52a0\u8981\u66f4\u65b0\u7684\u5b57\u6bb5\u548c\u503c<br>        List&lt;String&gt; setStatements = new ArrayList&lt;&gt;();<br>        for (Map.Entry&lt;String, Object&gt; entry : intent.getUpdateValues().entrySet()) {<br>            setStatements.add(entry.getKey() + \" = \" + formatValue(entry.getValue()));<br>        }<br>        sql.append(String.<em>join<\/em>(\", \", setStatements));<br><br>        \/\/ \u6dfb\u52a0WHERE\u6761\u4ef6<br>        if (intent.getConditions() != null &amp;&amp; !intent.getConditions().isEmpty()) {<br>            sql.append(\" WHERE \");<br>            List&lt;String&gt; conditionStrings = intent.getConditions().stream()<br>                    .map(this::formatCondition)<br>                    .collect(Collectors.<em>toList<\/em>());<br>            sql.append(String.<em>join<\/em>(\" AND \", conditionStrings));<br>        } else {<br>            throw new RuntimeException(\"UPDATE operation must have conditions\");<br>        }<br><br>        return sql.toString();<br>    }<br><br>    \/\/ \u683c\u5f0f\u5316SQL\u503c<br>    private String formatValue(Object value) {<br>        if (value == null) {<br>            return \"NULL\";<br>        } else if (value instanceof String) {<br>            return \"'\" + ((String)value).replace(\"'\", \"''\") + \"'\";<br>        } else if (value instanceof Number) {<br>            return value.toString();<br>        } else if (value instanceof Boolean) {<br>            return ((Boolean)value) ? \"1\" : \"0\";<br>        } else {<br>            return \"'\" + value.toString().replace(\"'\", \"''\") + \"'\";<br>        }<br>    }<br><br>    \/\/ \u683c\u5f0f\u5316\u6761\u4ef6<br>    private String formatCondition(DbCondition condition) {<br>        return condition.getField() + \" \" + condition.getOperator() + \" \" +<br>                formatValue(condition.getValue());<br>    }<br><br>    \/\/ \u9a8c\u8bc1\u66f4\u65b0\u610f\u56fe<br>    private void validateUpdateIntent(DbIntent intent) {<br>        if (intent.getType() != DbOperationType.<em>UPDATE<\/em>) {<br>            throw new RuntimeException(\"Expected UPDATE operation, got: \" + intent.getType());<br>        }<br><br>        if (intent.getUpdateValues() == null || intent.getUpdateValues().isEmpty()) {<br>            throw new RuntimeException(\"No fields to update\");<br>        }<br><br>        if (intent.getConditions() == null || intent.getConditions().isEmpty()) {<br>            throw new RuntimeException(\"UPDATE operation must have conditions\");<br>        }<br><br>        \/\/ \u9a8c\u8bc1\u8868\u548c\u5b57\u6bb5\u662f\u5426\u5b58\u5728<br>        SchemaManager.TableSchema schema = schemaManager.getTableSchema(intent.getTargetTable());<br><br>        \/\/ \u9a8c\u8bc1\u66f4\u65b0\u5b57\u6bb5<br>        for (String field : intent.getUpdateValues().keySet()) {<br>            if (!schema.hasColumn(field)) {<br>                throw new RuntimeException(\"Column not found: \" + field);<br>            }<br>        }<br><br>        \/\/ \u9a8c\u8bc1\u6761\u4ef6\u5b57\u6bb5<br>        for (DbCondition condition : intent.getConditions()) {<br>            if (!schema.hasColumn(condition.getField())) {<br>                throw new RuntimeException(\"Column not found in condition: \" + condition.getField());<br>            }<br>        }<br>    }<br>}<\/code><\/pre>\n\n\n\n<p>UpdateOperationResponse.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;<br><br>import lombok.Data;<br><br>@Data<br>public class UpdateOperationResponse {<br>    private String originalQuery;<br>    private DbIntent intent;<br>    private String generatedSql;<br>    private DbOperationResult result;<br>    private String explanation;<br>}<\/code><\/pre>\n\n\n\n<p>WenxinClient.java<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package org.example;\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.node.ArrayNode;\nimport com.fasterxml.jackson.databind.node.ObjectNode;\nimport org.apache.http.HttpEntity;\nimport org.apache.http.client.methods.CloseableHttpResponse;\nimport org.apache.http.client.methods.HttpPost;\nimport org.apache.http.entity.StringEntity;\nimport org.apache.http.impl.client.CloseableHttpClient;\nimport org.apache.http.impl.client.HttpClients;\nimport org.apache.http.util.EntityUtils;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.stereotype.Service;\n\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@Service\npublic class WenxinClient {\n\n    @Value(\"${wenxin.api.key}\")\n    private String apiKey;\n\n    @Value(\"${wenxin.secret.key}\")\n    private String secretKey;\n\n    private static final String <em>TOKEN_URL <\/em>= \"https:\/\/aip.baidubce.com\/oauth\/2.0\/token\";\n    private static final String <em>API_URL <\/em>= \"https:\/\/api.baiduce.com\/rpc\/2.0\/ai_custom\/v1\/wenxinworkshop\/chat\/completions\";\n    private static final String <em>API_URL_V2 <\/em>= \"https:\/\/qianfan.baidubce.com\/v2\/chat\/completions\";\n    private static final String <em>MODEL <\/em>= \"ernie-bot-4\";\n    private static final String <em>MODEL_new_x1 <\/em>= \"ernie-x1-turbo-32k\";\n    private static final String <em>MODEL_new_4$5 <\/em>= \"ernie-4.5-turbo-128k\";\n\n\n\n    private String accessToken;\n    private long tokenExpireTime;\n\n    \/\/ \u83b7\u53d6\u8bbf\u95ee\u4ee4\u724c\n    private String getAccessToken() throws IOException {\n        \/\/ \u5982\u679c\u4ee4\u724c\u6709\u6548\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (accessToken != null &amp;&amp; System.<em>currentTimeMillis<\/em>() &lt; tokenExpireTime) {\n            return accessToken;\n        }\n\n        \/\/ \u5426\u5219\u8bf7\u6c42\u65b0\u4ee4\u724c\n        try (CloseableHttpClient httpClient = HttpClients.<em>createDefault<\/em>()) {\n            HttpPost httpPost = new HttpPost(<em>TOKEN_URL <\/em>+\n                    \"?grant_type=client_credentials&amp;client_id=\" + apiKey +\n                    \"&amp;client_secret=\" + secretKey);\n\n            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {\n                HttpEntity entity = response.getEntity();\n                String result = EntityUtils.<em>toString<\/em>(entity);\n\n                ObjectMapper mapper = new ObjectMapper();\n                JsonNode rootNode = mapper.readTree(result);\n\n                this.accessToken = rootNode.path(\"access_token\").asText();\n                int expiresIn = rootNode.path(\"expires_in\").asInt();\n                this.tokenExpireTime = System.<em>currentTimeMillis<\/em>() + (expiresIn * 1000L);\n\n                return this.accessToken;\n            }\n        }\n    }\n\n    \/\/ \u751f\u6210\u56de\u590d\n    public String generateCompletion(String prompt) throws IOException {\n\/\/        String token = getAccessToken();\n\n        try (CloseableHttpClient httpClient = HttpClients.<em>createDefault<\/em>()) {\n            HttpPost httpPost = new HttpPost(<em>API_URL_V2<\/em>);\n            httpPost.setHeader(\"Content-Type\", \"application\/json\");\n            httpPost.setHeader(\"Authorization\",\"Bearer \"+apiKey);\n\n            ObjectMapper mapper = new ObjectMapper();\n            ObjectNode requestBody = mapper.createObjectNode();\n            requestBody.put(\"model\", <em>MODEL_new_x1<\/em>);\n\n            ArrayNode messages = mapper.createArrayNode();\n            ObjectNode userMessage = mapper.createObjectNode();\n            userMessage.put(\"role\", \"user\");\n            userMessage.put(\"content\", prompt);\n            messages.add(userMessage);\n\n            requestBody.set(\"messages\", messages);\n\n            StringEntity entity = new StringEntity(requestBody.toString(), StandardCharsets.<em>UTF_8<\/em>);\n            httpPost.setEntity(entity);\n\n            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {\n                HttpEntity responseEntity = response.getEntity();\n                String result = EntityUtils.<em>toString<\/em>(responseEntity);\n\n                JsonNode rootNode = mapper.readTree(result);\n                if (rootNode.has(\"error_code\")) {\n                    throw new IOException(\"API error: \" + rootNode.path(\"error_msg\").asText());\n                }\n\n\/\/                return rootNode.path(\"result\").asText();\n                return rootNode.path(\"choices\").path(0).path(\"message\").path(\"content\").asText();\n            }\n        }\n    }\n\n    \/\/ \u53d1\u9001\u5e26\u6709\u7cfb\u7edf\u63d0\u793a\u7684\u5bf9\u8bdd\n    public String generateCompletionWithSystem(String systemPrompt, String userPrompt) throws IOException {\n        String token = getAccessToken();\n\n        try (CloseableHttpClient httpClient = HttpClients.<em>createDefault<\/em>()) {\n            HttpPost httpPost = new HttpPost(<em>API_URL <\/em>+ \"?access_token=\" + token);\n            httpPost.setHeader(\"Content-Type\", \"application\/json\");\n\n            ObjectMapper mapper = new ObjectMapper();\n            ObjectNode requestBody = mapper.createObjectNode();\n            requestBody.put(\"model\", <em>MODEL<\/em>);\n\n            ArrayNode messages = mapper.createArrayNode();\n\n            \/\/ \u6dfb\u52a0\u7cfb\u7edf\u6d88\u606f\n            ObjectNode systemMessage = mapper.createObjectNode();\n            systemMessage.put(\"role\", \"system\");\n            systemMessage.put(\"content\", systemPrompt);\n            messages.add(systemMessage);\n\n            \/\/ \u6dfb\u52a0\u7528\u6237\u6d88\u606f\n            ObjectNode userMessage = mapper.createObjectNode();\n            userMessage.put(\"role\", \"user\");\n            userMessage.put(\"content\", userPrompt);\n            messages.add(userMessage);\n\n            requestBody.set(\"messages\", messages);\n\n            StringEntity entity = new StringEntity(requestBody.toString(), StandardCharsets.<em>UTF_8<\/em>);\n            httpPost.setEntity(entity);\n\n            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {\n                HttpEntity responseEntity = response.getEntity();\n                String result = EntityUtils.<em>toString<\/em>(responseEntity);\n\n                JsonNode rootNode = mapper.readTree(result);\n                if (rootNode.has(\"error_code\")) {\n                    throw new IOException(\"API error: \" + rootNode.path(\"error_msg\").asText());\n                }\n\n                return rootNode.path(\"result\").asText();\n            }\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p>\u4ee5\u4e0b\u662fsrc\/main\/resoures\u9700\u8981\u4fee\u6539\u4ee5\u53ca\u6dfb\u52a0\u6587\u4ef6<\/p>\n\n\n\n<p>application.properties<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spring.application.name=Springboot\nspring.datasource.url=jdbc:h2:mem:testdb\nspring.datasource.driverClassName=org.h2.Driver\nspring.datasource.username=sa\nspring.datasource.password=sa123\nspring.h2.console.enabled=true\nspring.h2.console.path=\/h2-console\n\nopenai.api.key=your_openai_api_key  \/\/\u8fd9\u4e2a\u4e0d\u9700\u8981\u4fee\u6539\nopenai.model=gpt-3.5-turbo\n\n# ???????? - ???????API??\nwenxin.api.key=\u7528\u4f60\u81ea\u5df1\u7684\u6587\u8a00\u4e00\u5fc3api\nwenxin.secret.key=\u7528\u4f60\u81ea\u5df1\u7684\u6587\u8a00\u4e00\u5fc3api   \/\/\u6ca1\u9519\u4e24\u4e2a\u90fd\u662f\u4e00\u6837\u7684\uff0c\u800c\u4e14\u53ea\u9700\u8981\u4fee\u6539\u8fd9\u4e24\u884c\n\nspring.sql.init.mode=<em>always\n<\/em>spring.sql.init.schema-locations=classpath:schema.sql<\/code><\/pre>\n\n\n\n<p>schema.sql<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DROP TABLE IF EXISTS products;<br><br>CREATE TABLE products (<br>                          id INT AUTO_INCREMENT PRIMARY KEY,<br>                          product_name VARCHAR(100) NOT NULL,<br>                          category VARCHAR(50),<br>                          price DECIMAL(10, 2),<br>                          stock INT,<br>                          description TEXT,<br>                          created_at TIMESTAMP DEFAULT <em>CURRENT_TIMESTAMP<br><\/em>);<br><br>INSERT INTO products (product_name, category, price, stock, description) VALUES<br>                                                                             ('iPhone 13', 'Electronics', 5999.00, 100, 'Apple iPhone 13 smartphone with A15 Bionic chip'),<br>                                                                             ('Samsung Galaxy S21', 'Electronics', 4599.00, 85, 'Samsung flagship phone with 5G capability'),<br>                                                                             ('Macbook Pro', 'Computers', 12999.00, 30, 'Apple laptop with M1 Pro chip'),<br>                                                                             ('Dell XPS 13', 'Computers', 8299.00, 45, 'Dell premium ultrabook with Intel Core i7'),<br>                                                                             ('Logitech MX Master 3', 'Accessories', 599.00, 200, 'Advanced wireless mouse'),<br>                                                                             ('Sony WH-1000XM4', 'Audio', 2299.00, 60, 'Wireless noise-cancelling headphones');<\/code><\/pre>\n\n\n\n<p>pom.xml<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;<br>&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"<br>         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 https:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;<br>    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;<br>    &lt;parent&gt;<br>        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br>        &lt;artifactId&gt;spring-boot-starter-parent&lt;\/artifactId&gt;<br>        &lt;version&gt;2.7.18&lt;\/version&gt;<br>        &lt;relativePath\/&gt;<br>    &lt;\/parent&gt;<br>    &lt;groupId&gt;com.example&lt;\/groupId&gt;<br>    &lt;artifactId&gt;aidb&lt;\/artifactId&gt;<br>    &lt;version&gt;0.0.1-SNAPSHOT&lt;\/version&gt;<br>    &lt;description&gt;Spring Boot for database updates&lt;\/description&gt;<br><br>    &lt;properties&gt;<br>        &lt;java.version&gt;11&lt;\/java.version&gt;<br>    &lt;\/properties&gt;<br><br>    &lt;dependencies&gt;<br>        &lt;!-- Spring Boot \u57fa\u7840\u4f9d\u8d56 --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br>            &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;<br>        &lt;\/dependency&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br>            &lt;artifactId&gt;spring-boot-starter-jdbc&lt;\/artifactId&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- H2\u5185\u5b58\u6570\u636e\u5e93 --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;com.h2database&lt;\/groupId&gt;<br>            &lt;artifactId&gt;h2&lt;\/artifactId&gt;<br>            &lt;scope&gt;runtime&lt;\/scope&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- HTTP\u5ba2\u6237\u7aef --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.apache.httpcomponents&lt;\/groupId&gt;<br>            &lt;artifactId&gt;httpclient&lt;\/artifactId&gt;<br>            &lt;version&gt;4.5.14&lt;\/version&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- OpenAI\u5ba2\u6237\u7aef --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;com.theokanning.openai-gpt3-java&lt;\/groupId&gt;<br>            &lt;artifactId&gt;service&lt;\/artifactId&gt;<br>            &lt;version&gt;0.12.0&lt;\/version&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- Lombok --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.projectlombok&lt;\/groupId&gt;<br>            &lt;artifactId&gt;lombok&lt;\/artifactId&gt;<br>            &lt;optional&gt;true&lt;\/optional&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- Jackson --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;com.fasterxml.jackson.core&lt;\/groupId&gt;<br>            &lt;artifactId&gt;jackson-databind&lt;\/artifactId&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- \u6d4b\u8bd5\u4f9d\u8d56 --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br>            &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;<br>            &lt;scope&gt;test&lt;\/scope&gt;<br>        &lt;\/dependency&gt;<br>        &lt;!-- Spring Core --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework&lt;\/groupId&gt;<br>            &lt;artifactId&gt;spring-core&lt;\/artifactId&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- Spring Beans --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework&lt;\/groupId&gt;<br>            &lt;artifactId&gt;spring-beans&lt;\/artifactId&gt;<br>        &lt;\/dependency&gt;<br><br>        &lt;!-- Spring Context --&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework&lt;\/groupId&gt;<br>            &lt;artifactId&gt;spring-context&lt;\/artifactId&gt;<br>        &lt;\/dependency&gt;<br>    &lt;\/dependencies&gt;<br><br>    &lt;build&gt;<br>        &lt;plugins&gt;<br>            &lt;plugin&gt;<br>                &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br>                &lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;<br>                &lt;configuration&gt;<br>                    &lt;excludes&gt;<br>                        &lt;exclude&gt;<br>                            &lt;groupId&gt;org.projectlombok&lt;\/groupId&gt;<br>                            &lt;artifactId&gt;lombok&lt;\/artifactId&gt;<br>                        &lt;\/exclude&gt;<br>                    &lt;\/excludes&gt;<br>                &lt;\/configuration&gt;<br>            &lt;\/plugin&gt;<br>        &lt;\/plugins&gt;<br>    &lt;\/build&gt;<br>&lt;\/project&gt;<\/code><\/pre>\n\n\n\n<p>\u5199\u5b8cpom.xml\uff0c\u8bf7\u53f3\u51fbpom.xml\uff0c<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-13-721x1024.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"721\" height=\"1024\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-13-721x1024.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-84\" style=\"width:529px;height:auto\"  sizes=\"auto, (max-width: 721px) 100vw, 721px\" \/><\/div><\/figure>\n\n\n\n<p>\u6700\u540e\u8fd0\u884cDbApplication.java\uff0c\u5982\u56fe\uff0c\u5c31\u4ee3\u8868\u4f60\u7684Spring Boot\u5df2\u7ecf\u6253\u5f00\u5566~<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-14-1024x371.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"371\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-14-1024x371.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-85\"  sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div><\/figure>\n\n\n\n<p>\u6d4b\u8bd5\u529f\u80fd\uff1a<\/p>\n\n\n\n<p>\u5e94\u7528\u542f\u52a8\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u6d4b\u8bd5<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -X POST \"http:\/\/localhost:8080\/api\/db\/update?query=\u5c06iPhone 13\u7684\u4ef7\u683c\u6539\u4e3a4999\u5143\"<\/code><\/pre>\n\n\n\n<p>\u6211\u662f\u8bf7\u6559\u9999\u9999\u540c\u5b66\u5b66\u4e60\u4f7f\u7528apifox\uff0c\u6ca1\u4e0b\u8f7d\u9700\u8981\u53bb\u5b98\u7f51\u4e0b\u8f7d\u54df~\u4e0b\u9762\u662f\u4f7f\u7528apifox\u7684\u8fc7\u7a0b<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-16-1024x633.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"633\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-16-1024x633.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-91\"  sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div><\/figure>\n\n\n\n<p>\u70b9\u51fb\u53d1\u9001\u4e4b\u540e\u9700\u8981\u7b49\u4e00\u7b49&#8230;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-17-1024x518.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"518\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-17-1024x518.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-93\"  sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div><\/figure>\n\n\n\n<p>\u201c\u8be5\u64cd\u4f5c\u6210\u529f\u4fee\u6539\u4e861\u6761\u7b26\u5408\u6761\u4ef6\u7684\u8bb0\u5f55\u201d\uff0c\u606d\u559c\u4f60\uff0c\u6210\u529f\u5566\uff01<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-18-1024x450.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"450\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-18-1024x450.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-94\"  sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div><\/figure>\n\n\n\n<p>\u8bbf\u95eeH2\u63a7\u5236\u53f0\u67e5\u770b\u6570\u636e\u53d8\u5316<\/p>\n\n\n\n<p>1.\u6253\u5f00\u6d4f\u89c8\u5668\u8bbf\u95ee\uff1a<a href=\"http:\/\/localhost:8080\/h2-console\">http:\/\/localhost:8080\/h2-console<\/a><\/p>\n\n\n\n<p>2.\u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u94fe\u63a5\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>JDBC URL\uff1a<strong>jdbc:h2:mem:testdb<\/strong><\/li>\n\n\n\n<li>User Name\uff1a<strong>sa<\/strong><\/li>\n\n\n\n<li>Password\uff1a<strong>sa123<\/strong><\/li>\n<\/ul>\n\n\n\n<p>3.\u8fde\u63a5\u540e\u6267\u884cSQL\uff1aSELECT * FROM products\u67e5\u770b\u66f4\u65b0\u7ed3\u679c<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-19-1024x497.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"497\" data-original=\"http:\/\/caihh.top\/wp-content\/uploads\/2025\/09\/image-19-1024x497.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-97\"  sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div><\/figure>\n\n\n\n<p>\u66f4\u591a\u7684\u53ef\u4ee5\u53bb\u5fae\u4fe1\u516c\u4f17\u53f7\uff0c\u641c\u7d22 \u98ce\u50cf\u5357 \u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u6587\u57fa\u4e8eSpring Boot\u6846\u67b6\uff0c\u7ed3\u5408\u5927\u6a21\u578b\uff08\u672c\u6587\u4f7f\u7528\u4e86\u767e\u5ea6\u6587\u5fc3\u4e00\u8a00\uff09\u7684\u8bed\u4e49\u7406\u89e3\u80fd\u529b\uff0c\u6784\u5efa\u4e86\u4e00\u5957\u81ea\u7136\u8bed\u8a00\u9a71\u52a8 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":34,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-80","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-learn"],"_links":{"self":[{"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/posts\/80","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/comments?post=80"}],"version-history":[{"count":9,"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions"}],"predecessor-version":[{"id":103,"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions\/103"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/media\/34"}],"wp:attachment":[{"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/media?parent=80"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/categories?post=80"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/caihh.top\/index.php\/wp-json\/wp\/v2\/tags?post=80"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}