package com.ch.lab.entity;
import lombok.Data;
@Data
public class Student {
private Integer sid;
private String sname;
private String sgender;
private Integer sage;
}
<?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.ch.lab.repository.StudentRepository">
<resultMap id="StudentResultMap" type="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="sgender" column="sgender"/>
<result property="sage" column="sage"/>
</resultMap>
<!-- 1. 查询所有学生 -->
<select id="findAll" resultMap="StudentResultMap">
SELECT sid, sname, sgender, sage FROM student
</select>
<!-- 2. 条件查询(where + if 动态SQL) -->
<select id="selectByCondition" parameterType="Student" resultMap="StudentResultMap">
SELECT sid, sname, sgender, sage FROM student
<where>
<if test="sname != null and sname != ''">
AND sname LIKE CONCAT('%', #{sname}, '%')
</if>
<if test="sgender != null and sgender != ''">
AND sgender = #{sgender}
</if>
<if test="sage != null">
AND sage = #{sage}
</if>
</where>
</select>
<!-- 3. 添加学生(主键回填) -->
<insert id="addStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="sid">
INSERT INTO student (sname, sgender, sage)
VALUES (#{sname}, #{sgender}, #{sage})
</insert>
<!-- 4. 更新学生(set + if 动态SQL) -->
<update id="updateStudent" parameterType="Student">
UPDATE student
<set>
<if test="sname != null and sname != ''">
sname = #{sname},
</if>
<if test="sgender != null and sgender != ''">
sgender = #{sgender},
</if>
<if test="sage != null">
sage = #{sage},
</if>
</set>
WHERE sid = #{sid}
</update>
<!-- 5. 删除学生 -->
<delete id="deleteStudent" parameterType="int">
DELETE FROM student WHERE sid = #{sid}
</delete>
<!-- 6. 根据ID列表查询(foreach) -->
<select id="selectByIds" resultMap="StudentResultMap">
SELECT sid, sname, sgender, sage FROM student
WHERE sid IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 7. 根据年龄范围查询(@Param) -->
<select id="selectByAgeRange" resultMap="StudentResultMap">
SELECT sid, sname, sgender, sage FROM student
WHERE sage BETWEEN #{minAge} AND #{maxAge}
</select>
</mapper>
package com.ch.lab.repository;
import com.ch.lab.entity.Student;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface StudentRepository {
List<Student> findAll();
List<Student> selectByCondition(Student student);
int addStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int sid);
List<Student> selectByIds(List<Integer> ids);
List<Student> selectByAgeRange(@Param("minAge") int minAge, @Param("maxAge") int maxAge);
}
package com.ch.lab.service;
import com.ch.lab.entity.Student;
import java.util.List;
public interface StudentService {
List<Student> findAll();
List<Student> selectByCondition(Student student);
int addStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int sid);
List<Student> selectByIds(List<Integer> ids);
List<Student> selectByAgeRange(int minAge, int maxAge);
}
package com.ch.lab.service;
import com.ch.lab.entity.Student;
import com.ch.lab.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentRepository studentRepository;
@Override
public List<Student> findAll() {
return studentRepository.findAll();
}
@Override
public List<Student> selectByCondition(Student student) {
return studentRepository.selectByCondition(student);
}
@Override
public int addStudent(Student student) {
return studentRepository.addStudent(student);
}
@Override
public int updateStudent(Student student) {
return studentRepository.updateStudent(student);
}
@Override
public int deleteStudent(int sid) {
return studentRepository.deleteStudent(sid);
}
@Override
public List<Student> selectByIds(List<Integer> ids) {
return studentRepository.selectByIds(ids);
}
@Override
public List<Student> selectByAgeRange(int minAge, int maxAge) {
return studentRepository.selectByAgeRange(minAge, maxAge);
}
}
package com.ch.lab.controller;
import com.ch.lab.entity.Student;
import com.ch.lab.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/students")
public class StudentController {
@Autowired
private StudentService studentService;
// 1. GET /lab_backend/students - 查询所有学生
@GetMapping
public List<Student> findAll() {
return studentService.findAll();
}
// 2. GET /lab_backend/students/search?sgender=男 - 条件查询
@GetMapping("/search")
public List<Student> selectByCondition(Student student) {
return studentService.selectByCondition(student);
}
// 3. GET /lab_backend/students/age?min=20&max=22 - 年龄范围查询
@GetMapping("/age")
public List<Student> selectByAgeRange(@RequestParam("min") int minAge, @RequestParam("max") int maxAge) {
return studentService.selectByAgeRange(minAge, maxAge);
}
// 4. POST /lab_backend/students - 添加学生
@PostMapping
public int addStudent(@RequestBody Student student) {
return studentService.addStudent(student);
}
// 5. PUT /lab_backend/students - 更新学生
@PutMapping
public int updateStudent(@RequestBody Student student) {
return studentService.updateStudent(student);
}
// 6. DELETE /lab_backend/students/{sid} - 删除学生
@DeleteMapping("/{sid}")
public int deleteStudent(@PathVariable("sid") int sid) {
return studentService.deleteStudent(sid);
}
// 7. GET /lab_backend/students/batch?ids=1,3,5 - 批量查询
@GetMapping("/batch")
public List<Student> selectByIds(@RequestParam("ids") String idsStr) {
List<Integer> ids = Arrays.stream(idsStr.split(","))
.map(Integer::parseInt)
.collect(Collectors.toList());
return studentService.selectByIds(ids);
}
}
server.servlet.context-path=/lab_backend
spring.datasource.url=jdbc:mysql://localhost:3306/springtest?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatis 配置
mybatis.type-aliases-package=com.ch.lab.entity
mybatis.mapper-locations=classpath:mappers/*.xml
package com.ch.lab;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.ch.lab.repository")
public class LabBackendApplication {
public static void main(String[] args) {
SpringApplication.run(LabBackendApplication.class, args);
}
}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面1 - 学生信息展示</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h1 { color: #569cd6; }
p { color: #9cdcfe; }
</style>
</head>
<body>
<div id="app">
<h1>学生信息展示</h1>
<p>姓名:{{ name }}</p>
<p>学号:{{ studentId }}</p>
<p>专业:{{ major }}</p>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
name: '张三',
studentId: '2024001',
major: '计算机科学与技术'
}
}
})
app.mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面2 - 成绩计算</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h2 { color: #569cd6; }
p { color: #9cdcfe; }
input { background: #2d2d2d; color: #d4d4d4; border: 1px solid #555; padding: 4px 8px; font-family: inherit; }
</style>
</head>
<body>
<div id="app">
<h2>成绩计算</h2>
<p>成绩1:<input v-model.number="score1" placeholder="请输入成绩1"></p>
<p>成绩2:<input v-model.number="score2" placeholder="请输入成绩2"></p>
<p>成绩3:<input v-model.number="score3" placeholder="请输入成绩3"></p>
<p>平均分:{{ averageScore }}</p>
<p>等级:{{ gradeLevel }}</p>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
score1: 0,
score2: 0,
score3: 0
}
},
computed: {
averageScore() {
return ((this.score1 + this.score2 + this.score3) / 3).toFixed(2)
},
gradeLevel() {
const avg = (this.score1 + this.score2 + this.score3) / 3
if (avg >= 90) return '优秀'
if (avg >= 80) return '良好'
if (avg >= 70) return '中等'
if (avg >= 60) return '及格'
return '不及格'
}
}
})
app.mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面3 - 用户信息表单</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h2, h3 { color: #569cd6; }
p { color: #9cdcfe; }
input, textarea, select { background: #2d2d2d; color: #d4d4d4; border: 1px solid #555; padding: 4px 8px; font-family: inherit; }
hr { border-color: #444; }
</style>
</head>
<body>
<div id="app">
<h2>用户信息表单</h2>
<p>用户名:<input v-model="username" placeholder="请输入用户名"></p>
<p>简介:<textarea v-model="bio" placeholder="请输入简介"></textarea></p>
<p>性别:
<input type="radio" v-model="gender" value="男"> 男
<input type="radio" v-model="gender" value="女"> 女
</p>
<p>城市:
<select v-model="city">
<option value="">请选择</option>
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
</select>
</p>
<hr>
<h3>实时预览</h3>
<p>用户名:{{ username }}</p>
<p>简介:{{ bio }}</p>
<p>性别:{{ gender }}</p>
<p>城市:{{ city }}</p>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
username: '',
bio: '',
gender: '男',
city: ''
}
}
})
app.mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面4 - 课程列表</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h2 { color: #569cd6; }
h3 { color: #4ec9b0; }
p { color: #9cdcfe; }
</style>
</head>
<body>
<template id="course-item">
<div>
<h3>课程{{ id }}:{{ title }}</h3>
<p>学分:{{ credit }}</p>
</div>
</template>
<div id="app">
<h2>课程列表</h2>
<course-item
v-for="course in courses"
:key="course.id"
:id="course.id"
:title="course.title"
:credit="course.credit">
</course-item>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
courses: [
{ id: 1, title: 'Web全栈开发', credit: 4 },
{ id: 2, title: '数据结构', credit: 3 },
{ id: 3, title: '操作系统', credit: 3 },
{ id: 4, title: '数据库原理', credit: 3 }
]
}
}
})
app.component('course-item', {
template: '#course-item',
props: ['id', 'title', 'credit']
})
app.mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面5 - 事件与methods</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h2 { color: #569cd6; }
p { color: #9cdcfe; }
button { background: #0e639c; color: #fff; border: none; padding: 6px 16px; cursor: pointer; font-family: inherit; }
button:hover { background: #1177bb; }
</style>
</head>
<body>
<div id="app">
<h2>计数器</h2>
<p>已点击 {{ count }} 次</p>
<button @click="increment">点击 +1</button>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
})
app.mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面6 - v-if与v-show</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h2 { color: #569cd6; }
p { color: #9cdcfe; }
input { background: #2d2d2d; color: #d4d4d4; border: 1px solid #555; padding: 4px 8px; font-family: inherit; }
button { background: #0e639c; color: #fff; border: none; padding: 6px 16px; cursor: pointer; font-family: inherit; }
button:hover { background: #1177bb; }
hr { border-color: #444; }
</style>
</head>
<body>
<div id="app">
<h2>成绩等级判定</h2>
<p>请输入成绩:<input v-model.number="score" placeholder="请输入分数"></p>
<div>
<p v-if="score >= 90">优秀</p>
<p v-else-if="score >= 80">良好</p>
<p v-else-if="score >= 70">中等</p>
<p v-else-if="score >= 60">及格</p>
<p v-else>不及格</p>
</div>
<hr>
<h2>v-show 切换</h2>
<button @click="visible = !visible">切换显示</button>
<p v-show="visible">这是一段提示文字(v-show控制)</p>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
score: 0,
visible: true
}
}
})
app.mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面7 - v-for列表渲染</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h2 { color: #569cd6; }
li { color: #9cdcfe; }
table { border-collapse: collapse; }
th { background: #264f78; color: #d4d4d4; padding: 6px 12px; }
td { color: #9cdcfe; padding: 6px 12px; }
table, th, td { border: 1px solid #555; }
</style>
</head>
<body>
<div id="app">
<h2>书籍列表</h2>
<ul>
<li v-for="(book, index) in books" :key="index">{{ index + 1 }}. {{ book }}</li>
</ul>
<h2>作者列表</h2>
<table border="1">
<tr>
<th>姓名</th>
<th>年龄</th>
<th>国籍</th>
</tr>
<tr v-for="author in authors" :key="author.name">
<td>{{ author.name }}</td>
<td>{{ author.age }}</td>
<td>{{ author.country }}</td>
</tr>
</table>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
books: ['Vue.js设计与实现', 'JavaScript高级程序设计', 'CSS世界', 'Node.js实战'],
authors: [
{ name: '鲁迅', age: 55, country: '中国' },
{ name: '莎士比亚', age: 52, country: '英国' },
{ name: '海明威', age: 61, country: '美国' },
{ name: '莫泊桑', age: 43, country: '法国' }
]
}
}
})
app.mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面8 - 组件注册</title>
<style>
body { background: #1e1e1e; color: #d4d4d4; font-family: 'Consolas', 'Monaco', monospace; padding: 20px; }
h2 { color: #569cd6; }
p { color: #9cdcfe; }
button { background: #0e639c; color: #fff; border: none; padding: 6px 16px; cursor: pointer; font-family: inherit; }
button:hover { background: #1177bb; }
</style>
</head>
<body>
<template id="button-counter">
<div>
<p>{{ title }}:{{ count }} 次</p>
<button @click="count++">点击 +1</button>
</div>
</template>
<div id="app">
<h2>全局组件 - 计数器</h2>
<button-counter title="计数器A"></button-counter>
<button-counter title="计数器B"></button-counter>
<button-counter title="计数器C"></button-counter>
</div>
<script src="js/vue.global.js"></script>
<script>
const app = Vue.createApp({})
app.component('button-counter', {
template: '#button-counter',
props: ['title'],
data() {
return {
count: 0
}
}
})
app.mount('#app')
</script>
</body>
</html>
打包 lab_backend + lab_vue 两个文件夹,命名:学号_姓名_上机.zip
总分:第一大题60分 + 第二大题40分 = 100分