Python SQLAlchemy库详解

news2024/10/6 14:35:29

        大家好,在Python生态系统中,SQLAlchemy库是一个强大的工具,为开发人员提供了便捷的方式来处理与数据库的交互。无论是开发一个小型的Web应用程序,还是构建一个大型的企业级系统,SQLAlchemy都能满足你的需求,并提供灵活性和性能上的优势。本文将带你深入探索SQLAlchemy库,从基础概念到高级用法,让你对其有一个全面的了解。

一、介绍

        SQLAlchemy是Python中一个强大的开源SQL工具包和对象关系映射(ORM)库,它允许开发人员以Python代码的方式与关系型数据库进行交互。无论是简单的SQLite数据库,还是复杂的MySQL、PostgreSQL、Oracle等企业级数据库,SQLAlchemy都能轻松应对。

        在传统的数据库交互中,开发人员通常需要编写大量的SQL语句来执行各种操作,如创建表、插入数据、查询记录等。这种方式可能会导致代码重复、可维护性差和安全性问题。而SQLAlchemy的出现解决了这些问题。

        SQLAlchemy提供了一种更加直观和Pythonic的方式来处理数据库交互。它的主要优势之一是将数据库表映射为Python类,使得开发人员可以使用面向对象的方式来操作数据库,而不必直接与SQL语句打交道。这种抽象化的设计让数据库操作变得更加简单和直观。

        此外,SQLAlchemy还提供了强大的查询语言和灵活的对象关系映射机制,使得开发人员可以轻松地执行复杂的数据库查询和操作。它支持事务管理、连接池、数据库连接的自动管理等功能,为开发人员提供了一套完整的数据库解决方案。

二、安装和配置SQLAlchemy

        安装SQLAlchemy非常简单,可以通过pip(Python包管理器)来完成。以下是安装SQLAlchemy的步骤:

1、使用pip安装SQLAlchemy

打开命令行界面(如终端或命令提示符),然后运行以下命令:

pip install sqlalchemy

这将会从Python Package Index(PyPI)下载并安装SQLAlchemy库及其依赖项。

2、确认安装

安装完成后,你可以运行以下命令来确认SQLAlchemy已成功安装:

python -c "import sqlalchemy; print(sqlalchemy.__version__)"

如果安装成功,将会打印出SQLAlchemy的版本号。

现在,SQLAlchemy已经成功安装在你的Python环境中了。接下来,让我们进行简单的配置。

3、配置SQLAlchemy连接

        在使用SQLAlchemy之前,你需要配置连接信息,以便连接到数据库。SQLAlchemy支持多种数据库,因此你需要根据你使用的数据库类型进行相应的配置。以下是一个简单的示例,演示如何配置连接到SQLite数据库:

from sqlalchemy import create_engine

# SQLite数据库连接字符串
DATABASE_URL = "sqlite:///mydatabase.db"

# 创建数据库引擎
engine = create_engine(DATABASE_URL)

# 测试连接是否成功
if engine.connect():
    print("Connection successful!")
else:
    print("Connection failed!")

        在这个示例中,我们使用了SQLite数据库,并指定了一个SQLite连接字符串作为数据库的路径。你可以根据自己的需要修改连接字符串,以连接到其他类型的数据库,如MySQL、PostgreSQL等。

三、核心概念

        当谈到SQLAlchemy的核心概念时,通常涉及到一些重要的概念和组件,包括表(Table)、模型(Model)、会话(Session)等。下面是对这些核心概念的详细介绍:

  1. 表(Table)

    表是数据库中存储数据的结构化方式,它由一系列列组成,每列定义了表中存储的数据的类型。在SQLAlchemy中,表可以通过Table类来表示,通常与数据库中的实际表相对应。你可以使用Table类来定义表的结构,包括列的名称、数据类型、约束条件等。

  2. 模型(Model)

    模型是SQLAlchemy中最重要的概念之一,它将数据库中的表映射为Python类。每个模型类对应着数据库中的一个表,类的属性对应着表中的列。通过模型,你可以使用面向对象的方式来操作数据库,而不必直接编写SQL语句。在SQLAlchemy中,模型通常是通过继承declarative_base类创建的。

  3. 会话(Session)

    会话是SQLAlchemy中用于管理数据库事务的核心组件之一。通过会话,你可以执行数据库的增、删、改、查等操作,并确保这些操作在一个事务中原子地提交或回滚。会话提供了一种高层次的接口,使得对数据库的操作更加简单和直观。在SQLAlchemy中,你可以通过sessionmaker来创建会话工厂,然后使用这个工厂创建会话对象。

        以上是SQLAlchemy中的一些核心概念,它们构成了SQLAlchemy强大而灵活的ORM框架的基础。理解这些概念将有助于你更好地使用SQLAlchemy进行数据库操作,提高代码的可维护性和可读性。在后续的文章中,我们将会更深入地探讨这些概念,并演示如何在实际项目中应用它们。

