Mybatis框架

2026年9月18日星期五·4026 字·20 分钟·
-浏览量
后端框架MyBatisMybatisSSM
AI 摘要- DeepSeek

此框架是目前最流行的数据持久层框架 , 是对JDBC代码进行了封装 , 程序员只需要通过注解或配置文件的方式提供需要执行的SQL语句 , 框架会自动根据SQL语句生成出JDBC代码 , 从而提高执行效率

Mybatis框架 - 封面图

Mybatis#

  • 此框架是目前最流行的数据持久层框架 , 是对JDBC代码进行了封装 , 程序员只需要通过注解或配置文件的方式提供需要执行的SQL语句 , 框架会自动根据SQL语句生成出JDBC代码 , 从而提高执行效率

  • 如何使用Mybatis框架?

  1. 创建boot2-2工程 , 创建工程时需要勾选3个依赖分别是:

    a. Web —> Spring Web

    b. SQL —> Mybatis Framework

    c. SQL —> MySQL Driver

  2. 在application.properties配置文件中书写连接数据库的信息

    properties
    spring.datasource.url=jdbc:mysql://localhost:3306/empdb?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    spring.datasource.username=root
    spring.datasource.password=root

    User#

    java
    package cn.tedu.boot22.entity;
    public class User {
    private Integer id;
    private String username;
    private String password;
    private String nickname;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public String getUsername() {
    return username;
    }
    public void setUsername(String username) {
    this.username = username;
    }
    public String getPassword() {
    return password;
    }
    public void setPassword(String password) {
    this.password = password;
    }
    public String getNickname() {
    return nickname;
    }
    public void setNickname(String nickname) {
    this.nickname = nickname;
    }
    @Override
    public String toString() {
    return "User{" +
    "id=" + id +
    ", username='" + username + '\'' +
    ", password='" + password + '\'' +
    ", nickname='" + nickname + '\'' +
    '}';
    }
    }

    Hero#

    java
    package cn.tedu.boot22.entity;
    public class Hero {
    private Integer id;
    private String name;
    private Integer money;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getMoney() {
    return money;
    }
    public void setMoney(Integer money) {
    this.money = money;
    }
    @Override
    public String toString() {
    return "Hero{" +
    "id=" + id +
    ", name='" + name + '\'' +
    ", money=" + money +
    '}';
    }
    }

创建index页面#

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<a href="/add.html">添加英雄</a>
<a href="/delete.html">删除英雄</a>
<a href="/select">查询英雄</a>
</body>
</html>

创建add页面#

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加英雄页面</h1>
<form action="/add">
<input type="text" name="name" placeholder="英雄名">
<input type="text" name="money" placeholder="英雄价格">
<input type="submit" value="添加">
</form>
</body>
</html>

创建delete页面#

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>请输入要删除的英雄名称</h1>
<form action="/delete">
<input type="text" name="name">
<input type="submit" value="删除">
</form>
</body>
</html>

创建接口#

HeroMapper#

java
package cn.tedu.boot22.mapper;
import cn.tedu.boot22.entity.Hero;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper //Mybatis框架提供的注解,会创建实现类
public interface HeroMapper {
/**
* #{xxx}会从下面方法中的参数列表中找到同名的变量,如果没有同名的变量则进入对象中查找同名
* 的成员变量的get方法
* mybatis框架根据此方法声明生成具体的实现类的实现方法,方法内部就是JDBC代码
*/
@Insert("insert into hero values(null,#{name},#{money})")
void insert(Hero hero);
@Delete("delete from hero where name = #{name}")
void deleteByName(String name);
@Select("select * from hero")
List<Hero> select();
@Update("update hero set name = #{name},money = #{money} where id = #{id}")
void update(Hero hero);
}

创建update页面#

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>修改英雄页面</h1>
<form action="/update">
<input type="text" name="id" placeholder="请输入修改的id">
<input type="text" name="name" placeholder="名字">
<input type="text" name="money" placeholder="价格">
<input type="submit" value="修改">
</form>
</body>
</html>

创建HeroController#

