活动介绍
file-type

SQL关键字解析:异或注入检测与自动过滤

下载需积分: 10 | 548B | 更新于2024-09-03 | 68 浏览量 | 1 下载量 举报 收藏
download 立即下载
SQL关键字是编程语言中用于特定数据库查询操作的一组预定义符号,它们在编写和执行SQL语句时起着至关重要的作用。在这个文本文件"sql_Keyword.txt"中,列出了大量常用的SQL关键字,这些关键字可以帮助开发者更有效地进行数据处理、查询过滤和安全防范,特别是对于防止SQL注入攻击。 SQL注入是一种常见的Web应用程序安全漏洞,攻击者通过输入恶意SQL代码来操纵数据库,获取未经授权的数据或者破坏系统。文本中提到的"异或注入判断过滤"(使用'^length("§aaa§")!=0'这样的表达式)是一种在应用层面上利用SQL语法特性来检测注入尝试的方法。在这里,`^`通常表示异或运算,而`length()`函数用于获取字符串的长度。通过比较字符串长度与预期值,可以识别出是否进行了非预期的字符插入,从而防止恶意注入。 文件中的部分关键字包括: 1. 操作符:如`!=`(不等于)、`!`(逻辑非)、`%`(匹配任意字符)、`&&`(逻辑与)、`||`(逻辑或)、`<`(小于)、`>`(大于)、`=`, `<>`(不等于),这些用于条件判断和比较。 2. 控制结构:如`if`、`else`、`for`、`while`等,用于控制程序流程。 3. 数据库相关:`database`、`table`、`column`、`schema`等,表示数据库对象。 4. 查询命令:`select`、`from`、`where`、`union`等,用于构造SQL查询语句。 5. 函数和方法:`length()`、`substr()`、`substring()`、`ord()`、`reverse()`等,提供字符串处理功能。 6. 安全相关的词汇:`xor`(异或),虽然在本上下文中用于注入检测,但在一般情况下也用于加密或混淆数据。 理解并正确使用这些关键字,能够帮助开发人员编写高效且安全的SQL代码,同时也能在自动化测试工具如Burp Suite中利用这些关键字实现自动化的安全检查,避免手动注入测试的工作量。例如,通过在文本中的`aaa`位置插入字典值来运行测试,`%0a`和`%a0`可能是编码后的换行符和空格,用于模拟用户输入。 这个文件中的SQL关键字列表提供了编写、优化和安全SQL查询的基础,对IT专业人士来说是一项宝贵的资源。在实际项目中,理解和熟练运用这些关键字能有效提升代码质量,保护系统免受潜在的SQL注入威胁。

相关推荐

filetype