四、基本用法

        下面是SQLAlchemy中基本用法的详细介绍,包括如何创建数据库模型以及执行基本的CRUD操作(创建、读取、更新、删除):

1、创建数据库模型

        首先,我们需要定义数据库模型,通常是通过创建一个继承自Base的Python类来实现的。这个类对应着数据库中的一张表,类的属性对应着表中的列。例如,我们创建一个简单的User模型来表示用户表:

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    username = Column(String)
    email = Column(String)

2、执行基本的CRUD操作

        一旦定义了数据库模型,我们就可以使用SQLAlchemy来执行各种数据库操作,包括创建、读取、更新、删除等。

(1)创建(Create)

        要创建新的数据库记录,我们可以使用模型类的构造函数来创建对象,然后将其添加到会话中,并提交事务以保存到数据库:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# 创建数据库引擎
engine = create_engine('sqlite:///mydatabase.db')

# 创建会话工厂
Session = sessionmaker(bind=engine)
session = Session()

# 创建新用户
new_user = User(username='John', email='john@example.com')
session.add(new_user)
session.commit()

(2)读取(Read)

        要从数据库中读取记录,我们可以使用查询语句来执行查询操作,并使用all()方法获取所有结果或first()方法获取第一个结果:

# 查询所有用户
all_users = session.query(User).all()

# 查询第一个用户
first_user = session.query(User).first()

(3)更新(Update)

        要更新数据库记录,我们可以获取要更新的对象,然后修改其属性,并提交事务以保存更改到数据库:

# 查询并更新用户
user = session.query(User).filter_by(username='John').first()
user.email = 'john_new@example.com'
session.commit()

(4)删除(Delete)

要删除数据库记录,我们可以使用delete()方法来删除对象,并提交事务以保存更改到数据库:

# 查询并删除用户
user = session.query(User).filter_by(username='John').first()
session.delete(user)
session.commit()

        通过以上步骤,我们可以使用SQLAlchemy执行基本的CRUD操作,从而实现对数据库的增、删、改、查等功能。这些操作可以帮助我们轻松地管理数据库中的数据,提高开发效率和代码质量。

五、查询

        在SQLAlchemy中,查询是使用query()方法执行的。通过查询对象,您可以执行各种数据库操作,包括过滤、排序、连接等。

1、过滤(Filter)

过滤操作用于根据特定条件检索数据。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Employee  # 假设Employee模型已经定义

# 创建数据库引擎和会话
engine = create_engine('sqlite:///example.db')
Session = sessionmaker(bind=engine)
session = Session()

# 查询所有名字为"John"的员工
john_employees = session.query(Employee).filter(Employee.name == 'John').all()

2、排序(Order By)

排序操作用于按特定列的顺序检索数据。

# 查询所有员工按照名字的字母顺序排序
sorted_employees = session.query(Employee).order_by(Employee.name).all()

3、连接(Join)

连接操作用于联合两个或多个表以获取相关联的数据。

from models import Department  # 假设Department模型已经定义

# 查询所有员工及其所属部门的名称
employees_with_departments = session.query(Employee, Department).join(Employee.department).all()

4、聚合函数(Aggregate Functions)

聚合函数用于执行统计操作,如计数、求和、平均值等。

from sqlalchemy import func

# 查询员工数量
employee_count = session.query(func.count(Employee.id)).scalar()

5、过滤并排序(Filter and Order By)

您可以结合使用过滤和排序来执行更精细的数据检索。