java
package cn.tedu.boot22.controller;
@Controller
public class HeroController {
/**
* 自动注入/自动装配注解的作用:Spring框架结合mybatis框架会自动的将HeroMapper生成一个实现类和
* 实现内部的方法,并且会自动实例化此对象,并交给Spring容器管理
* required = false 告诉idea编译器此对象是非必须的
*/
@Autowired(required = false)
HeroMapper mapper;
@RequestMapping("add")
@ResponseBody
public String add(Hero hero) {
System.out.println("hero:"+hero);
mapper.insert(hero);
return "添加完成";
}
@RequestMapping("delete")
@ResponseBody
public String delete(String name) {
mapper.deleteByName(name);
return "删除完成";
}
@RequestMapping("select")
@ResponseBody
public String select() {
List<Hero> list = mapper.select();
return list.toString();
}
@RequestMapping("update")
@ResponseBody
public String update(Hero hero) {
mapper.update(hero);
return "修改完成";
}
}

Mybatis框架添加英雄步骤:#

  1. 创建boot2-2, 添加三个依赖

  2. 在application.properties配置文件中添加内容

  3. 停止之前工程, 运行新工程测试是否能正常运行

  4. 创建index.html 页面里面添加超链接 , 添加英雄 , 访问地址为add.html

  5. 创建add.html页面里面添加form表单 , 请求地址为 /add

  6. 创建controller.HeroController, 里面添加@Controller注解,添加@RequestMapping注解处理 /add请求并添加add方法,

  7. 创建entity.Hero实体类 并提供get和set方法 还有tostring方法

  8. 在HeroController的add方法参数列表中声明Hero对象 , 用来接收传递过来的参数 ,此时打桩输出hero对象 检查是否接收到了参数

  9. 创建mapper.HeroMapper接口, 里面添加@Mapper注解, 声明一个insert方法通过@Insert注解修饰,注解里面添加插入数据的SQL语句

  10. 在HeroController里面 通过@Autowired注解把HeroMapper装配进来, 在add方法里面调用mapper.insert方法把接收到的hero对象传递进去, 重启工程测试即可!

删除英雄步骤:#

  1. 在首页中添加删除英雄超链接 访问地址为 delete.html

  2. 创建delete.html页面 在里面添加form表单 提交地址为/delete

  3. 在HeroController 中创建delete方法 处理路径为/delete 参数列表中声明name 接收页面传递过来的名字

  4. 在HeroMapper里面添加deleteByName方法 通过@Delete注解修饰,里面填写 删除的SQL语句

  5. 在HeroController里面的delete方法中调用mapper的deleteByName方法

修改英雄步骤:#

  1. 在首页添加修改英雄超链接, 地址为update.html页面

  2. 创建update.html页面 并添加form表单 提交地址为/update

  3. 在Controller中添加update方法 处理/update请求

  4. 在HeroMapper里面添加update方法 通过@Update注解进行修饰,里面添加修改的SQL语句

  5. 在HeroController里面的update方法中调用mapper的update方法把接收到的hero对象传递到方法中

查询英雄步骤:#

  1. 在首页添加查询的超链接,请求地址为/select

  2. 在HeroController中添加select方法处理/select请求

  3. 在HeroMapper里面添加select方法用@Select注解进行修饰,里面写查询的SQL语句

  4. 在HeroController的select方法中 调用mapper的select方法,把查询到的List集合返回给客户端展示

商品表的增删改查#

  • 创建商品表
sql
use empdb;
create table product(id int primary key auto_increment,title varchar(100),price double(10,2),sale_count int)charset=utf8;
  1. 创建boot3-1工程 , 添加三个依赖

  2. 从之前工程中复制application.properties配置文件的信息到新工程, 启动工程测试是否成功

  3. 创建index.html

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>商品管理首页</h1>
<a href="/insert.html">添加商品</a>
<a href="/select">查询商品</a>
<a href="/update.html">修改商品</a>
<hr>
<a href="/helloAxios.html">异步请求测试</a>
</body>
</html>