import sys import pymysql from PyQt5.QtWidgets import ( QApplication, QMainWindow, QWidget, QDialog, QTableWidgetItem, QMessageBox, QHeaderView, QPushButton, QLineEdit, QComboBox, QLabel, QVBoxLayout, QHBoxLayout, QFormLayout, QGroupBox, QTableWidget ) from PyQt5.QtCore import Qt from PyQt5.QtGui import QIcon, QIntValidator, QRegExpValidator from PyQt5.QtCore import QRegExp # 数据库配置,与原系统保持一致 DB_CONFIG = { 'host': '127.0.0.1', 'user': 'root', 'password': '123456', 'database': 'studentscore', 'charset': 'utf8mb4' } class LoginDialog(QDialog): """登录窗口""" def __init__(self): super().__init__() self.setWindowTitle("专业管理系统登录") self.setFixedSize(350, 200) # 设置登录窗口的背景颜色为淡蓝色 self.setStyleSheet("background-color: #e0f7fa;") # 创建布局 layout = QVBoxLayout() # 表单组 form_group = QGroupBox("数据库登录信息") form_layout = QFormLayout() self.txt_host = QLineEdit() self.txt_host.setText(DB_CONFIG['host']) self.txt_host.setPlaceholderText("数据库主机地址") self.txt_user = QLineEdit() self.txt_user.setText(DB_CONFIG['user']) self.txt_user.setPlaceholderText("数据库用户名") self.txt_pass = QLineEdit() self.txt_pass.setText(DB_CONFIG['password']) self.txt_pass.setPlaceholderText("数据库密码") self.txt_pass.setEchoMode(QLineEdit.Password) self.txt_db = QLineEdit() self.txt_db.setText(DB_CONFIG['database']) self.txt_db.setPlaceholderText("数据库名称") form_layout.addRow("主机:", self.txt_host) form_layout.addRow("用户名:", self.txt_user) form_layout.addRow("密码:", self.txt_pass) form_layout.addRow("数据库:", self.txt_db) form_group.setLayout(form_layout) # 按钮组 btn_layout = QHBoxLayout() self.btn_login = QPushButton("登录") self.btn_login.clicked.connect(self.attempt_login) self.btn_exit = QPushButton("退出") self.btn_exit.clicked.connect(self.reject) btn_layout.addWidget(self.btn_login) btn_layout.addWidget(self.btn_exit) # 添加到主布局 layout.addWidget(form_group) layout.addLayout(btn_layout) self.setLayout(layout) def attempt_login(self): """尝试登录""" config = { 'host': self.txt_host.text().strip(), 'user': self.txt_user.text().strip(), 'password': self.txt_pass.text().strip(), 'database': self.txt_db.text().strip(), 'charset': 'utf8mb4' } if not all(config.values()): QMessageBox.warning(self, "输入不完整", "请填写所有数据库连接信息") return try: # 测试数据库连接 conn = pymysql.connect(**config) # 检查bmajor表是否存在 with conn.cursor() as cursor: cursor.execute("SHOW TABLES LIKE 'bmajor'") if not cursor.fetchone(): QMessageBox.critical(self, "表不存在", "数据库中未找到bmajor表") return conn.close() # 更新全局配置 global DB_CONFIG DB_CONFIG = config self.accept() # 关闭对话框并返回QDialog.Accepted except pymysql.Error as e: QMessageBox.critical(self, "连接失败", f"数据库连接失败:\n{str(e)}") class MajorManager(QMainWindow): """专业管理主窗口""" def __init__(self): super().__init__() self.setWindowTitle("专业信息管理系统") self.setGeometry(100, 100, 1000, 600) # 创建中央部件 central_widget = QWidget() self.setCentralWidget(central_widget) # 主布局 main_layout = QVBoxLayout(central_widget) # 搜索功能区 search_group = QGroupBox("专业搜索") search_layout = QHBoxLayout() self.lbl_search = QLabel("专业名称:") self.txt_search = QLineEdit() self.txt_search.setPlaceholderText("输入专业名称关键字...") self.btn_search = QPushButton("搜索") self.btn_search.clicked.connect(self.search_major) self.btn_refresh = QPushButton("刷新数据") self.btn_refresh.clicked.connect(self.load_data) search_layout.addWidget(self.lbl_search) search_layout.addWidget(self.txt_search) search_layout.addWidget(self.btn_search) search_layout.addWidget(self.btn_refresh) search_group.setLayout(search_layout) # 数据表格 self.table = self.create_table() # 操作按钮区 btn_group = QGroupBox("专业操作") btn_layout = QHBoxLayout() self.btn_add = QPushButton("添加专业") self.btn_add.clicked.connect(self.add_major) self.btn_edit = QPushButton("编辑专业") self.btn_edit.clicked.connect(self.edit_major) self.btn_delete = QPushButton("删除专业") self.btn_delete.clicked.connect(self.delete_major) btn_layout.addWidget(self.btn_add) btn_layout.addWidget(self.btn_edit) btn_layout.addWidget(self.btn_delete) btn_group.setLayout(btn_layout) # 添加到主布局 main_layout.addWidget(search_group) main_layout.addWidget(self.table, 1) # 表格占据更多空间 main_layout.addWidget(btn_group) # 状态栏 self.statusBar().showMessage("就绪") # 加载数据 self.load_data() def create_table(self): """创建专业表格""" table = QTableWidget() table.setColumnCount(4) table.setHorizontalHeaderLabels(["专业ID", "专业名称", "院系ID", "院系名称"]) table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) table.verticalHeader().setVisible(False) table.setSelectionBehavior(QTableWidget.SelectRows) table.setEditTriggers(QTableWidget.NoEditTriggers) table.setSortingEnabled(True) return table def get_connection(self): """获取数据库连接""" return pymysql.connect(**DB_CONFIG) def load_data(self): """从数据库加载专业数据""" try: conn = self.get_connection() with conn.cursor() as cursor: # 查询bmajor表的所有数据 cursor.execute("SELECT major_id, major_name, depart_id, depart_name FROM bmajor") result = cursor.fetchall() self.table.setRowCount(len(result)) for row_idx, row in enumerate(result): for col_idx, col in enumerate(row): item = QTableWidgetItem(str(col) if col is not None else "") self.table.setItem(row_idx, col_idx, item) conn.close() self.statusBar().showMessage(f"成功加载 {len(result)} 条专业记录") except pymysql.Error as e: QMessageBox.critical(self, "数据库错误", f"加载数据失败:\n{str(e)}") self.statusBar().showMessage("数据加载失败") def add_major(self): """添加新专业""" dialog = MajorDialog(self) if dialog.exec_() == QDialog.Accepted: major_data = dialog.get_data() try: conn = self.get_connection() with conn.cursor() as cursor: sql = """INSERT INTO bmajor (major_id, major_name, depart_id, depart_name) VALUES (%s, %s, %s, %s)""" cursor.execute(sql, major_data) conn.commit() self.load_data() self.statusBar().showMessage(f"成功添加专业: {major_data[1]}") except pymysql.IntegrityError as e: if "Duplicate entry" in str(e): QMessageBox.critical(self, "添加失败", "专业ID或专业名称已存在") else: QMessageBox.critical(self, "添加失败", f"添加专业失败:\n{str(e)}") except pymysql.Error as e: QMessageBox.critical(self, "添加失败", f"添加专业失败:\n{str(e)}") def edit_major(self): """编辑选中专业""" selected = self.table.currentRow() if selected < 0: QMessageBox.warning(self, "未选择", "请先选择要编辑的专业") return major_id = self.table.item(selected, 0).text() dialog = MajorDialog(self, major_id) if dialog.exec_() == QDialog.Accepted: major_data = dialog.get_data() try: conn = self.get_connection() with conn.cursor() as cursor: sql = """UPDATE bmajor SET major_name = %s, depart_id = %s, depart_name = %s WHERE major_id = %s""" # 注意顺序: name, depart_id, depart_name, id cursor.execute(sql, ( major_data[1], major_data[2], major_data[3], major_data[0] )) conn.commit() self.load_data() self.statusBar().showMessage(f"成功更新专业: {major_data[1]}") except pymysql.Error as e: QMessageBox.critical(self, "更新失败", f"更新专业失败:\n{str(e)}") def delete_major(self): """删除选中专业""" selected = self.table.currentRow() if selected < 0: QMessageBox.warning(self, "未选择", "请先选择要删除的专业") return major_id = self.table.item(selected, 0).text() major_name = self.table.item(selected, 1).text() reply = QMessageBox.question(self, "确认删除", f"确定要删除专业 '{major_name}' (ID: {major_id}) 吗?", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: try: conn = self.get_connection() with conn.cursor() as cursor: cursor.execute("DELETE FROM bmajor WHERE major_id = %s", (major_id,)) conn.commit() self.load_data() self.statusBar().showMessage(f"已删除专业: {major_name}") except pymysql.Error as e: # 检查是否有外键约束 if "foreign key constraint" in str(e).lower(): QMessageBox.critical(self, "删除失败", "该专业可能被其他表引用,无法删除") else: QMessageBox.critical(self, "删除失败", f"删除专业失败:\n{str(e)}") def search_major(self): """搜索专业""" keyword = self.txt_search.text().strip() if not keyword: self.load_data() return try: conn = self.get_connection() with conn.cursor() as cursor: cursor.execute("SELECT major_id, major_name, depart_id, depart_name " "FROM bmajor WHERE major_name LIKE %s", (f"%{keyword}%",)) result = cursor.fetchall() self.table.setRowCount(len(result)) for row_idx, row in enumerate(result): for col_idx, col in enumerate(row): item = QTableWidgetItem(str(col) if col is not None else "") self.table.setItem(row_idx, col_idx, item) conn.close() self.statusBar().showMessage(f"找到 {len(result)} 条匹配专业") except pymysql.Error as e: QMessageBox.critical(self, "搜索失败", f"搜索专业失败:\n{str(e)}") class MajorDialog(QDialog): """专业编辑对话框""" def __init__(self, parent=None, major_id=None): super().__init__(parent) self.setWindowTitle("添加专业" if not major_id else "编辑专业") self.setFixedSize(400, 350) # 主布局 layout = QVBoxLayout() # 表单布局 form_layout = QFormLayout() self.txt_id = QLineEdit() self.txt_id.setPlaceholderText("2位专业代码") # 设置专业ID验证器,必须是2位字母或数字 id_validator = QRegExpValidator(QRegExp(r'^[a-zA-Z0-9]{2}$')) self.txt_id.setValidator(id_validator) self.txt_name = QLineEdit() self.txt_name.setPlaceholderText("输入专业名称") self.txt_depart_id = QLineEdit() self.txt_depart_id.setPlaceholderText("2位院系代码") # 设置院系ID验证器,必须是2位字母或数字 depart_id_validator = QRegExpValidator(QRegExp(r'^[a-zA-Z0-9]{2}$')) self.txt_depart_id.setValidator(depart_id_validator) self.txt_depart_name = QLineEdit() self.txt_depart_name.setPlaceholderText("输入院系名称") form_layout.addRow("专业ID:", self.txt_id) form_layout.addRow("专业名称:", self.txt_name) form_layout.addRow("院系ID:", self.txt_depart_id) form_layout.addRow("院系名称:", self.txt_depart_name) # 按钮布局 btn_layout = QHBoxLayout() self.btn_save = QPushButton("保存") self.btn_save.clicked.connect(self.validate_and_accept) self.btn_cancel = QPushButton("取消") self.btn_cancel.clicked.connect(self.reject) btn_layout.addStretch() btn_layout.addWidget(self.btn_save) btn_layout.addWidget(self.btn_cancel) # 添加到主布局 layout.addLayout(form_layout) layout.addLayout(btn_layout) self.setLayout(layout) # 如果是编辑模式,加载现有数据 self.major_id = major_id if major_id: self.load_major_data() self.txt_id.setEnabled(False) # 禁止编辑专业ID def load_major_data(self): """加载专业数据到表单""" try: conn = pymysql.connect(**DB_CONFIG) with conn.cursor() as cursor: cursor.execute("SELECT * FROM bmajor WHERE major_id = %s", (self.major_id,)) result = cursor.fetchone() if result: self.txt_id.setText(result[0]) self.txt_name.setText(result[1]) self.txt_depart_id.setText(result[2] if result[2] is not None else "") self.txt_depart_name.setText(result[3] if result[3] is not None else "") conn.close() except pymysql.Error as e: QMessageBox.critical(self, "加载失败", f"加载专业数据失败:\n{str(e)}") def get_data(self): """从表单获取数据""" # 处理可能为空的值 def get_value_or_none(text): return text.strip() if text.strip() else None return ( self.txt_id.text().strip(), self.txt_name.text().strip(), get_value_or_none(self.txt_depart_id.text()), get_value_or_none(self.txt_depart_name.text()) ) def validate_and_accept(self): """验证表单数据并接受""" # 验证专业ID格式 major_id = self.txt_id.text().strip() if len(major_id) != 2: QMessageBox.warning(self, "格式错误", "专业ID必须是2位字符") return # 验证必填字段 if not self.txt_name.text().strip(): QMessageBox.warning(self, "输入不完整", "专业名称不能为空") return # 验证院系ID depart_id = self.txt_depart_id.text().strip() if depart_id and len(depart_id) != 2: QMessageBox.warning(self, "格式错误", "院系ID必须是2位字符") return super().accept() if __name__ == "__main__": app = QApplication(sys.argv) # 显示登录窗口 login = LoginDialog() if login.exec_() != QDialog.Accepted: sys.exit() # 显示主窗口 window = MajorManager() window.show() sys.exit(app.exec_())

