refactor(project):重构项目结构并迁移至snails-chat模块- 将项目主模块更名为snails-chat,调整包结构
- 移除JPA相关依赖,替换为MyBatis-Plus- 数据库从MySQL迁移至PostgreSQL- 移除QueryTool工具类及相关依赖- 更新Redis配置,使用JSON序列化- 移除DashScopeController及AIResponse类 - 添加User实体类及Mapper接口 - 调整ChatClientConfiguration配置类- 更新pom.xml依赖管理及模块配置
This commit is contained in:
45
pom.xml
45
pom.xml
@@ -6,23 +6,33 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.6</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<groupId>com.hanserwei</groupId>
|
||||
<artifactId>snails-ai</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>snails-ai</name>
|
||||
<description>snails-ai</description>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>snails-chat</module>
|
||||
</modules>
|
||||
|
||||
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<spring-ai.version>1.0.3</spring-ai.version>
|
||||
<jasypt-starter-version>3.0.5</jasypt-starter-version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
@@ -33,19 +43,10 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- spring-ai-alibaba-starter -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud.ai</groupId>
|
||||
@@ -55,7 +56,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.ulisesbocchio</groupId>
|
||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||
<version>3.0.5</version>
|
||||
<version>${jasypt-starter-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud.ai</groupId>
|
||||
@@ -65,6 +66,19 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-jsqlparser</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
@@ -83,6 +97,13 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-bom</artifactId>
|
||||
<version>3.5.14</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
28
snails-chat/pom.xml
Normal file
28
snails-chat/pom.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.hanserwei</groupId>
|
||||
<artifactId>snails-ai</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.hanserwei.chat</groupId>
|
||||
<artifactId>snails-chat</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>snails-chat</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.hanserwei.chat;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.hanserwei.chat.domain.mapper")
|
||||
public class SnailsChatApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SnailsChatApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.hanserwei.snailsai.config;
|
||||
package com.hanserwei.chat.config;
|
||||
|
||||
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
|
||||
import com.alibaba.cloud.ai.memory.redis.BaseRedisChatMemoryRepository;
|
||||
import com.alibaba.cloud.ai.memory.redis.LettuceRedisChatMemoryRepository;
|
||||
import com.hanserwei.snailsai.tools.QueryTool;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
|
||||
@@ -29,8 +28,6 @@ public class ChatClientConfiguration {
|
||||
|
||||
@Resource
|
||||
private DashScopeChatModel dashScopeChatModel;
|
||||
@Resource
|
||||
private QueryTool queryTool;
|
||||
|
||||
@Bean
|
||||
public BaseRedisChatMemoryRepository redisChatMemoryRepository() {
|
||||
@@ -54,7 +51,6 @@ public class ChatClientConfiguration {
|
||||
@Bean
|
||||
public ChatClient dashScopeChatClient(ChatMemory chatMemory) {
|
||||
return ChatClient.builder(dashScopeChatModel)
|
||||
.defaultTools(queryTool)
|
||||
.defaultAdvisors(PromptChatMemoryAdvisor.builder(chatMemory).build(), new SimpleLoggerAdvisor())
|
||||
.build();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.hanserwei.snailsai.config;
|
||||
package com.hanserwei.chat.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.hanserwei.chat.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
// 设置 RedisTemplate 的连接工厂
|
||||
redisTemplate.setConnectionFactory(connectionFactory);
|
||||
|
||||
// 使用 StringRedisSerializer 来序列化和反序列化 redis 的 key 值,确保 key 是可读的字符串
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
|
||||
// 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis 的 value 值, 确保存储的是 JSON 格式
|
||||
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
redisTemplate.setValueSerializer(serializer);
|
||||
redisTemplate.setHashValueSerializer(serializer);
|
||||
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.hanserwei.chat.domain.dataobject;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName(value = "t_user")
|
||||
public class User {
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
@TableField(value = "\"name\"")
|
||||
private String name;
|
||||
|
||||
@TableField(value = "email")
|
||||
private String email;
|
||||
|
||||
@TableField(value = "age")
|
||||
private Integer age;
|
||||
|
||||
@TableField(value = "created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@TableField(value = "is_active")
|
||||
private Boolean isActive;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.hanserwei.chat.domain.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.hanserwei.chat.domain.dataobject.User;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.hanserwei.chat.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hanserwei.chat.domain.dataobject.User;
|
||||
|
||||
public interface UserService extends IService<User> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.hanserwei.chat.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.hanserwei.chat.domain.dataobject.User;
|
||||
import com.hanserwei.chat.domain.mapper.UserMapper;
|
||||
import com.hanserwei.chat.service.UserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.hanserwei.snailsai.utils;
|
||||
package com.hanserwei.chat.utils;
|
||||
|
||||
import org.jasypt.util.text.AES256TextEncryptor;
|
||||
|
||||
@@ -9,14 +9,6 @@ spring:
|
||||
name: snails-ai
|
||||
banner:
|
||||
location: config/banner.txt
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
properties:
|
||||
# 开启 SQL 语句格式化 (重点:让 SQL 易读)
|
||||
hibernate.format_sql: true
|
||||
# 开启 SQL 语法高亮 (重点:让 SQL 醒目)
|
||||
hibernate.highlight_sql: true
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
@@ -32,10 +24,10 @@ spring:
|
||||
min-idle: 10
|
||||
time-between-eviction-runs: 10000
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/snails_ai?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowMultiQueries=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: mysql
|
||||
driver-class-name: org.postgresql.Driver
|
||||
url: jdbc:postgresql://localhost:5432/postgres
|
||||
username: postgres
|
||||
password: postgressql
|
||||
# HikariCP 连接池配置
|
||||
hikari:
|
||||
maximum-pool-size: 20 # 最大连接数设置为 20
|
||||
@@ -55,9 +47,15 @@ spring:
|
||||
options:
|
||||
model: qwen-plus
|
||||
temperature: 0.5
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||
global-config:
|
||||
banner: false
|
||||
mapper-locations: classpath*:/mapperxml/*.xml
|
||||
logging:
|
||||
level:
|
||||
org.hibernate.SQL: debug
|
||||
# 隐藏掉 Hibernate 冗长的连接池 INFO 信息
|
||||
org.hibernate.orm.connections.pooling: WARN
|
||||
org.springframework.ai.chat.client.advisor: DEBUG
|
||||
18
snails-chat/src/main/resources/mapperxml/UserMapper.xml
Normal file
18
snails-chat/src/main/resources/mapperxml/UserMapper.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.hanserwei.chat.domain.mapper.UserMapper">
|
||||
<resultMap id="BaseResultMap" type="com.hanserwei.chat.domain.dataobject.User">
|
||||
<!--@mbg.generated-->
|
||||
<!--@Table t_user-->
|
||||
<id column="id" jdbcType="INTEGER" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="email" jdbcType="VARCHAR" property="email" />
|
||||
<result column="age" jdbcType="INTEGER" property="age" />
|
||||
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
|
||||
<result column="is_active" jdbcType="BOOLEAN" property="isActive" />
|
||||
</resultMap>
|
||||
<sql id="Base_Column_List">
|
||||
<!--@mbg.generated-->
|
||||
id, "name", email, age, created_at, is_active
|
||||
</sql>
|
||||
</mapper>
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.hanserwei.snailsai;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SnailsAiApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SnailsAiApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.hanserwei.snailsai.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.hanserwei.snailsai.controller;
|
||||
|
||||
import com.hanserwei.snailsai.model.AIResponse;
|
||||
import com.hanserwei.snailsai.dto.ChatMessageDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.ai.chat.memory.ChatMemory;
|
||||
import org.springframework.ai.chat.messages.UserMessage;
|
||||
import org.springframework.ai.chat.model.Generation;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@Slf4j
|
||||
@RequestMapping("/dashscope")
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
public class DashScopeController {
|
||||
|
||||
@Resource
|
||||
private ChatClient dashScopeChatClient;
|
||||
|
||||
@PostMapping(value = "/generateStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public Flux<AIResponse> generateStream(@RequestBody ChatMessageDTO chatMessageDTO) {
|
||||
// 构建提示词
|
||||
Prompt prompt = new Prompt(new UserMessage(chatMessageDTO.getMessage()));
|
||||
|
||||
// 流式输出
|
||||
return dashScopeChatClient.prompt(prompt)
|
||||
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatMessageDTO.getConversionId()))
|
||||
.stream() // 流式输出
|
||||
.chatResponse()
|
||||
.mapNotNull(chatResponse -> {
|
||||
Generation generation = chatResponse.getResult();
|
||||
String text = generation.getOutput().getText();
|
||||
return AIResponse.builder().v(text).build();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.hanserwei.snailsai.controller;
|
||||
|
||||
import com.hanserwei.snailsai.entity.UserEntity;
|
||||
import com.hanserwei.snailsai.service.UserService;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
public class TestDataController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
public TestDataController(UserService userService) {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/test/generate-users?count=100
|
||||
* 插入假数据用于分页测试
|
||||
*/
|
||||
@PostMapping("/api/test/generate-users")
|
||||
public String generateTestData(@RequestParam(defaultValue = "100") int count) {
|
||||
List<UserEntity> insertedUsers = userService.insertDummyUsers(count);
|
||||
return String.format("成功插入了 %d 条假数据!", insertedUsers.size());
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.hanserwei.snailsai.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class ChatMessageDTO {
|
||||
|
||||
private String message;
|
||||
|
||||
private Long conversionId;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package com.hanserwei.snailsai.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(
|
||||
name = "users",
|
||||
uniqueConstraints = @UniqueConstraint(
|
||||
name = "UQ_USER_NAME",
|
||||
columnNames = {"user_name"} // 指定应用约束的列
|
||||
)
|
||||
)
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class UserEntity implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 812305521669146765L;
|
||||
|
||||
// 1. 主键:自增ID
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
// 2. 用户名:不能为空,长度限制
|
||||
@Column(name = "user_name", nullable = false, unique = true, length = 50)
|
||||
private String username;
|
||||
|
||||
// 3. 密码:加密存储,不能为空,长度需足够长
|
||||
@Column(name = "password", nullable = false, length = 100)
|
||||
private String password;
|
||||
|
||||
// 4. 逻辑外键
|
||||
@Column(name = "hobby_id")
|
||||
private Long hobbyId;
|
||||
|
||||
// 5. 补充审计字段 (推荐)
|
||||
@Column(name = "create_time", nullable = false)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Column(name = "update_time")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.hanserwei.snailsai.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class AIResponse {
|
||||
// 流式响应内容
|
||||
private String v;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.hanserwei.snailsai.repository;
|
||||
|
||||
import com.hanserwei.snailsai.entity.UserEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.ai.tool.annotation.Tool;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<UserEntity, Long> {
|
||||
|
||||
@NotNull List<UserEntity> findAll();
|
||||
|
||||
@NotNull List<UserEntity> findAllByIdIn(List<Long> ids);
|
||||
|
||||
@NotNull List<UserEntity> findAllByUsernameContaining(String name);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package com.hanserwei.snailsai.service;
|
||||
|
||||
import com.hanserwei.snailsai.entity.UserEntity;
|
||||
import com.hanserwei.snailsai.repository.UserRepository;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
// 构造器注入
|
||||
public UserService(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量生成并插入指定数量的假用户数据
|
||||
* @param count 要插入的用户数量
|
||||
* @return 插入成功的用户列表
|
||||
*/
|
||||
@Transactional // 确保整个批量操作在一个事务中完成
|
||||
public List<UserEntity> insertDummyUsers(int count) {
|
||||
if (count <= 0) {
|
||||
return List.of(); // 返回空列表
|
||||
}
|
||||
|
||||
List<UserEntity> dummyUsers = new ArrayList<>(count);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 确保用户名是唯一的
|
||||
// 我们可以先获取当前数据库中用户数量,作为生成唯一用户名的起始点
|
||||
long startId = userRepository.count();
|
||||
|
||||
for (int i = 1; i <= count; i++) {
|
||||
|
||||
// 使用 startId + i 来保证生成的用户名在多次运行时尽可能不重复
|
||||
long userIndex = startId + i;
|
||||
|
||||
// 注意:密码通常应该是加密后的,这里为了演示使用明文
|
||||
UserEntity user = new UserEntity(
|
||||
null, // ID 设为 null,让 JPA 自动生成
|
||||
"testUser_" + userIndex, // 确保用户名唯一
|
||||
"123456", // 模拟一个加密后的密码,或者使用一个测试用的明文,例如 "password"
|
||||
(long) (i % 3) + 1, // 随机分配一个 hobbyId (例如 1, 2, 3)
|
||||
now.plusSeconds(i), // 模拟创建时间略微递增
|
||||
null // updateTime 初始为 null
|
||||
);
|
||||
dummyUsers.add(user);
|
||||
}
|
||||
|
||||
// 使用 JpaRepository 的 saveAll 方法进行批量插入,效率比单个 save 要高
|
||||
return userRepository.saveAll(dummyUsers);
|
||||
}
|
||||
|
||||
public List<UserEntity> findAll() {
|
||||
return userRepository.findAll();
|
||||
}
|
||||
|
||||
public List<UserEntity> findAllByIdIn(List<Long> ids) {
|
||||
return userRepository.findAllByIdIn(ids);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.hanserwei.snailsai.tools;
|
||||
|
||||
import com.hanserwei.snailsai.entity.UserEntity;
|
||||
import com.hanserwei.snailsai.service.UserService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.ai.tool.annotation.Tool;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class QueryTool {
|
||||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@Tool(name = "findAll", description = "查询所有用户")
|
||||
public List<UserEntity> findAll() {
|
||||
return userService.findAll();
|
||||
}
|
||||
|
||||
@Tool(name = "findAllByIdIn", description = "根据id列表查询用户")
|
||||
public List<UserEntity> findAllByIdIn(List<Long> ids) {
|
||||
return userService.findAllByIdIn(ids);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.hanserwei.snailsai;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class SnailsAiApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user