创建insert.html

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加商品页面</h1>
<form action="/insert">
<input type="text" name="title" placeholder="商品标题">
<input type="text" name="price" placeholder="商品价格">
<input type="text" name="saleCount" placeholder="商品销量">
<input type="submit" value="添加">
</form>
</body>
</html>

创建update.html

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>修改商品页面</h1>
<form action="/update">
<input type="text" name="id" placeholder="请输入修改商品的id">
<input type="text" name="title" placeholder="商品标题">
<input type="text" name="price" placeholder="商品价格">
<input type="text" name="saleCount" placeholder="商品销量">
<input type="submit" value="修改">
</form>
</body>
</html>

创建ProductController

java
package cn.tedu.boot31.controller;
//@Controller
//@ResponseBody //此注解相当于在每个方法上都添加了ResponseBody注解
@RestController //=@Controller + @ResponseBody
public class ProductController {
@Autowired
ProductMapper mapper;
@RequestMapping("insert")
public String insert(Product product) {
mapper.insert(product);
return "添加完成!<a href='/'>返回首页</a>";
}
@RequestMapping("select")
public String select() {
List<Product> list = mapper.select();
String html = "<table border=1>";
html+="<caption>商品列表</caption>";
html+="<tr><th>id</th><th>标题</th><th>价格</th><th>销量</th><th>操作</th></tr>";
for (Product p : list) {
html+="<tr>";
html+="<td>"+p.getId()+"</td>";
html+="<td>"+p.getTitle()+"</td>";
html+="<td>"+p.getPrice()+"</td>";
html+="<td>"+p.getSaleCount()+"</td>";
html+="<td><a href='/delete?id="+p.getId()+"'>删除</a></td>";
html+="</tr>";
}
html+="</table>";
return html;
}
@RequestMapping("delete")
public String delete(int id) {
mapper.deleteById(id);
return "删除完成!<a href='/select'>返回列表页面</a>";
}
@RequestMapping("update")
public String update(Product product) {
mapper.update(product);
return "修改完成<a href='/select'>返回列表页面</a>";
}
}

创建Product

java
package cn.tedu.boot31.entity;
public class Product {
private Integer id;
private String title;
private Double price;
private Integer saleCount;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Integer getSaleCount() {
return saleCount;
}
public void setSaleCount(Integer saleCount) {
this.saleCount = saleCount;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", title='" + title + '\'' +
", price=" + price +
", saleCount=" + saleCount +
'}';
}
}

创建ProductMapper

java
package cn.tedu.boot31.mapper;
@Mapper
public interface ProductMapper {
@Insert("insert into product values(null,#{title},#{price},#{saleCount})")
void insert(Product product);
@Select("select * from product")
@Result(column = "sale_count",property = "saleCount")
List<Product> select();
@Delete("delete from product where id = #{id}")
void deleteById(int id);
@Update("update product set title = #{title},price = #{price},sale_count=#{saleCount} where id = #{id}")
void update(Product product);
}

同步请求和异步请求#

  • 同步 : 指单线程依次做几件事

  • 异步 : 指多线程同时做几件事

  • 同步请求 : 指客户端浏览器只有一个主线程, 此线程负责页面的渲染和发出请求等操作, 如果此主线程发出请求的话则停止渲染而且会清空页面显示的内容 , 直到服务器响应了数据后才能再次显示, 由于主线程清空了原有显示的内容所以只能实现页面的整体刷新(整体改变)

  • 异步请求 : 指客户端的主线程只负责页面渲染相关操作,发请求的事儿由新的子线程操作, 这样子线程发出请求时页面不需要清空 , 而且可以将查询回来的数据展示在原有页面基础之上, 这样实现的效果就叫做页面的局部刷新

客户端发出请求的几种方式#

  1. 通过浏览器的地址栏中发出请求 同步请求
  2. 通过html页面中的超链接发出请求 同步请求
  3. 通过html页面中的form表单发出请求 同步请求
  4. 通过前端框架发出请求 异步请求

客户端如何发出异步请求#

  1. 通过Axios框架发出异步请求

  2. 此框架就是一个普通的js文件 , 页面需要使用此框架时需要将此文件引入到页面中

  3. axios框架地址 , 下载axios.min.js文件