filetype

import re import sqlite3 from collections import Counter from tkinter import * from tkinter import ttk, messagebox import tkinter.scrolledtext as scrolledtext from nltk.corpus import stopwords from nltk.tokenize import word_tokenize import nltk import threading # 下载NLTK数据(第一次运行时需要) nltk.download('stopwords') nltk.download('punkt') class AcademicPaperManager: def __init__(self, root): self.root = root self.root.title("学术论文管理系统") self.root.geometry("1000x700") # 初始化数据库 self.init_db() # 创建界面 self.create_widgets() # 加载停用词 self.stop_words = set(stopwords.words('english')) def init_db(self): """初始化数据库""" self.conn = sqlite3.connect('papers.db') self.cursor = self.conn.cursor() # 创建表 self.cursor.execute(''' CREATE TABLE IF NOT EXISTS papers ( id INTEGER PRIMARY KEY, title TEXT, year INTEGER, journal TEXT, volume TEXT, number TEXT, pages TEXT, abstract TEXT, doi TEXT, issn TEXT, month TEXT ) ''') self.cursor.execute(''' CREATE TABLE IF NOT EXISTS authors ( id INTEGER PRIMARY KEY, name TEXT UNIQUE ) ''') self.cursor.execute(''' CREATE TABLE IF NOT EXISTS paper_author ( paper_id INTEGER, author_id INTEGER, PRIMARY KEY (paper_id, author_id), FOREIGN KEY (paper_id) REFERENCES papers(id), FOREIGN KEY (author_id) REFERENCES authors(id) ) ''') self.cursor.execute(''' CREATE TABLE IF NOT EXISTS keywords ( id INTEGER PRIMARY KEY, keyword TEXT UNIQUE ) ''') self.cursor.execute(''' CREATE TABLE IF NOT EXISTS paper_keyword ( paper_id INTEGER, keyword_id INTEGER, PRIMARY KEY (paper_id, keyword_id), FOREIGN KEY (paper_id) REFERENCES papers(id), FOREIGN KEY (keyword_id) REFERENCES keywords(id) ) ''') self.conn.commit() def create_widgets(self): """创建界面组件""" # 顶部框架 - 导入功能 top_frame = Frame(self.root) top_frame.pack(pady=10, fill=X) Label(top_frame, text="BibTeX文件路径:").grid(row=0, column=0, padx=5) self.file_path = Entry(top_frame, width=50) self.file_path.grid(row=0, column=1, padx=5) Button(top_frame, text="浏览", command=self.browse_file).grid(row=0, column=2, padx=5) Button(top_frame, text="导入数据", command=self.start_import).grid(row=0, column=3, padx=5) # 进度条和状态 self.progress = ttk.Progressbar(top_frame, orient=HORIZONTAL, length=200, mode='determinate') self.progress.grid(row=1, column=0, columnspan=4, pady=5, sticky='ew') self.status = Label(top_frame, text="就绪") self.status.grid(row=2, column=0, columnspan=4) # 中间框架 - 查询功能 middle_frame = Frame(self.root) middle_frame.pack(pady=10, fill=X) # 查询条件 Label(middle_frame, text="关键词:").grid(row=0, column=0, padx=5) self.keyword_entry = Entry(middle_frame, width=20) self.keyword_entry.grid(row=0, column=1, padx=5) Label(middle_frame, text="作者:").grid(row=0, column=2, padx=5) self.author_entry = Entry(middle_frame, width=20) self.author_entry.grid(row=0, column=3, padx=5) Label(middle_frame, text="年份:").grid(row=0, column=4, padx=5) self.year_entry = Entry(middle_frame, width=10) self.year_entry.grid(row=0, column=5, padx=5) Button(middle_frame, text="查询", command=self.search_papers).grid(row=0, column=6, padx=5) Button(middle_frame, text="查询合作关系", command=self.search_collaborators).grid(row=0, column=7, padx=5) Button(middle_frame, text="统计高频词", command=self.show_top_words).grid(row=0, column=8, padx=5) # 底部框架 - 结果显示 bottom_frame = Frame(self.root) bottom_frame.pack(pady=10, fill=BOTH, expand=True) # 结果列表 self.tree = ttk.Treeview(bottom_frame, columns=('ID', 'Title', 'Authors', 'Year', 'Journal'), show='headings') self.tree.heading('ID', text='ID') self.tree.heading('Title', text='标题') self.tree.heading('Authors', text='作者') self.tree.heading('Year', text='年份') self.tree.heading('Journal', text='期刊') self.tree.column('ID', width=50) self.tree.column('Title', width=300) self.tree.column('Authors', width=200) self.tree.column('Year', width=50) self.tree.column('Journal', width=150) self.tree.pack(side=LEFT, fill=BOTH, expand=True) # 添加滚动条 scrollbar = ttk.Scrollbar(bottom_frame, orient=VERTICAL, command=self.tree.yview) scrollbar.pack(side=RIGHT, fill=Y) self.tree.configure(yscrollcommand=scrollbar.set) # 详情面板 self.details = scrolledtext.ScrolledText(self.root, width=100, height=10) self.details.pack(pady=10, fill=BOTH, expand=False) # 绑定事件 self.tree.bind('<<TreeviewSelect>>', self.show_paper_details) def browse_file(self): """浏览文件""" from tkinter.filedialog import askopenfilename filepath = askopenfilename(filetypes=[("BibTeX files", "*.bib"), ("Text files", "*.txt"), ("All files", "*.*")]) if filepath: self.file_path.delete(0, END) self.file_path.insert(0, filepath) def start_import(self): """开始导入数据""" filepath = self.file_path.get() if not filepath: messagebox.showerror("错误", "请选择BibTeX文件") return # 清空进度条 self.progress['value'] = 0 self.status.config(text="正在导入...") # 直接在主线程中执行导入 self.import_data(filepath) def import_data(self, filepath): """导入数据到数据库""" try: with open(filepath, 'r', encoding='utf-8') as f: content = f.read() # 解析BibTeX文件 entries = self.parse_bibtex(content) total = len(entries) for i, entry in enumerate(entries): # 更新进度 progress = (i + 1) / total * 100 self.root.after(0, lambda p=progress: self.update_progress(p, f"正在导入 {i+1}/{total}")) # 插入论文 paper_id = self.insert_paper(entry) # 插入作者 if 'author' in entry: authors = self.parse_authors(entry['author']) for author in authors: author_id = self.insert_author(author) self.insert_paper_author(paper_id, author_id) # 插入关键词 if 'keywords' in entry: keywords = [kw.strip() for kw in entry['keywords'].split(';')] for keyword in keywords: keyword_id = self.insert_keyword(keyword) self.insert_paper_keyword(paper_id, keyword_id) self.root.after(0, lambda: self.update_progress(100, f"导入完成,共导入 {total} 篇论文")) self.root.after(0, lambda: messagebox.showinfo("成功", f"成功导入 {total} 篇论文")) except Exception as e: self.root.after(0, lambda: messagebox.showerror("错误", f"导入失败: {str(e)}")) self.root.after(0, lambda: self.update_progress(0, "导入失败")) def update_progress(self, value, text): """更新进度条和状态""" self.progress['value'] = value self.status.config(text=text) self.root.update() def parse_bibtex(self, content): """解析BibTeX内容""" entries = [] pattern = re.compile(r'@(\w+)\s*\{([^,]+),\s*([^@]*)\}', re.DOTALL) for match in pattern.finditer(content): entry_type = match.group(1) entry_key = match.group(2) entry_fields = match.group(3) if entry_type.lower() != 'article': continue entry = {'key': entry_key} field_pattern = re.compile(r'(\w+)\s*=\s*\{([^}]*)\}', re.DOTALL) for field_match in field_pattern.finditer(entry_fields): field_name = field_match.group(1).lower() field_value = field_match.group(2).strip() entry[field_name] = field_value entries.append(entry) return entries def parse_authors(self, author_str): """解析作者字符串""" # 处理类似 "Chen, Zheyi and Liang, Jie and Yu, Zhengxin" 的格式 authors = [] for author in author_str.split(' and '): author = author.strip() if ',' in author: last, first = author.split(',', 1) author = f"{first.strip()} {last.strip()}" authors.append(author) return authors def insert_paper(self, entry): """插入论文到数据库""" self.cursor.execute(''' INSERT INTO papers (title, year, journal, volume, number, pages, abstract, doi, issn, month) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ''', ( entry.get('title', ''), int(entry['year']) if 'year' in entry else None, entry.get('journal', ''), entry.get('volume', ''), entry.get('number', ''), entry.get('pages', ''), entry.get('abstract', ''), entry.get('doi', ''), entry.get('issn', ''), entry.get('month', '') )) self.conn.commit() return self.cursor.lastrowid def insert_author(self, author_name): """插入作者到数据库""" self.cursor.execute(''' INSERT OR IGNORE INTO authors (name) VALUES (?) ''', (author_name,)) self.conn.commit() self.cursor.execute('SELECT id FROM authors WHERE name = ?', (author_name,)) return self.cursor.fetchone()[0] def insert_paper_author(self, paper_id, author_id): """插入论文-作者关系到数据库""" self.cursor.execute(''' INSERT OR IGNORE INTO paper_author (paper_id, author_id) VALUES (?, ?) ''', (paper_id, author_id)) self.conn.commit() def insert_keyword(self, keyword): """插入关键词到数据库""" self.cursor.execute(''' INSERT OR IGNORE INTO keywords (keyword) VALUES (?) ''', (keyword,)) self.conn.commit() self.cursor.execute('SELECT id FROM keywords WHERE keyword = ?', (keyword,)) return self.cursor.fetchone()[0] def insert_paper_keyword(self, paper_id, keyword_id): """插入论文-关键词关系到数据库""" self.cursor.execute(''' INSERT OR IGNORE INTO paper_keyword (paper_id, keyword_id) VALUES (?, ?) ''', (paper_id, keyword_id)) self.conn.commit() def search_papers(self): """查询论文""" keyword = self.keyword_entry.get().strip() author = self.author_entry.get().strip() year = self.year_entry.get().strip() query = ''' SELECT p.id, p.title, GROUP_CONCAT(a.name, ', '), p.year, p.journal FROM papers p JOIN paper_author pa ON p.id = pa.paper_id JOIN authors a ON pa.author_id = a.id ''' conditions = [] params = [] if keyword: query += ''' JOIN paper_keyword pk ON p.id = pk.paper_id JOIN keywords k ON pk.keyword_id = k.id ''' conditions.append("k.keyword LIKE ?") params.append(f"%{keyword}%") if author: conditions.append("a.name LIKE ?") params.append(f"%{author}%") if year: conditions.append("p.year = ?") params.append(year) if conditions: query += " WHERE " + " AND ".join(conditions) query += " GROUP BY p.id" self.cursor.execute(query, params) papers = self.cursor.fetchall() # 清空树视图 for item in self.tree.get_children(): self.tree.delete(item) # 添加结果 for paper in papers: self.tree.insert('', 'end', values=paper) self.status.config(text=f"找到 {len(papers)} 篇论文") def search_collaborators(self): """查询合作关系""" author_name = self.author_entry.get().strip() if not author_name: messagebox.showwarning("警告", "请输入作者名") return # 查找作者ID self.cursor.execute('SELECT id FROM authors WHERE name LIKE ?', (f"%{author_name}%",)) authors = self.cursor.fetchall() if not authors: messagebox.showinfo("提示", "未找到该作者") return # 查询合作关系 collaborators = set() for author_id in authors: self.cursor.execute(''' SELECT a.name FROM authors a JOIN paper_author pa ON a.id = pa.author_id WHERE pa.paper_id IN ( SELECT paper_id FROM paper_author WHERE author_id = ? ) AND a.id != ? ''', (author_id[0], author_id[0])) for collab in self.cursor.fetchall(): collaborators.add(collab[0]) # 显示结果 if collaborators: result = f"作者 {author_name} 的合作者:\n\n" + "\n".join(collaborators) self.details.delete(1.0, END) self.details.insert(END, result) self.status.config(text=f"找到 {len(collaborators)} 位合作者") else: messagebox.showinfo("提示", "未找到合作者") def show_top_words(self): """显示摘要高频词""" self.cursor.execute('SELECT abstract FROM papers') abstracts = [row[0] for row in self.cursor.fetchall() if row[0]] if not abstracts: messagebox.showinfo("提示", "没有可用的摘要数据") return # 分词并统计 words = [] for abstract in abstracts: tokens = word_tokenize(abstract.lower()) words.extend([word for word in tokens if word.isalpha() and word not in self.stop_words]) word_counts = Counter(words) top_words = word_counts.most_common(20) # 显示结果 result = "摘要高频词Top 20:\n\n" for word, count in top_words: result += f"{word}: {count}\n" self.details.delete(1.0, END) self.details.insert(END, result) self.status.config(text="已统计摘要高频词") def show_paper_details(self, event): """显示论文详情""" selected = self.tree.focus() if not selected: return paper_id = self.tree.item(selected, 'values')[0] # 获取论文详情 self.cursor.execute('SELECT * FROM papers WHERE id = ?', (paper_id,)) paper = self.cursor.fetchone() # 获取作者 self.cursor.execute(''' SELECT a.name FROM authors a JOIN paper_author pa ON a.id = pa.author_id WHERE pa.paper_id = ? ''', (paper_id,)) authors = ", ".join([row[0] for row in self.cursor.fetchall()]) # 获取关键词 self.cursor.execute(''' SELECT k.keyword FROM keywords k JOIN paper_keyword pk ON k.id = pk.keyword_id WHERE pk.paper_id = ? ''', (paper_id,)) keywords = ", ".join([row[0] for row in self.cursor.fetchall()]) # 显示详情 details = f""" 标题: {paper[1]} 作者: {authors} 年份: {paper[2]} 期刊: {paper[3]} 卷: {paper[4]} 期: {paper[5]} 页: {paper[6]} DOI: {paper[8]} ISSN: {paper[9]} 月份: {paper[10]} 关键词: {keywords} 摘要: {paper[7]} """ self.details.delete(1.0, END) self.details.insert(END, details) if __name__ == "__main__": root = Tk() app = AcademicPaperManager(root) root.mainloop() 详细解析此段代码