# 查询名字为"John"的员工并按照ID降序排列
john_employees_sorted = session.query(Employee).filter(Employee.name == 'John').order_by(Employee.id.desc()).all()

6、聚合查询(Group By)

聚合查询用于对数据进行分组并应用聚合函数。

# 查询每个部门的员工数量
from sqlalchemy import func

employee_count_by_department = session.query(Employee.department_id, func.count(Employee.id)).group_by(Employee.department_id).all()

7、子查询(Subquery)

子查询是在主查询中使用的嵌套查询。

# 查询工资高于平均工资的员工
from sqlalchemy.sql import select

avg_salary = session.query(func.avg(Employee.salary)).scalar()
subquery = select([Employee]).where(Employee.salary > avg_salary).alias()
employees_above_avg_salary = session.query(subquery).all()

8、原生 SQL 查询(Raw SQL Query)

有时您可能需要执行原生的 SQL 查询,SQLAlchemy也支持这种方式。

# 执行原生 SQL 查询
result = session.execute("SELECT * FROM employees WHERE salary > :salary", {"salary": 50000})
for row in result:
    print(row)

六、关联关系

        关联关系在数据库中非常常见,用于表示不同表之间的关联和连接。在SQLAlchemy中,您可以使用外键和关系来定义和管理这些关联关系。我将详细介绍如何定义和使用数据库表之间的不同关联关系,包括一对一、一对多和多对多关系。

1. 一对一关系(One-to-One Relationship)

一对一关系表示两个表之间的一一对应关系。例如,一个人只能有一个身份证号,而一个身份证号也只能对应一个人。

定义模型:
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Person(Base):
    __tablename__ = 'persons'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    identity_card_id = Column(Integer, ForeignKey('identity_cards.id'))

    identity_card = relationship("IdentityCard", uselist=False)

class IdentityCard(Base):
    __tablename__ = 'identity_cards'

    id = Column(Integer, primary_key=True)
    number = Column(String, unique=True)

使用:

# 创建一个人和一个身份证号
person = Person(name='John')
identity_card = IdentityCard(number='1234567890')

# 关联两者
person.identity_card = identity_card

2. 一对多关系(One-to-Many Relationship)

一对多关系表示一个对象可以有多个相关联的对象。例如,一个部门可以有多个员工,但一个员工只能属于一个部门。

定义模型:
class Department(Base):
    __tablename__ = 'departments'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    employees = relationship("Employee", back_populates="department")

class Employee(Base):
    __tablename__ = 'employees'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    department_id = Column(Integer, ForeignKey('departments.id'))

    department = relationship("Department", back_populates="employees")

使用:

# 创建一个部门和两个员工
department = Department(name='IT')
employee1 = Employee(name='John')
employee2 = Employee(name='Alice')

# 关联员工到部门
department.employees.append(employee1)
department.employees.append(employee2)

3. 多对多关系(Many-to-Many Relationship)

多对多关系表示两个对象之间存在复杂的多对多关系。例如,学生和课程之间的关系,一个学生可以选修多门课程,而一门课程也可以被多个学生选修。

定义模型:
association_table = Table('association', Base.metadata,
    Column('student_id', Integer, ForeignKey('students.id')),
    Column('course_id', Integer, ForeignKey('courses.id'))
)

class Student(Base):
    __tablename__ = 'students'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    courses = relationship("Course", secondary=association_table, back_populates="students")

class Course(Base):
    __tablename__ = 'courses'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    students = relationship("Student", secondary=association_table, back_populates="courses")

使用:

# 创建两个学生和两门课程
student1 = Student(name='John')
student2 = Student(name='Alice')
course1 = Course(name='Math')
course2 = Course(name='Science')

# 关联学生和课程
student1.courses.append(course1)
student1.courses.append(course2)
student2.courses.append(course2)

        以上是在SQLAlchemy中定义和使用一对一、一对多和多对多关系的示例。您可以根据实际需求,在模型中定义适当的关联关系,以便更好地管理和操作您的数据。

七、事务管理

        事务管理是数据库操作中非常重要的一部分,它确保了数据库操作的一致性和完整性。在SQLAlchemy中,您可以使用会话(Session)对象来管理事务。我将详细介绍如何使用SQLAlchemy来管理事务。