html
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>

static目录下创建js目录 , 将axios.min.js和vue.js放入此目录中

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<h1>{{info}}</h1>
<input type="button" value="测试异步请求get" @click="f1()">
<input type="button" value="测试异步请求post" @click="f2()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
let v = new Vue({
el:"div",
data:{
info:"测试Vue!"
},
methods:{
f1(){
axios.get("/hello1Axios?info=tom").then(function (response) {
//response代表服务器的响应对象
//response.data代表服务器响应的数据
alert(response.data);
})
},
f2(){
//发出异步post请求
axios.post("/hello2Axios",{info:"刘德华"}).then(function (response) {
alert(response.data);
})
}
}
})
</script>
</body>
</html>

AxiosController#

java
package cn.tedu.boot31.controller;
@RestController
public class AxiosController {
@RequestMapping("hello1Axios")
public String hello1(String info) {
return "请求成功! info="+info;
}
/**
* @RequestBody 注解作用:当客户端发出post请求并且提交的是自定义对象时,服务器端接收参数
* 必须使用此注解,否则获取不到传递过来的参数
*/
@RequestMapping("hello2Axios")
public String hello2(@RequestBody String info) {
return "请求成功! info="+info;
}
}

Get请求和Post请求#

  • 从字面意思理解 , Get是向服务器要数据 , Post是给服务器传数据

  • Get : 请求参数写在请求地址的后面(可见) , 请求参数有大小限制只能传几k的数据(不能处理文件上传)

    应用场景 : 查询请求一般都会使用get , 删除也会使用get请求

  • Post : 请求参数放在请求体里面(不可见) , 参数没有大小限制

    应用场景 : 文件上传 , 带有敏感信息的请求(比如注册登录时有密码)

注册登录步骤 :#

  1. 创建工程boot3-2 , 添加三个依赖

  2. 从之前工程中复制application.properties里面的连接数据库的信息 , 复制完之后立即启动工程 , 测试是否创建成功 , 如果工程启动不起来 , 检查报错是不是因为端口被占用 , 如果不是 , 刷新maven再次启动 , 如果还是启动不了 , 删除工程重新创建新工程 , 直至启动成功

  3. 创建index.html页面 , 在里面添加两个超链接访问注册和登录页面

  4. 创建reg.html页面 , 在页面中引入vue和axios两个框架文件 , 从之前工程中复制js文件夹(检查里面是不是包含这两个框架文件) , 在页面中点击按钮时向/reg发出异步请求 , 同时把用户输入的信息提交给服务器,然后在then方法里面判断返回的response.data值为1代表注册成功 , 显示首页 , 值为2代表用户名已存在

  5. 创建controller.UserController并且创建entity.User实体类

  6. 在Controller里面添加reg方法处理/reg请求 , 声明User变量用来接收传递过来的用户信息

  7. 创建mapper.UserMapper , 在里面提供两个方法 , 分别是 selectByUsername和insert两个方法

  8. 回到Controller里面把UserMapper通过@Autowired装配进来 , 在reg方法中先调用mapper里面的selectByUsername方法 , 判断返回值是否有值 , 如果有值则给客户端返回2代表用户名已存在 , 如果没有值 , 则调用mapper的insert方法 , 把用户信息保存到数据库 , 最后返回1代表注册成功

  9. 下一步开始实现登录功能 , 步骤类似注册 , 先创建login.html页面 , 然后在页面中通过Vue对内容进行管理 , 当点击登录按钮的时候向/login发出异步请求 , 同样把输入的用户信息提交给服务器 , 在then方法中判断response.data的值为1代表登录成功显示首页 , 值为2代表用户名不存在, 值为3代表密码错误

  10. 在Controller里面添加login方法处理/login请求 , 声明User对象接收传递过来的用户信息 , 在方法中调用mapper的selectByUsername 通过用户输入的用户名查询对应的用户信息 , 如果没有查询到 , 直接返回2代表用户名不存在 , 如果查询到了 , 继续通过输入的密码和查询到的密码比较如果一致返回1代表登录成功 , 如果不一致返回2 , 代表密码错误.