filetype

package com.student.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.student.entity.Student; import com.student.util.DBUtil; public class StudentDAO { // 插入学生 public void insertStudent(Student student) { String sql = "INSERT INTO students (sid, name, age, score) VALUES (?, ?, ?, ?)"; try (Connection conn = DBUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, student.getSid()); pstmt.setString(2, student.getName()); pstmt.setInt(3, student.getAge()); pstmt.setDouble(4, student.getScore()); pstmt.executeUpdate(); } catch (SQLException e) { System.err.println("插入学生信息时出现错误: " + e.getMessage()); } } // 获取所有学生 public List<Student> getAllStudents() { List<Student> students = new ArrayList<>(); String sql = "SELECT * FROM students"; try (Connection conn = DBUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { students.add(extractStudentFromResultSet(rs)); } } catch (SQLException e) { e.printStackTrace(); } return students; } // 删除学生(修改方法名) public void deleteStudent(String sid) { // 这里修改了方法名 String sql = "DELETE FROM students WHERE sid = ?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, sid); int rowsAffected = pstmt.executeUpdate(); if (rowsAffected == 0) { System.err.println("未找到学号为 " + sid + " 的学生"); } } catch (SQLException e) { e.printStackTrace(); } } // 更新学生信息 public void updateStudent(Student student) { String sql = "UPDATE students SET name = ?, age = ?, score = ? WHERE sid = ?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, student.getName()); pstmt.setInt(2, student.getAge()); pstmt.setDouble(3, student.getScore()); pstmt.setString(4, student.getSid()); int rowsAffected = pstmt.executeUpdate(); if (rowsAffected == 0) { System.err.println("未找到学号为 " + student.getSid() + " 的学生"); } } catch (SQLException e) { e.printStackTrace(); } } // 搜索学生 public List<Student> searchStudents(String keyword) { List<Student> students = new ArrayList<>(); String sql = "SELECT * FROM students WHERE sid LIKE ? OR name LIKE ?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { String searchPattern = "%" + keyword + "%"; pstmt.setString(1, searchPattern); pstmt.setString(2, searchPattern); try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { students.add(extractStudentFromResultSet(rs)); } } } catch (SQLException e) { e.printStackTrace(); } return students; } // 排序学生 public List<Student> getStudentsOrderBy(String field) { List<Student> students = new ArrayList<>(); String validField = validateSortField(field); String sql = "SELECT * FROM students ORDER BY " + validField; try (Connection conn = DBUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { students.add(extractStudentFromResultSet(rs)); } } catch (SQLException e) { e.printStackTrace(); } return students; } // 根据ID获取学生 public Student getStudentById(String sid) { String sql = "SELECT * FROM students WHERE sid = ?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, sid); try (ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { return extractStudentFromResultSet(rs); } } } catch (SQLException e) { e.printStackTrace(); } return null; } // 验证排序字段(防止SQL注入) private String validateSortField(String field) { String[] validFields = {"sid", "name", "age", "score"}; for (String valid : validFields) { if (valid.equalsIgnoreCase(field)) { return valid; } } return "sid"; // 默认值 } // 从ResultSet提取学生对象(复用代码) private Student extractStudentFromResultSet(ResultSet rs) throws SQLException { String sid = rs.getString("sid"); String name = rs.getString("name"); int age = rs.getInt("age"); double score = rs.getDouble("score"); return new Student(sid, name, age, score); } } 根据上面的给我一个可运行的完整代码

airrudder
  • 粉丝: 106
上传资源 快速赚钱