1、开启事务

        在SQLAlchemy中,当您创建一个会话(Session)对象时,事务会自动开启。您可以使用session.begin()方法手动开启事务。

from sqlalchemy.orm import sessionmaker

# 创建会话
Session = sessionmaker(bind=engine)
session = Session()

# 手动开启事务
session.begin()

2、提交事务

        一旦您对数据库进行了一系列的操作,并且希望将这些操作永久保存到数据库中,您可以使用session.commit()方法提交事务。

# 提交事务
session.commit()

3、回滚事务

        如果在事务进行过程中出现了错误,或者您想要取消之前的操作,您可以使用session.rollback()方法回滚事务。

try:
    # 一系列数据库操作
    session.commit()
except Exception as e:
    # 回滚事务
    session.rollback()

4、自动提交

        在某些情况下,您可能希望在每次数据库操作后自动提交事务,而不是手动调用commit()方法。您可以通过设置会话的autocommit参数来实现这一点。

# 创建自动提交的会话
Session = sessionmaker(bind=engine, autocommit=True)
session = Session()

5、事务的嵌套

        在SQLAlchemy中,事务是可以嵌套的。如果您在一个事务中开启了另一个事务,那么内部事务的提交和回滚不会影响外部事务。外部事务的提交或回滚会同时提交或回滚内部事务。

# 开启外部事务
session.begin()

try:
    # 一系列数据库操作
    session.begin_nested()

    try:
        # 更多数据库操作
        session.commit()  # 提交内部事务
    except Exception as e:
        session.rollback()  # 回滚内部事务
        raise

    session.commit()  # 提交外部事务
except Exception as e:
    session.rollback()  # 回滚外部事务
    raise

6、事务的隔离级别

        SQLAlchemy还提供了事务的隔离级别设置。默认情况下,事务的隔离级别为“可重复读”(REPEATABLE READ)。您可以通过设置会话的isolation_level参数来更改隔离级别。

from sqlalchemy import create_engine

# 创建引擎并设置事务隔离级别
engine = create_engine('sqlite:///example.db', isolation_level='READ COMMITTED')

        通过这些方法,您可以使用SQLAlchemy管理事务,确保数据库操作的一致性和完整性。无论您是手动控制事务还是使用自动提交,SQLAlchemy都提供了灵活的方式来满足您的需求。

八、性能优化

        在SQLAlchemy中,性能优化是一个重要的方面,它可以显著提高数据库操作的效率。以下是一些SQLAlchemy中的性能优化技巧:

1、延迟加载(Lazy Loading)

        延迟加载是一种优化技术,它允许您在需要时才从数据库中加载数据,而不是在对象被访问时立即加载。这可以减少不必要的数据库查询,提高性能。

        在SQLAlchemy中,默认情况下,关联对象是延迟加载的,这意味着当您访问关联对象时,才会从数据库中加载相关数据。例如:

# 延迟加载示例
employee = session.query(Employee).first()
print(employee.department.name)  # 在访问时加载部门对象

2、预加载(Eager Loading)

        预加载是指在执行查询时,一次性加载所有相关联的对象,而不是在需要时逐个加载。这样可以减少多次查询,提高性能。

        在SQLAlchemy中,您可以使用options()方法来指定预加载选项。例如,使用joinedload()来预加载关联对象:

from sqlalchemy.orm import joinedload

# 预加载示例
employee = session.query(Employee).options(joinedload(Employee.department)).first()
print(employee.department.name)  # 已经预加载了部门对象

3、缓存(Caching)

        缓存是指将数据库查询的结果保存在内存中,以便将来的查询可以直接从缓存中获取,而不必再次查询数据库。这可以显著提高查询性能,特别是对于频繁重复的查询。

在SQLAlchemy中,您可以使用query_cache参数来启用查询缓存:

from sqlalchemy.orm import Query

# 启用查询缓存
query = session.query(Employee).options(Query.cacheable(True))

4、批量操作(Bulk Operations)

        批量操作是指一次性执行多个数据库操作,而不是逐个执行单个操作。这可以减少数据库交互的次数,提高性能。

在SQLAlchemy中,您可以使用bulk_save_objects()方法一次性保存多个对象:

# 批量插入示例
employees = [Employee(name='John'), Employee(name='Alice')]
session.bulk_save_objects(employees)
session.commit()

5、SQL表达式(SQL Expressions)

        有时,您可能需要执行复杂的数据库操作,而ORM可能无法提供足够的性能。在这种情况下,您可以使用SQL表达式直接执行原生SQL查询。

from sqlalchemy.sql import text

# 原生SQL查询示例
result = session.execute(text("SELECT * FROM employees WHERE salary > :salary"), {"salary": 50000})
for row in result:
    print(row)

        以上是一些在SQLAlchemy中用于性能优化的常用技巧。根据您的具体需求和场景,选择适合的优化方法可以显著提高数据库操作的效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1796271.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

hid.dll丢失怎么办?hid.dll丢失多种解决方法详解

hid.dll,即Human Interface Device (HID) Dynamic Link Library,是Windows操作系统中用于管理人机交互设备(如键盘、鼠标、游戏控制器等)的动态链接库文件。它负责处理这些设备的输入和输出,确保设备与系统之间的通信顺…

SpringBoot+Vue在线考试答题系统【附:资料➕文档】

前言:我是源码分享交流Coding,专注JavaVue领域,专业提供程序设计开发、源码分享、 技术指导讲解、各类项目免费分享,定制和毕业设计服务! 免费获取方式--->>文章末尾处! 项目介绍016: 本…

windows10子系统wsl ubuntu22.04下GN/ninja环境搭建

打开windows10子系统 ubuntu22.04 ubuntu22.04: 首先需要 安装ninja $sudo apt install ninja-build $ ninja --version 1.10.0 安装clang $sudo apt install clang $clang --version Ubuntu clang version 14.0.0-1ubuntu1.1安装gn Github: https://github.com/timniederh…

如何在npm上发布自己的包

如何在npm上发布自己的包 npm创建自己的包 一、一个简单的创建 1、创建npm账号 官网:https://www.npmjs.com/创建账号入口:https://www.npmjs.com/signup 注意:需要进入邮箱验证 2、创建目录及初始化 $ mkdir ufrontend-test $ cd ufron…

LLM主流开源代表模型

LLM主流开源大模型介绍 1 LLM主流大模型类别 随着ChatGPT迅速火爆,引发了大模型的时代变革,国内外各大公司也快速跟进生成式AI市场,近百款大模型发布及应用。 目前,市面上已经开源了各种类型的大语言模型,本章节我们…

用idea将java文件打成jar包

一、用idea将java文件打成jar包 1、在idea上选择file—Project Structure 2、Artifacts —点–JAR—From modules with dependencies 3、选择要打包的java文件 4、Build — Build Artifacts 5、找到刚才添加的Artifacts直接Build 6、生成jar包文件

tomcat服务器之maxHttpHeaderSize

背景:在OA流程表单中,填写了200条数据,一提交,秒报400错误,且请求没有打到后端中(无报错日志),一开始以为是谷歌浏览器的问题,可百度上关于这个错误的解决方案都是清除缓…

Renesas MCU之FreeRTOS的应用

目录 概述 1 FSP配置FreeRTOS 1.1 软件版本信息 1.2 配置FreeRTOS 2 FreeRTOS的Task 2.1 FSP下的项目结构 2.2 Task代码 2.2.1 Task测试案例配置 2.2.2 测试代码实现 3 自定义Task 3.1 编写代码 3.2 测试函数 4 测试 4.1 Task断点测试 4.2 板卡运行测试 概述 …

Spring boot 集成mybatis-plus

Spring boot 集成mybatis-plus 背景 Spring boot集成mybatis后,我们可以使用mybatis来操作数据。然后,我们还是需要写许多重复的代码和sql语句,比如增删改查。这时候,我们就可以使用 mybatis-plus了,它可以极大解放我…

CC++内存管理【new和delete操作符的详细分析】【常见面试题】

C/C内存管理 1.C/C内存分布 我们先来看一段代码&#xff0c;来了解一下C/C中的数据内存分布。 # include <stdlib.h>int globalVar 1; static int staticGlobalVar 1; // 比globalVar还要先销毁,同一个文件下后定义的先析构 // 全局变量存在 数据段&#xff08;静态…