index.html#

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>工程首页</h1>
<a href="/reg.html">注册</a>
<a href="/login.html">登录</a>
</body>
</html>

将上个项目中的js目录复制到新项目中的static目录下

reg.html#

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>注册页面</h1>
<div>
<input type="text" v-model="user.username" placeholder="请输入用户名">
<input type="text" v-model="user.password" placeholder="请输入密码">
<input type="text" v-model="user.nickname" placeholder="请输入昵称">
<input type="button" value="注册" @click="reg()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
let v = new Vue({
el:"div",
data:{
user:{
username:"",
password:"",
nickname:""
}
},
methods:{
reg(){
//发出post请求
axios.post("/reg",v.user).then(function (response) {
//alert(response.data);
//判断如果注册成功,返回首页
if (response.data == 1) {
alert("注册成功!");
//让浏览器跳转到首页
location.href="/";
}else {
alert("用户名已存在!")
}
})
}
}
})
</script>
</body>
</html>

login.html#

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登录页面</h1>
<div>
<input type="text" v-model="user.username" placeholder="用户名">
<input type="text" v-model="user.password" placeholder="密码">
<input type="button" value="登录" @click="login()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
let v = new Vue({
el:"div",
data:{
user:{
username:"",
password:""
}
},
methods: {
login() {
//发出异步请求
axios.post("/login",v.user).then(function (response) {
if (response.data == 1) {
alert("登录成功!");
location.href="/";
}else if(response.data == 2){
alert("用户名不存在!")
}else {
alert("密码错误!");
}
})
}
}
})
</script>
</body>
</html>

UserController#

java
package cn.tedu.boot32.controller;
@RestController
public class UserController {
@Autowired
UserMapper mapper;
@RequestMapping("reg")
public int reg(@RequestBody User user) {
//获取用户输入的用户名到数据库中查询用户信息
User u = mapper.selectByUsername(user.getUsername());
if (u != null) {
return 2; //2代表用户名已存在
}
mapper.insert(user);
return 1; //1注册成功
}
@RequestMapping("login")
public int login(@RequestBody User user) {
//获取用户输入的用户名到数据库中查询用户信息
User u = mapper.selectByUsername(user.getUsername());
if (u != null) {//代表查询到了用户信息
//判断用户输入的密码和查询的密码是否一致
if (user.getPassword().equals(u.getPassword())) {
return 1; //登录成功
}
return 3; //密码错误
}
return 2; //用户名不存在
}
}

User实体类#

java
package cn.tedu.boot32.entity;
public class User {
private Integer id;
private String username;
private String password;
private String nickname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}

UserMapper#

java
package cn.tedu.boot32.mapper;
@Mapper
public interface UserMapper {
//因为返回值为一个对象,要求查询回来的结果必须是0或者1条
@Select("select * from user where username = #{username}")
User selectByUsername(String username);
@Insert("insert into user values(null,#{username},#{password},#{nickname})")
void insert(User user);
}
Mybatis框架
https://www.cati.cc.cd/posts/spring-mvc-mybatis-notes/
作者
MIAOWU
发布于
2026-09-18
许可协议
CC BY-NC-SA 4.0

评论区

动作模组
等待模型加载…
看板娘
公告
公告大版本更新

一口气全面统一博客样式,移除部分冗余导航页面,更专注内容展示。

公告稳定性修复一批

统一Swup生命周期(BUG更少了、牺牲了首屏部分性能)、升级astro 7(构建速度翻倍)、文章封面图片加载(更流畅)、更换音乐播放器 API(更稳定)等多个问题,站点更稳了。

公告互换友链

欢迎各位大佬互换友链,要求内容原创、稳定更新。申请前请先看友链页的说明,期待和你交换链接。

查看详情
公告关于我的介绍

欢迎来到我的博客,我是深耕java、python和agent技术开发。热爱技术、持续学习,欢迎同好交流探讨。

查看详情
音乐
封面

音乐

暂未播放

0:00
0:00
暂无歌词

日历

正在加载日历...

