
以下是使用最新Java技术构建的学生信息管理系统的实操内容,包含详细的技术方案和代码说明:
使用Spring Initializr创建基础项目,添加以下依赖:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}创建Student实体类,使用JPA注解映射数据库表:
@Entity
@Table(name = "students")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "姓名不能为空")
@Size(max = 50)
private String name;
@NotNull(message = "年龄不能为空")
@Min(1)
@Max(100)
private Integer age;
@Email(message = "邮箱格式不正确")
@Size(max = 100)
private String email;
@CreationTimestamp
private LocalDateTime createTime;
@UpdateTimestamp
private LocalDateTime updateTime;
}使用Spring Data JPA的JpaRepository接口:
public interface StudentRepository extends JpaRepository<Student, Long> {
List<Student> findByNameContaining(String name);
}添加业务逻辑和事务管理:
@Service
@Transactional
public class StudentService {
private final StudentRepository repository;
public StudentService(StudentRepository repository) {
this.repository = repository;
}
public Student createStudent(Student student) {
return repository.save(student);
}
public List<Student> searchStudents(String name) {
return repository.findByNameContaining(name);
}
public void deleteStudent(Long id) {
repository.deleteById(id);
}
// 其他业务方法...
}使用Spring MVC创建API接口:
@RestController
@RequestMapping("/api/students")
@CrossOrigin(origins = "http://localhost:5173")
public class StudentController {
private final StudentService service;
public StudentController(StudentService service) {
this.service = service;
}
@PostMapping
public ResponseEntity<Student> create(@Valid @RequestBody Student student) {
Student saved = service.createStudent(student);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}
@GetMapping
public ResponseEntity<List<Student>> search(@RequestParam(required = false) String name) {
List<Student> students = service.searchStudents(name);
return ResponseEntity.ok(students);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
service.deleteStudent(id);
return ResponseEntity.noContent().build();
}
// 其他API方法...
}配置Spring Security和JWT:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
// 其他安全配置...
}使用Vite初始化项目:
npm create vite@latest client -- --template react-ts
cd client
npm install axios react-router-dom @tanstack/react-query使用Axios和React Query:
// src/api/studentApi.ts
import axios from 'axios';
import { useQuery, useMutation } from '@tanstack/react-query';
const apiClient = axios.create({
baseURL: 'http://localhost:8080/api',
headers: {
'Content-Type': 'application/json',
},
});
export const useGetStudents = (name?: string) => {
return useQuery({
queryKey: ['students', name],
queryFn: () =>
apiClient.get('/students', { params: { name } }).then(res => res.data),
});
};
export const useCreateStudent = () => {
return useMutation({
mutationFn: (student: any) =>
apiClient.post('/students', student).then(res => res.data),
});
};// src/components/StudentList.tsx
import { useGetStudents } from '../api/studentApi';
import { Table, Button } from 'antd';
const StudentList = ({ searchTerm }: { searchTerm?: string }) => {
const { data: students, isLoading, error } = useGetStudents(searchTerm);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
const columns = [
{ title: 'ID', dataIndex: 'id' },
{ title: '姓名', dataIndex: 'name' },
{ title: '年龄', dataIndex: 'age' },
{ title: '邮箱', dataIndex: 'email' },
{ title: '操作', render: (_, record) => (
<Button danger onClick={() => handleDelete(record.id)}>
删除
</Button>
)}
];
return <Table dataSource={students} columns={columns} rowKey="id" />;
};// src/components/StudentForm.tsx
import { Form, Input, Button, Select, notification } from 'antd';
import { useCreateStudent } from '../api/studentApi';
const StudentForm = () => {
const { mutate, isLoading } = useCreateStudent();
const [form] = Form.useForm();
const onFinish = (values: any) => {
mutate(values, {
onSuccess: () => {
notification.success({ message: '创建成功' });
form.resetFields();
},
onError: (err: any) => {
notification.error({ message: '创建失败', description: err.message });
},
});
};
return (
<Form form={form} onFinish={onFinish}>
<Form.Item
name="name"
rules={[{ required: true, message: '请输入姓名' }]}
>
<Input placeholder="姓名" />
</Form.Item>
<Form.Item
name="age"
rules={[{ required: true, message: '请输入年龄' }]}
>
<Input.Number placeholder="年龄" />
</Form.Item>
<Form.Item
name="email"
rules={[{ required: true, message: '请输入邮箱' }, { type: 'email' }]}
>
<Input placeholder="邮箱" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" loading={isLoading}>
提交
</Button>
</Form.Item>
</Form>
);
};# 基础镜像
FROM openjdk:17-jdk-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
# 下载依赖
RUN ./mvnw dependency:go-offline -B
# 复制源代码
COPY src ./src
# 构建应用
RUN ./mvnw package -DskipTests
# 暴露端口
EXPOSE 8080
# 启动应用
CMD ["java", "-jar", "target/student-management-0.0.1-SNAPSHOT.jar"]version: '3.8'
services:
db:
image: postgres:15
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
POSTGRES_DB: student_db
ports:
- "5432:5432"
redis:
image: redis:7
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- db
- redis
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/student_db
SPRING_DATASOURCE_USERNAME: admin
SPRING_DATASOURCE_PASSWORD: password
SPRING_REDIS_HOST: redis
frontend:
build: ./frontend
ports:
- "5173:80"
depends_on:
- backend
volumes:
postgres-data:@SpringBootTest
class StudentServiceTest {
@Autowired
private StudentService service;
@Autowired
private StudentRepository repository;
@Test
void testCreateStudent() {
Student student = Student.builder()
.name("测试学生")
.age(20)
.email("test@example.com")
.build();
Student saved = service.createStudent(student);
assertNotNull(saved.getId());
assertEquals("测试学生", saved.getName());
// 验证数据库中是否存在
assertTrue(repository.existsById(saved.getId()));
}
}import { render, screen } from '@testing-library/react';
import { StudentList } from './StudentList';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
test('renders student list', async () => {
const queryClient = new QueryClient();
const mockStudents = [
{ id: 1, name: '张三', age: 20, email: 'zhangsan@example.com' },
];
jest.spyOn(queryClient, 'fetchQuery').mockResolvedValue(mockStudents);
render(
<QueryClientProvider client={queryClient}>
<StudentList />
</QueryClientProvider>
);
await screen.findByText('张三');
expect(screen.getByText('张三')).toBeInTheDocument();
});通过这个实操项目,你可以掌握Java全栈开发的完整流程,包括后端API设计、前端组件开发、容器化部署以及测试与监控等关键环节。项目采用了当前业界主流的技术栈,符合企业级应用开发标准。
Java 学生信息管理系统,Spring Boot 3,React, 实操指南,Java 开发,管理系统教程,Spring Boot 实战,React 项目开发,学生管理系统,Java 编程,前后端开发,Spring Boot 框架,React 教程,管理系统开发,Java 项目实战
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。