opencv进阶 ——(十三)基于三角剖分实现换脸

换脸的关键在于人脸对齐&#xff0c;人脸对齐主要包括以下几点&#xff1a; 1、人脸可能存在一定的角度&#xff0c;因此需要先将倾斜方向进行对齐 2、大小对齐&#xff0c;将模板人脸的大小缩放到同一大小 3、要想有好的效果&#xff0c;关键点选取很重要 4、人脸对齐后&a…

前端自测 - 那些经典的bug

前言 我一直坚持的一个观点&#xff0c;就是不以bug数论成败&#xff0c;但是这个需要加一个前提&#xff0c;就是不能出现那些低级的bug&#xff0c;更不能反复的出现。 由此整理了一系列我认为比较经典常见的前端bug&#xff0c;都是在项目中多次遇到过的&#xff0c;用于前…

14. WinCC 无法打开画面编辑器Graphis Designer,且提示X值坐标过大,Y值坐标过大

wincc双击画面一直显示在这个界面&#xff0c;并且这个窗口背后还有小窗口。 直接回到桌面主界面下&#xff0c;点一下这个窗口&#xff0c;窗口消失&#xff0c;点击任务栏的wincc图标会弹窗&#xff0c;显示X坐标值过大&#xff0c;Y坐标值过大。将这些窗口都点击确定之后就…

多线程..

线程定义&#xff1a;线程是操作系统能够进行运算调度的最小单位&#xff0c;它被包含在进程之中&#xff0c;是进程中实际运作单位。简单来说&#xff0c;应用软件中相互独立&#xff0c;可以同时运作的功能。 多线程作用&#xff1a;有了多线程&#xff0c;我们就可以让程序…

扩散模型会成为深度学习的下一个前沿领域吗?

文章目录 一、说明二、 第 1 部分&#xff1a;了解扩散模型2.1 什么是扩散模型2.2 正向扩散2.3 反向扩散 三、他们的高成本四、扩散模型的用处五、为什么扩散模型如此出色六、第 2 部分&#xff1a;使用扩散模型生成6.1 用于自然语言处理和 LLM 的文本扩散6.2 音频视频生成6.3 …

Hadoop3:MapReduce源码解读之Map阶段的CombineFileInputFormat切片机制(4)

Job那块的断点代码截图省略&#xff0c;直接进入切片逻辑 参考&#xff1a;Hadoop3&#xff1a;MapReduce源码解读之Map阶段的Job任务提交流程&#xff08;1&#xff09; 6、CombineFileInputFormat原理解析 类的继承关系 与TextInputFormat切片机制的区别 框架默认的TextI…

docker构建jdk17镜像

资料参考 参考自黑马教程&#xff1a;10.Docker基础-自定义镜像_哔哩哔哩_bilibili 更多详细语法声明&#xff0c;请参考官网文档&#xff1a;https://docs.docker.com/engine/reference/builder 初步准备 1、下载jdk17包&#xff08;linux版&#xff09;&#xff0c;我这边版…

问题:在本案复议阶段,复议机关()。 #其他#媒体

问题&#xff1a;在本案复议阶段&#xff0c;复议机关&#xff08;&#xff09;。 A&#xff0e;有权责令被申请人纠正违法的征税行为 B&#xff0e;应当对被申请人作出的税务具体行政行为所依据的事实证据、法律程序、法律依据及设定权利义务内容的合法性、适当性进行全面审…

暑期来临,AI智能视频分析方案筑牢防溺水安全屏障

随着夏季暑期的来临&#xff0c;未成年人溺水事故频发。传统的防溺水方式往往依赖于人工巡逻和警示标识的设置&#xff0c;但这种方式存在人力不足、反应速度慢等局限性。近年来&#xff0c;随着视频监控智能分析技术的不断发展&#xff0c;其在夏季防溺水中的应用也日益凸显出…

【十二】图解mybatis日志模块之设计模式

图解mybatis日志模块之设计模式 概述 最近经常在思考研发工程师初、中、高级工程师以及系统架构师各个级别的工程师有什么区别&#xff0c;随着年龄增加我们的技术级别也在提升&#xff0c;但是很多人到了高级别反而更加忧虑&#xff0c;因为it行业35岁年龄是个坎这是行业里的共…