--

    最近节日

    正在加载日历...
    ----

    最近生日/纪念日

    正在加载日历...
    ----
    距月底--
    距年底--

    隐私政策

    更新日期: 2026 年 7 月 15 日
    生效日期: 2026 年 7 月 15 日

    适用范围#

    本政策适用于 MiaoWu 的博客(以下简称“本站”)。本站是个人博客,用于发布和分享内容;不提供账户注册、支付、定位或广告投放服务。访问本站、发表文章评论或在留言板留言前,请阅读本政策。

    信息收集与使用#

    本站只在提供内容、评论和留言功能,以及维护站点安全所需的范围内处理信息。

    • 访问与统计信息:访问页面时,统计服务可能处理访问时间、页面地址、来源页、浏览器和设备相关信息,用于了解内容访问情况、排查故障和改进站点。
    • 评论信息:使用文章评论功能时,Waline 可能处理您主动提交的昵称、邮箱、站点链接和评论内容;还可能处理 IP 地址等必要信息,用于防止垃圾评论、滥用和维护服务安全。评论内容、昵称和站点链接(如填写)可能公开展示在文章下方;邮箱不会公开展示。
    • 留言信息:留言板使用 Waline /guestbook/ 频道。Waline 可能处理您主动提交的昵称、可选邮箱、站点链接、留言内容和图片,以及浏览器、操作系统、IP 地址等必要的反滥用信息。默认情况下,留言图片以内嵌数据随留言提交;如站点维护者配置了远程图片上传接口,图片会先发送至该接口并在留言中保存返回的图片地址。留言内容、昵称、图片和站点链接(如填写)可能公开展示;邮箱和 IP 地址不会在留言板公开展示。

    请不要在评论或留言中提交身份证件、银行卡、住址、密码或其他不必要的敏感个人信息。

    第三方服务#

    为实现本站功能,以下第三方会在各自服务范围内处理相关数据:

    • Umami:用于匿名化的网站访问统计和出站链接点击统计,帮助我了解本站的使用情况。
    • Waline:用于文章评论、留言板及访问量统计。服务会按照其自身规则处理您在评论或留言时提交的信息及必要的反滥用信息。
    • Cloudflare:可为本站提供静态资源分发和域名基础设施。
    • unpkg:用于加载 Waline 的前端脚本、样式和表情资源;请求这些资源时,您的浏览器会与该服务建立连接。

    第三方服务可能有独立的隐私政策和数据保存规则。请在使用相关功能前查阅其规则;本站无法控制其独立的数据处理活动。

    本站主要使用浏览器本地存储(Local Storage 或 Session Storage)保存使用偏好,例如主题颜色、明暗模式、文章列表视图和音乐播放设置。留言板会在本地保存匿名资料、未发送草稿和登录状态,以便恢复输入与会话;管理员登录状态仅保存在当前会话。

    本站不主动设置用于广告定向的第一方 Cookie。评论、统计或资源服务可能按照其自身规则使用 Cookie 或类似技术。您可以通过浏览器设置查看、删除或限制 Cookie 和本地存储;清除后,部分偏好或互动状态可能会恢复为默认值,评论功能也可能受到影响。

    信息公开、保存与安全#

    评论和留言属于公开互动内容,提交后可能被搜索引擎收录、被他人引用或在缓存中短暂保留。请谨慎决定发布内容。除非您提出删除请求、内容违反规则或法律法规另有要求,公开内容会持续保留以维持讨论上下文。

    本站会采取合理措施保护数据安全,包括使用 HTTPS、输入校验、内容转义和访问频率限制。但互联网传输和第三方服务均无法保证绝对安全,请理解并自行承担公开发布信息的相应风险。

    你的权利#

    你可以通过 996491835@qq.com 联系我,申请查询、更正或删除由本站直接保存的评论、留言或相关公开内容。为保护他人权益,请在请求中提供足以定位内容的信息,并说明你与该内容的关系;必要时可能需要进行合理核验。

    对于由 Waline、Umami、Cloudflare 或 unpkg 独立处理的数据,你也可以直接向对应服务提供方行使相关权利。删除公开评论或留言后,第三方缓存、搜索引擎索引或他人转载的副本可能无法立即同步删除。

    未成年人条款#

    未满 14 周岁的未成年人应在监护人同意和指导下使用本站的评论、留言等互动功能。监护人如发现未成年人未经同意提交了个人信息,可通过上述联系方式与我联系,我会在合理范围内协助处理。

    政策更新与联系#

    我可能因本站功能或适用规则变化更新本政策,更新后的版本将在本站公布并标明日期。继续使用相关功能即表示你已阅读并理解更新后的政策。

    如对本政策或数据处理有疑问,请联系 996491835@qq.com。

    用户协议

    更新日期: 2026 年 5 月 19 日
    生效日期: 2026 年 5 月 19 日

    适用范围#

    本协议适用于你访问 MiaoWu 的博客,以及使用文章评论、留言板等互动功能的行为。继续浏览本站或提交评论、留言,即表示你已阅读、理解并同意遵守本协议及本站的隐私政策。

    评论及留言规则#

    请在交流中保持友善、理性和尊重。你不得利用本站发布、传播或实施以下行为:

    • 发布任何违反中华人民共和国法律法规的内容。
    • 发布任何侵犯他人合法权益的内容,包括但不限于隐私、名誉、肖像、著作权、商标权和其他知识产权。
    • 恶意攻击、辱骂、骚扰、威胁、歧视其他用户或任何第三方。
    • 发布垃圾广告、恶意推广、刷屏、灌水,或与讨论主题明显无关的重复内容。
    • 利用本站进行网络诈骗、钓鱼、传播恶意软件,或发布可能危害网络和信息安全的内容。
    • 绕越或试图绕越本站的审核、限流、封禁等管理措施。
    • 冒充他人、伪造身份,或收集、公开他人的个人信息。

    内容与访问管理#

    你应对自己发布的评论和留言负责,并保证拥有发布该等内容所需的合法权利。论坛管理员有权在不另行通知的情况下删除违规内容、限制或封禁违规账号,或限制其继续使用本站互动功能。

    如发现涉嫌违法犯罪、严重侵权或危及本站安全的内容,本站可保留相关记录,并在法律法规要求或必要时向有关部门提供协助。对管理措施有疑问时,可通过文末联系方式说明情况;本站会结合实际情况处理,但不承诺恢复已删除内容或访问权限。

    知识产权与内容授权#

    本站原创文章、页面设计和其他受保护内容的权利归作者或权利人所有。未经授权,请勿复制、转载、镜像或用于商业用途;法律法规允许的合理使用除外。

    你发布评论或留言时,授予本站为展示、存储、备份、审核、删除和维护互动功能所必需的非独占、免费的使用许可。该许可不改变你对原创内容依法享有的权利。

    免责声明#

    本站内容仅用于个人记录、学习交流和一般信息参考,不构成任何专业意见、承诺或担保。你应结合自身情况独立判断,并对据此采取的行动负责。

    评论、留言和外部链接中的内容由其发布者或运营者负责,不代表本站立场。本站会在合理范围内处理明显违规内容,但不保证所有内容均及时发现,也不对第三方网站的可用性、内容、安全性或隐私实践承担责任。

    因网络故障、不可抗力、第三方服务异常、维护升级或超出合理控制范围的原因导致本站暂时无法访问、内容延迟或数据丢失的,本站会尽力恢复,但不承担由此产生的间接损失。

    未成年人条款#

    未满 14 周岁的未成年人应在监护人同意和指导下使用评论、留言等互动功能。监护人应协助未成年人理解本协议,并对其使用行为进行必要的引导。

    其他条款#

    我可以根据本站功能、管理需要或法律法规变化更新本协议,更新后的版本将在本站公布并标明日期。继续使用本站即视为接受更新后的协议。

    本协议的订立、执行和解释适用中华人民共和国法律。因本协议或使用本站产生争议时,双方应先友好协商;协商不成的,依法向有管辖权的人民法院解决。

    如对本协议或内容管理有疑问,请联系 996491835@qq.com。

    复制成功,转载请标注本文地址