学生管理系统(用maven来导入jar包)
不废话,直接上
先看一下项目列表:
首先创建一个maven工程,然后导入相应的jar包,请参考:使用maven导入jar包
接着在Source Folder创建具体的项目:
Main类(客户端)
package com.zzu.client;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;import com.zzu.tool.db.DBLink;
import com.zzu.tool.db.IRowMapper;public class Main {public static void main(String[] args) {System.out.println("*********************************");System.out.println("*\t\t\t\t*");System.out.println("*\t欢迎使用学生信息管理系统\t*");System.out.println("*\t\t\t\t*");System.out.println("*********************************");while (true) {menu();}}static void menu() {System.out.println("1、添加学生信息");System.out.println("2、删除学生信息");//学号System.out.println("3、修改学生信息");//地址传递System.out.println("4、查询学生信息");//nameSystem.out.println("请输入操作,以Enter键结束:");Scanner scanner = new Scanner(System.in);int option = scanner.nextInt();switch (option) {case 1:{System.out.println("请输入学号:");String id = scanner.next();String sql = "select id from student where id = ?";if(new DBLink().exist(sql, id)) {System.out.println("学号已存在,无法添加!");return;}System.out.println("请输入姓名:");String name = scanner.next();System.out.println("请输入手机号:");String mobile = scanner.next();System.out.println("请输入家庭住址:");String address = scanner.next();sql = "insert into student (id,name,mobile,address) values (?,?,?,?)";if(new DBLink().update(sql, id,name,mobile,address)) {System.out.println("添加成功!");return;}System.out.println("添加失败!");break;}case 2:{System.out.println("请输入要删除学生的学号:");String id = scanner.next();String sql = "delete from student where id = ?";if(new DBLink().update(sql, id)) {System.out.println("删除成功!");return;}System.out.println("删除失败!");break;}case 3:{System.out.println("请输入要修改学生的学号:");String id = scanner.next();String sql = "select id from student where id = ?";if(new DBLink().exist(sql, id)) {System.out.println("请输入新的姓名:");String name = scanner.next();System.out.println("请输入新的手机号:");String mobile = scanner.next();System.out.println("请输入新的家庭住址:");String address = scanner.next();sql = "update student set name = ?,mobile = ?, address = ? where id = ?";if(new DBLink().update(sql, name,mobile,address,id)) {System.out.println("修改成功!");return;}System.out.println("修改失败!");return;}System.out.println("未查询到要修改学生的学号!");break;}case 4:{System.out.println("请输入要查询学生的学号:");String id = scanner.next();String sql = "select id from student where id = ?";if(!new DBLink().exist(sql, id)) {System.out.println("学号不存在,无法查询!");}sql = "select id,name,mobile,address from student where id = ?";//有名内部类class RowMapper implements IRowMapper{public void rowMapper(ResultSet rs) {try {if(rs.next()) {String id1 = rs.getString("id");String name = rs.getString("name");String mobile = rs.getString("mobile");String address = rs.getString("address");System.out.println("学号:"+id1+",姓名:"+name+",手机号:"+mobile+",家庭住址:"+address);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}};RowMapper rowMapper = new RowMapper();new DBLink().select(sql, rowMapper,id);//Lambda表达式/*new DBLink().select(sql, (ResultSet rs)->{try {if(rs.next()) {String id1 = rs.getString("id");String name = rs.getString("name");String mobile = rs.getString("mobile");String address = rs.getString("address");System.out.println("学号:"+id1+",姓名:"+name+",手机号:"+mobile+",家庭住址:"+address);}} catch (SQLException e) {e.printStackTrace();}},id);*/break;}default:System.out.println("I'm Sorry,there is not the "+option+" option,please try again.");}}
}
DBLink(工具类)
package com.zzu.tool.db;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;import org.apache.log4j.Logger;import com.zzu.tool.PropertiesTool;/*** 数据库管理(增删改查)* * @author ZhaoZhengyi*/public class DBLink {private Logger logger = Logger.getLogger(DBLink.class);/*** 获取数据库连接** @author ZhaoZhengyi*/public Connection getConnection() {try {String driver = PropertiesTool.getValue("db.driver");String url = PropertiesTool.getValue("db.url");String userName = PropertiesTool.getValue("db.userName");String password = PropertiesTool.getValue("db.password");Class.forName(driver);return DriverManager.getConnection(url, userName, password);} catch (Exception e) {logger.debug(e.getMessage(), e);}return null;}/*** 该方法用于判断某个用户是否存在,若存在返回该用户数据,否则返回false* @param sql 是指要执行的SQL语句* @return*//*public boolean exist(String sql) {//初始化变量为nullConnection connection = null;Statement statement = null;ResultSet resultset = null;try {connection = getConnection();statement = connection.createStatement();//创建SQL语句对象 resultset = statement.executeQuery(sql);//executeQuery用于查询用户的数据,并将其存入ResultSet类型的resultset变量中去return resultset.next();//若有则返回该用户数据} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {//即便有异常也会执行代码close(resultset,statement,connection);//释放资源}return false;}*//*** 判断某条数据是否存在** @author ZhaoZhengyi*/public boolean exist(String sql,Object ...params) {//初始化变量为nullConnection connection = null;PreparedStatement prepareStatement = null;ResultSet resultset = null;try {connection = getConnection();prepareStatement = connection.prepareStatement(sql);//此时prepareStatement为含有?的sql语句for (int i = 0; i < params.length; i++) {//为?赋值,这里之所以为i+1,是因为该方法是从1开始的prepareStatement.setObject(i+1, params[i]);}resultset = prepareStatement.executeQuery();//executeQuery用于查询用户的数据,并将其存入ResultSet类型的resultset变量中去return resultset.next();//若有则返回该用户数据} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {//即便有异常也会执行代码close(resultset,prepareStatement,connection);//释放资源}return false;//若没有则返回false}/*** 该方法用于insert(添加)、delete(删除)、update(修改)用户信息* 至于选哪一个来操作用户信息因sql语句而定* @param sql 是指要操作的SQL语句* @return 若成功则返回影响的行数,否则返回false*/public boolean update(String sql) {Connection connection = null;Statement statement = null;try {connection = getConnection();statement = connection.createStatement();//创建SQL语句对象 int affect = statement.executeUpdate(sql);//执行sql语句,返回影响的行数,仅限于insert delete update/*statement.close();connection.close();*///如果上面代码出现异常,则该行代码及其下面代码无法执行,所以资源无法释放;比如sql语句语法错误,则statement和connection无法释放return affect>0;/** 这里我想说明一下,由于finally的特殊性,会先执行完finally里的释放资源,再执行上一语句:返回一个affect值* 总之就是在结束方法之前无论如何都要先释放资源才可以*/} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {//即便有异常也会执行代码close(statement,connection);//释放资源}return false;}/*** 用于添加、删除、修改用户信息** @author ZhaoZhengyi*/public boolean update(String sql, Object ...params) {Connection connection = null;PreparedStatement prepareStatement = null;try {connection = getConnection();prepareStatement = connection.prepareStatement(sql);//含有?的sql语句 赋值给prepareStatementfor(int i = 0; i < params.length; i++) {prepareStatement.setObject(i+1, params[i]);//用参数替换掉?}int affect = prepareStatement.executeUpdate();//执行sql语句,并返回影响的行数return affect>0;} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {close(prepareStatement,connection);}return false;}//获取某个表中的总行数(分页使用)public Object getValue(String sql,String columnName) {Connection connection = null;Statement statement = null;ResultSet resultset = null;try {connection = getConnection();statement = connection.createStatement();resultset = statement.executeQuery(sql);if(resultset.next()) {return resultset.getObject(columnName);}} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {close(resultset,statement,connection);}return null;}//获取某个表中的总行数(分页使用)(防止sql注入)public Object getValue(String sql,String columnName,Object ...params) {Connection connection = null;PreparedStatement prepareStatement = null;ResultSet resultset = null;try {connection = getConnection();prepareStatement = connection.prepareStatement(sql);for (int i = 0; i < params.length; i++) {prepareStatement.setObject(i+1, params[i]);}resultset = prepareStatement.executeQuery();if(resultset.next()) {return resultset.getObject(columnName);}} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {close(resultset,prepareStatement,connection);}return null;}/*** 该方法用于查询用户信息* @param sql 要执行的SQL语句* @param rowMapper 接口是无法创建对象的,所以参数rowMapper一定指向接口(IRowMapper)实现类对象*/public void select(String sql,IRowMapper rowMapper) {Connection connection = null;Statement statement = null;ResultSet resultset = null;try {connection = getConnection();statement = connection.createStatement();//创建SQL语句对象resultset = statement.executeQuery(sql);//执行SQL语句,此时用户数据都在resultset里面rowMapper.rowMapper(resultset);//因为rowMapper参数指向IRowMapper接口实现类对象,所以此处将调用接口实现类中所实现的rowMapper方法 多态} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {close(resultset,statement,connection);//释放资源}}/*** 查询用户数据** @author ZhaoZhengyi*/public void select(String sql,IRowMapper rowMapper,Object ...params) {Connection connection = null;PreparedStatement prepareStatement = null;ResultSet resultset = null;try {connection = getConnection();prepareStatement = connection.prepareStatement(sql);for (int i = 0; i < params.length; i++) {prepareStatement.setObject(i+1, params[i]);}resultset = prepareStatement.executeQuery();//执行SQL语句,此时用户数据都在resultset里面rowMapper.rowMapper(resultset);//因为rowMapper参数指向IRowMapper接口实现类对象,所以此处将调用接口实现类中所实现的rowMapper方法 多态} catch (Exception e) {logger.debug(e.getMessage(), e);} finally {close(resultset,prepareStatement,connection);//释放资源}}/*** 释放资源** @author ZhaoZhengyi*/private void close(Statement statement,Connection connection) {try {if (statement != null) {//有可能由于异常导致statement没有赋值(譬如url出错),此时不必释放资源(多余),不然会报空指针异常statement.close();}} catch (SQLException e) {logger.debug(e.getMessage(), e);}try {if (connection != null) {connection.close();}} catch (SQLException e) {logger.debug(e.getMessage(), e);}}/*** 与上一方法是重载** @author ZhaoZhengyi*/private void close(ResultSet resultset,Statement statement,Connection connection) {try {if (resultset != null) {resultset.close();}} catch (SQLException e) {logger.debug(e.getMessage(), e);}close(statement,connection);}}
IRowMapper接口:
package com.zzu.tool.db;import java.sql.ResultSet;@FunctionalInterface
public interface IRowMapper {/*** 定义一个抽象方法(参数类型为ResultSet)** @author ZhaoZhengyi*/void rowMapper (ResultSet rs);
}
PropertiesTool类(获取数据库连接的桥梁):
package com.zzu.tool;import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;public class PropertiesTool {private static Properties properties = new Properties();/*** 联系db.properties文件和properties* * 静态代码块先于main方法先执行*/static {InputStream inputStream = PropertiesTool.class.getClassLoader().getResourceAsStream("db.properties");//将db.properties变为javaIO流对传入到inputStream中//此时db.properties文件中的数据就保存到了inputStream中try {properties.load(inputStream);//将inputStream中的key和value放到load方法中进行解析再存到properties中} catch (IOException e) {e.printStackTrace();}}/*** 我们创建一个getVaule方法来便于调用文件(此时也就是properties)中的数据*/public static String getValue(String key) {return properties.getProperty(key);//返回properties中的key值}/*** 我们来测试一下:*/public static void main(String [] ages) {String userName = getValue("db.userName");String password = getValue("db.password");String url = getValue("db.url");String driver = getValue("db.driver");System.out.println(userName);System.out.println(password);System.out.println(url);System.out.println(driver);}
}
要使用的资源:
db.properties(连接数据库的一些必要信息):
db.userName = root
db.password = root
db.url = jdbc:mysql://127.0.0.1:3306/test
db.driver = com.mysql.jdbc.Driver
log4j.properties(收集异常信息所需要的一些配置):
# DEBUG\u8BBE\u7F6E\u8F93\u51FA\u65E5\u5FD7\u7EA7\u522B\uFF0C\u7531\u4E8E\u4E3ADEBUG\uFF0C\u6240\u4EE5ERROR\u3001WARN\u548CINFO \u7EA7\u522B\u65E5\u5FD7\u4FE1\u606F\u4E5F\u4F1A\u663E\u793A\u51FA\u6765
log4j.rootLogger=DEBUG,Console,RollingFile#\u5C06\u65E5\u5FD7\u4FE1\u606F\u8F93\u51FA\u5230\u63A7\u5236\u53F0
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern= [%-5p]-[%d{yyyy-MM-dd HH:mm:ss}] -%l -%m%n
#\u5C06\u65E5\u5FD7\u4FE1\u606F\u8F93\u51FA\u5230\u64CD\u4F5C\u7CFB\u7EDFD\u76D8\u6839\u76EE\u5F55\u4E0B\u7684log.log\u6587\u4EF6\u4E2D
log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.RollingFile.File=D://log.log
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n
slf4j-log4j:
# DEBUG设置输出日志级别,由于为DEBUG,所以ERROR、WARN和INFO 级别日志信息也会显示出来
log4j.rootLogger=DEBUG,RollingFile
#每天产生一个日志文件(RollingFile)
log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender
#当天的日志文件全路径
log4j.appender.RollingFile.File=d:/logs/sirius.log
#服务器启动日志是追加,false:服务器启动后会生成日志文件把老的覆盖掉
log4j.appender.RollingFile.Append=true
#日志文件格式
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n
log4j.appender.RollingFile.Threshold=DEBUG
#设置每天生成一个文件名后添加的名称,备份名称:sirius.log.年月日时分.log
log4j.appender.RollingFile.DatePattern='.'yyyy-MM-dd-HH-mm'.log'
相关文章:

视觉惯性SLAM:VINS-Mono
视觉惯性SLAM:VINS-Mono这篇博客一些符号说明IV 测量数据的预处理A.视觉处理前端B.IMU预积分V. 初始化A.Vision-Only SfM in Sliding WindowB.Visual-Inertial AlignmentVI.TIGHTLY COUPLED MONOCULAR VIOA.公式介绍B.IMU误差C.视觉误差D.边缘化E.位姿优化F.以IMU采…

mysql 0x80004005 unable to connect to any of the specified mysql hosts
语言:c# 问题:偶尔会出现连不上mysql 报标题的这个错误。 解决方法:把server localhost 改为 127.0.0.1 或者静态IP ,按着改暂时没出现了,继续观望! 转载于:https://www.cnblogs.com/wdw31210/p/9857514…
iOS开发-自己定义重用机制给ScrollerView加入子视图
iOS开发-自己定义重用机制给ScrollerView加入子视图 事实上这个问题我非常早就想过,仅仅是没有通过去写程序实现,昨天有人提起,我就巧了一下 不知道大家打印郭tableview:cellforrow中cell初始的次数,也就是重用池中的c…

2021年中国工业互联网安全大赛核能行业赛道writeup之Webshell密码
附件题:Webshell密码 题目描述: 某次攻防演练中,抓到了一个webshell的流量,请分析出密码,flag形式:flag{密码} 附件下载: https://download.csdn.net/download/qpeity/33675356https://downlo…

关于python3与python2同时存在情况下导入pyqt失败解决记录
最近感觉tkinter功能还是比较不适合新手做出高大上的界面,故开始使用pyqt,通过pip安装好了之后,利用qt设计师设计好界面之后,cmd运行之,报错提示没有找到pyqt5模块,IDE运行能正常加载 查找资料后发现&#…

ORBSLAM-Altas:多地图SLAM
ORBSLAM-Atlas:多地图SLAM这篇博客ORBSLAM-Altas这个系统系统方法两类子地图新地图的构建相机位姿的可观测性子地图融合系统线程结尾这篇博客 最近ORB-SLAM3横空出世,马上跑去GitHub膜拜。然后在项目的相关工作中看到了ORB-SLAM3使用了一个多地图方法。这…

Android驱动学习-内部机制_回顾binder框架关键点
内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie client使用服务前要先getService:会在驱动程序里对该服务构造一个binder_ref, binder_ref含有desc, node成员…

数据库--事务
我们知道数据库中的SQL语句分为DDL(数据定义语言)、DQL(数据查询语言)、DML(数据操纵语言)、DCL(数据控制语言),详情请看SQL语句 当数据库的表中数据执行完添加、删除、和修改等数据操纵语言(DML)后,需要执行commit(提交)数据控制…

2021年中国工业互联网安全大赛核能行业赛道writeup之传统流量取证
附件题:传统流量取证 题目描述: 在某次攻防演练中,小王发现流量探针平台突然告警,小王第一时间下载了告警流量包,并进行分析:发现攻击队攻击在攻入内网后,利用了一个内网OA的一个漏洞ÿ…

ORB-SLAM3 论文笔记
ORB-SLAM3 论文笔记这篇博客ORB-SLAM3系统相机模型的抽象(Camera Model)重定位的问题图片矫正的问题视觉惯性SLAM的工作原理相关公式IMU初始化跟踪和建图系统对跟踪丢失的应对多地图的闭环检测和地图融合位置识别视觉地图融合方法视觉惯性地图的融合方法单个地图中的闭环融合结…

为什么需要 外键 呢?
生活现象: 不知你们是否遇到过这样的现象,就是你辛辛苦苦花了几十块钱注册一个会员,结果家里的七大姑,八大姨都要拿去用,而且完全可以用。还有就是一个淘宝账号里却可以添加好多个收获地址(里面包括收货人的姓名&#…

JavaScript闭包函数箭头函数调用与执行
一、标准的闭包函数 //一、标准的闭包函数 function A() {var i0;i;console.log(i : i);return function b() {return function c() {return i}} }var a A(); // 初始化A,执行A内的非function语句 ‘ i0; i‘,输出 I : 1 console.log(a()); // 执行fu…
jlink api sdk c# 离线数获取 标定
jlink 如何 离开 keil、IAR 监控变量呢? 目前 jlink的 api 可以做到,自己可以用C# 做一个 上位机,监控RAM里面的变量。而不用打开keil 调试。还可以 刷写 flash,可以用在产品量产的刷写上。SEGGER 的 jlink sdk并不是免费的&…
2021年中国工业互联网安全大赛核能行业赛道writeup之usb流量分析
目录 一、USB协议 二、键盘流量 三、鼠标流量 四、writeup 附件题:usb流量分析 题目描述: 具体描述忘记了o(╯□╰)o 大概意思是有个U盘插到电脑上,然后经过一些操作导致该电脑重启了。找到这个过程中的flag。 附件下载: 20…

BOS项目 第2天(BaseDao、BaseAction、用户登录、自定义strust登录拦截器)
BOS项目 第2天 今天内容安排: 1、根据提供的pdm文件生成sql 2、持久层和表现层设计---BaseDao、BaseAction 3、实现用户登录功能 4、jQuery EasyUI 消息提示控件 5、jQuery EasyUI menubutton菜单按钮 6、自定义struts2拦截器,实现用户未登录自动跳转到…

服务器 主动 推送 客户端浏览器 消息***
前言 通常情况下,无论是web浏览器还是移动app,我们与服务器之间的交互都是主动的,客户端向服务器端发出请求,然后服务器端返回数据给客户端,客户端浏览器再将信息呈现,客户端与服务端对应的模式是: 客户端请…

数据库表(字段类型、约束、截断表、修改表字段、重命名表)
字段类型: 在这里只列举一些常用的字段类型: 整数类型:int(Integer):普通大小的整数 小数类型: float(m,d):单精度浮点数,m表示数字长度,d表示小数位数,例如float(5,2)最大值999.99double(m,d…

(转载)动态SLAM系统:VDO-SLAM!
动态SLAM系统:VDO-SLAM!这篇博客是转载 计算机视觉life 公众号中的文章。这篇文章是对VDO-SLAM论文的全文翻译,是 !!真人工翻译!!不是机器翻译,我看了之后觉得挺好,所以分…

2021年中国工业互联网安全大赛核能行业赛道writeup之入门的黑客
附件题:入门的黑客 题目描述: 在某次工控攻防演练中,防守方使用蜜罐捕捉到了某黑客在入侵时留下的恶意程序样本,现在要对该黑客进行画像,需要从该恶意程序中分析出反连时的IP和端口信息,看看聪明的你能否能…

一种视觉惯性+激光传感器的SLAM系统
一种视觉惯性激光传感器的SLAM系统这篇博客论文摘要一些假设和标注系统总览VI 里程计扫描匹配(scan matching)优化提高系统鲁棒性的措施闭环检测和临近检测全局位姿图优化总结这篇博客 这篇论文“Robust High Accuracy Visual-Inertial-Laser SLAM Syste…

抽象类和接口的联系与区别
抽象类和接口联系与区别 关键字: 抽象类与接口的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。 abstract class和interface之间在对于抽象类定义的支持方面具…

P1132 数字生成游戏
题目描述 小明完成了这样一个数字生成游戏,对于一个不包含00的数字ss来说,有以下33种生成新的数的规则: 将ss的任意两位对换生成新的数字,例如143143可以生成314,413,134314,413,134;将ss的任意一位删除生成新的数字&a…

MySQL02-升级
MySQL 版本号由三个数字和可选后缀组成,形式 mysql-x.y.z-suffix。比如 mysql-5.7.21 或者 mysql-5.7.34。 x(5)这位是大版本y(7)这位是小版本,大版本小版本组合成 5.7 就是一个发行版最后一位是bugfix release版本,从1逐渐增加,…

Kinect V1读取图像数据(For Windows)
Kinect V1读取图像数据(For Windows)这篇博客Kinect V1介绍数据读取的基本流程运行代码和注释结尾这篇博客 刚好有一台现成的Kinect V1相机,所以就拿过来学习一下它的数据读取方式和编程方法,毕竟它还能用于跑RGBD-SLAM。Kinect V…

1.IocDI和Spring
1.面向对象回顾和案例 面向对象程序设计:1 2 3 4 案例分析: 需求分析: 报表功能: 报表服务类,检索数据,并生成图标 报表生成器类,生成不同格式的报表文件,例如PDF格式、Html…

MySQL之模糊查询
先在MySQL数据库里创建一个表,并添加几条数据: create table student(id char(36) primary key,name varchar(8) not null,age int(3) default 0,mobile char(11),address varchar(150) ) insert into student values (9b4435ec-372c-456a-b287-e3c5aa…

rsync工具
rsync工具一、介绍1、可以实现 本地数据 《----------》 远程数据/本地数据 的传输2、两种通信方式(man rsync)(1)remote shell(一个冒号:),通过sshd协议传输(2…

2021年中国工业互联网安全大赛核能行业赛道writeup之日志分析
附件题:日志分析 题目描述: 核电站新来的运维小王粗心把一个办公网地址映射到外网,遭到大量攻击,你能从日志当中找到有效信息吗。 附件下载: 2021-10-12T15_37_51.61064600_00rizhifenxi.rar-网络攻防文档类资源-CSD…

【POJ1509】Glass Beads 【后缀自动机】
题意 给出一个字符串,求它的最小表示法。 分析 这个题当然可以用最小表示法做啦!但是我是为了学后缀自动机鸭! 我们把这个字符串长度乘二,然后建SAM,然后在SAM上每次跑最小的那个字母,找出长度为n的时候就停…

order by总结
先在MySQL数据库里建一个表,并添加几条数据: create table student(id char(36) primary key,name varchar(8) not null,age int(3) default 0,mobile char(11),address varchar(150) ) insert into student values (9b4435ec-372c-456a-b287-e3c5aa23…