创建一个简单的flask项目步骤

news/2024/12/5 9:23:48/

创建一个flask项目目录(结构配置,SQLAlchemy,邮件,消息闪现等)

展示一下当前的目录结果

在这里插入图片描述

|-feng7309						# 项目文件夹
|--|apps						# 统一管理所有的蓝图信息
|--|--|users					# users 蓝图
|--|--|--|__init__.py			# 蓝图声明和初始化
|--|--|--|login.py				# 蓝图视图文件 执行业务逻辑
|--|--|--|for_db.py				# 测试一些数据库的使用情况
|--|--|--|send_mail.py			# 测试发送邮件
|--|utils						# 工具文件夹,保存一些工具文件
|--|--|read_config.py			# 读取配置文件的共计代码
|--|static						# 保存静态文件
|--|--|css.py					# 保存样式文件上
|--|--|js.py					# 保存js文件
|--|--|images.py				# 保存图片文件
|--|templates					# 保存依稀静态的模板文件 html
|--|base_object.py				# 用于创建一些扩展的对象,防止循环导入的现象
|--|config.ini					# 外部信息配置文件
|--|create_app.py				# 用于对flask项目进行数据初始化等信息配置,创建flask对象
|--|models.py					# 所有的数据库模型代码
|--|req.txt						# 需要的第三方包的名字和版本
|--|run.py						# 程序入口文件
|--|setting.py					# 做一些区分性的配置,分类拆分# 以下文件不用管
# enve			我自己的虚拟环境
# migration 	迁移数据库生成的文件

1 创建空文件

# 创建一个空文件,将空文件突拖入pycharm中
# 创建   feng7309

2 创建环境创建目录结构

# 1 创建apps 文件夹,管理蓝图# 2 创建utils 保存工具文件# 3 创建虚拟环境 并将学你环境存放在项目目录下面   我用的是 python3.8并在虚拟环境终端安装flaskpip install flask
# 4 安装指定文件的包pip install -r req.txt

3 项目的编写

1 创建 入口文件 run.py
2 创建 create_app.py
3 创建 settings.py
4 在utils下创建 read_config.py 文件
5 创建 config.ini 文件
6 创建 base_object.py 统一创建第三方扩展对象

3.1 create_app.py

from flask import Flask
# 创建数据库对象
def create_app():flask_app = Flask(__name__)# 加载配置# 注册蓝图# 配置第三方扩展# 返回 flask对象return flask_app

3.2 run.py

from create_app import create_app
# 导入模型类
from models import Users
# 通过 create_app 创建flask对象
app = create_app()@app.route('/')
def index():return "Hello World!"
if __name__ == '__main__':app.run()

这样就可以运行了 ,127.0.0.1:5000 启动

3.3 配置信息,加载配置信息

config.ini

[DB]
HOST = 127.0.0.1
PORT = 3306
USERNAME = root
PASSWORD = root
NAME = flask_db
[SERVER]
DEBUG = True
HOST = 127.0.0.1
PORT = 5000

read_config.py

import configparserclass ReadConfig:"""创建一个读取配置文件的类"""def __init__(self):"""初始化连接配置对象,和配置文件位置"""self.config_path = r'C:\Users\FengHan7309\Desktop\base\feng7309\config.ini'self.read_config()def read_config(self):"""读取配置文件,返回读取配置对象:return: 读取文件配置文件对象"""self.config = configparser.ConfigParser()self.config.read(self.config_path)def config_value(self, section, key):"""通过获取secton和key获取指定的值:param section: section:param key: key:return: value"""value = self.config[section][key]return valuerc = ReadConfig()

settings.py

# -*- coding: utf-8 -*-
from utiles.read_config import rcclass BaseConfig:# 基础配置信息DEBUG = TrueSECRET_KEY = "qwertyuiopasdfghjklzxcvbnm"host = rc.config_value("DB", "HOST")port = int(rc.config_value("DB", "PORT"))username = rc.config_value("DB", "USERNAME")password = rc.config_value("DB", "PASSWORD")db_name = rc.config_value("DB", "NAME")SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{username}:{password}@{host}:{port}/{db_name}"SQLALCHEMY_TRACK_MODIFICATIONS = Falseclass DevelopmentConfig(BaseConfig):# 开发环境配置信息...class TestConfig(BaseConfig):# 测试环境配置信息...class ProductionConfig(BaseConfig):# 生产环境配置信息...

修改create_app.py 进行信息的的配置

# -*- coding: utf-8 -*-
"""
from flask import Flask
import settings
from flask_sqlalchemy import SQLAlchemydef create_app():flask_app = Flask(__name__)# 加载配置flask_app.config.from_object(settings.DevelopmentConfig)# 注册蓝图# 配置第三方扩展return flask_app

创建 base_object.py 创建扩展信息

from flask_mail import Mail
from flask_sqlalchemy import SQLAlchemy# 创建数据库对象
db = SQLAlchemy()
# 创建邮件对象
mails = Mail()

4 蓝图 users

创建一个python package,并在包下面创建一个login.py

4.1 _ _init _ _.py

from flask import Blueprintuser_dp = Blueprint('user', __name__)
# 引用蓝图的视图
from . import login

4.2 login.py

from apps.users import user_dp# 使用蓝图定义路由和视图,功能
@user_dp.route('/login', methods=['GET'])
def login():return "this is a login func"

4.3 修改create_app注册蓝图

from flask import Flaskimport settingsfrom apps.users import user_dp# 创建数据库对象def create_app():flask_app = Flask(__name__)# 加载配置flask_app.config.from_object(settings.DevelopmentConfig)# 注册蓝图flask_app.register_blueprint(user_dp, url_prefix="/user")# 配置第三方扩展return flask_app

重启项目,可以在127.0.0.1:5000/user/login 可以进行login信息的访问

5 SQLAlchemy的使用和配置

5.1 相关包的安装

使用mysql创建一个数据库名为 flask-db

pip install sqlalchemy
pip install lask_migrate
pip install flask_script
pip install pymysql

5.2 models.py

run文件夹同目录下创建models.py文件

from datetime import datetime
from email.policy import defaultfrom create_app import db# 创建用户表 命名为 f_users
class Users(db.Model):__tablename__ = 'f_users'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(20))password = db.Column(db.String(20))age = db.Column(db.Integer)sex = db.Column(db.Integer)create_time = db.Column(db.DateTime, default=datetime.now)updated_time = db.Column(db.DateTime, default=datetime.now)

创建其他数据表的映射信息–用于测试

class User(db.Model):__tablename__ = 'users'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(20))password = db.Column(db.String(20))# 一方指定关联的表 f 反向关联到user表articles = db.relationship('Article', backref='users')# 指定与Userinfo的关系 uselist 指定一对一的关系userinfo = relationship('UserInfo', backref='users', uselist=False)# 一个用户对应多个文章
class Article(db.Model):__tablename__ = 'articles'id = db.Column(db.Integer, primary_key=True, autoincrement=True)title = db.Column(db.String(20))content = db.Column(db.Text)# 指定外键是roles中的iduser_id = db.Column(db.Integer, ForeignKey('users.id'))# 一个用户对应一条信息
class UserInfo(db.Model):__tablename__ = 'userinfos'id = db.Column(db.Integer, primary_key=True, autoincrement=True)name = db.Column(db.String(20))age = db.Column(db.Integer)sex = db.Column(db.String(10))user_id = db.Column(db.Integer, ForeignKey('users.id'))# 定义多对对的关系      需要一个中间的对应关系
# 一篇文章有多个标签,同时一个标签也可以书与多个文章class Tag(db.Model):__tablename__ = 'tags'id = db.Column(db.Integer, primary_key=True, autoincrement=True)name = db.Column(db.String(20))# 定义对应关系
article_tag = db.Table('article_tag',db.Column('article_id', db.Integer, ForeignKey('articles.id')),db.Column('tag_id', db.Integer, ForeignKey('tags.id'))
)

5.3 修改create_app.py 进行第三方扩展

from flask import Flask
import settings
from flask_sqlalchemy import SQLAlchemy
from apps.users import user_dp# 导入创建的第三方扩展
from base_object import dbdef create_app():flask_app = Flask(__name__)# 加载配置flask_app.config.from_object(settings.DevelopmentConfig)# 注册蓝图flask_app.register_blueprint(user_dp, url_prefix="/user")# 配置第三方扩展db.init_app(app=flask_app)return flask_app

5.4 修改入口文件 run.py

from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from create_app import create_app, db
# 导入模型类
from models import Usersapp = create_app()# 初始化数据库执行
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)@app.route('/')
def index():return "Hello World!"if __name__ == '__main__':manager.run()

然后运行会出问题

5.5 出现问题解决

MigrateCommand 问题

降低一下migrate的版本
pip install flask_migrate==2.7.0

flask._cmpat 报错

 点进去报错,修改 15行为
from flask_script._compat import text_type

manager启动出问题

usage: manage.py [-?] {db,shell,runserver} ...positional arguments:{db,shell,runserver}db                  Perform database migrationsshell               Runs a Python shell inside Flask application context.runserver           Runs the Flask development server i.e. app.run()optional arguments:-?, --help            show this help message and exit

配置一下启动参数为 runserver 就可启动了
在这里插入图片描述

5.6 数据库迁移和初始化

数据初始化

执行命令
python run.py db init 	# 只需要执行一次
# 执行完成好会生成一个migration的文件夹不要改动,不用管它

数据表的迁移

python run.py db migrate
数据表的迁移

数据表执行

python run.py db upgrade

之后在数据库中就能够见到一个名为 f_user的表了

5.7 测试数据的CRUD 和SQLALchemy相关使用

SQLAlchemy的相关使用(不完全版本)

# 导入多条件查询的 or和and关键字
from sqlalchemy import or_, and_from apps.users import user_dp
from base_object import db
from models import User, UserInfo
# 重新封装一下 db.session
dbs = db.session# 通过访问接口测试数据库的使用
@user_dp.route('/add_data_users')
def add_data_users():"""添加1一条数据或多条数据:return:"""user = User(username="feng", password="123456")db.session.add(user)user = User(username="zhang", password="123456")db.session.add(user)db.session.commit()return 'add_data successfully'@user_dp.route('/add_data_users_all')
def add_data_users_all():"""一次添加多条数数据:return:"""user1 = User(username="liu", password="123456")user2 = User(username="zhao", password="123456")db.session.add_all([user1, user2])db.session.commit()return 'add_data successfully'@user_dp.route('/add_data_userinfo')
def add_data_userinfo():"""添加一个用户的信息:return:"""userinfo = UserInfo(name="张杰", age=20, sex='女', user_id=2)db.session.add(userinfo)db.session.commit()return 'add_data_userinfo successfully'@user_dp.route('/update_user_data')
def update_user_data():"""更新指定的数据:return:"""# step 1# user = User.query.get(2)# user.username = 'zhangjie'# user.password = '1111111'# db.session.commit()# db.session.close()# step 2db.session.query(User).filter(User.id == 1).update({'username': 'fenghan'})db.session.commit()db.session.close()return '更新数据成功'@user_dp.route('/delete_user_data')
def delete_user_data():"""删除数据:return:"""user = db.session.query(User).filter(User.id == 4).first()db.session.delete(user)db.session.commit()db.session.close()return '删除数据成功'@user_dp.route('/query_data')
def query_data():"""查询数据:return:"""# 1 查询完整及路all_user = db.session.query(User).all()# 2 查询具体的某条字段query_keyword = db.session.query(User.username).all()return 'query_data'@user_dp.route('/query_select_data')
def query_select_data():"""查询并筛选字段:return:"""# 1 filter方法res1 = dbs.query(User).filter(User.id == 1).all()# 2 filter_by方法筛选数据res2 = dbs.query(User).filter_by(id=2).all()return 'query_data'@user_dp.route('/query_many_option_data')
def query_many_option_data():"""查询并筛选字段:return:"""# 1 and_ 关系查询res1 = dbs.query(User).filter(User.username == 'fenghan', User.password == '123456').all()res_and = dbs.query(User).filter(and_(User.username == 'fenghan', User.password == '123456')).all()# 2 or_ 关系查询res2 = dbs.query(User).filter(or_(User.id == 1, User.username == 'liu')).all()return 'query_data'@user_dp.route('/query_link_data')
def query_link_data():"""查询字段信息 内连接,外连接:return:"""# 1 内连接   表1,表2都有数据res1 = dbs.query(User).join(UserInfo, User.id == UserInfo.user_id).all()# 2 外连接 表1有数据,表2不一定有数据res2 = dbs.query(User).outerjoin(UserInfo, User.id == UserInfo.user_id).all()return 'query_data'@user_dp.route('/do_sql')
def do_sql():"""直接执行sql语句:return:"""sql = 'select * from users'res = dbs.execute(sql)print(list(res))return 'query_data'@user_dp.route('/query_order_by')
def query_order_by():"""排序:return:"""# 降序res1 = dbs.query(User).order_by(User.id.desc()).all()res2 = dbs.query(User).order_by(-User.id).all()# 升序res3 = dbs.query(User).order_by(User.id).all()return 'query_data'
@user_dp.route('/query_limit_offset_by')
def query_limit_offset_by():"""排序:return:"""# limit 限制查询数据的条数# offset 过滤掉前多少条res1 =dbs.query(User).offset(1).limit(1).all()# 过滤一条,查询一条# 可以使用切片查找res2 = dbs.query(User).order_by(-User.id)[0:2]return 'query_data'

6 发送电子邮件信息

6.1 配置发送邮件的相关信息

这里不能通过from_object进行配置,为甚吗?-- 现在还不知道,采取以下方式进行配置

修改 create_app.py 文件,对有劲啊信息进行配置

from flask import Flask
import settingsfrom apps.users import user_dp
# 导入统一管理的 第三方扩展注册
from base_object import db, mailsdef create_app():# 配置静态文件 路径flask_app = Flask(__name__, template_folder='templates', static_folder='static', static_url_path='/static')# 加载配置flask_app.config.from_object(settings.DevelopmentConfig)# 对邮件的信息进行配置flask_app.config['MAIL_SERVER'] = 'smtp.qq.com'flask_app.config['MAIL_PORT'] = 465flask_app.config['MAIL_USERNAME'] = '2418028749@qq.com'flask_app.config['MAIL_PASSWORD'] = '你的密钥信息'flask_app.config['MAIL_USE_TLS'] = Falseflask_app.config['MAIL_USE_SSL'] = True# 注册蓝图  给访问加上前缀flask_app.register_blueprint(user_dp, url_prefix="/user")# 配置第三方扩展# 配置数据库db.init_app(app=flask_app)# 配置邮箱服务mails.init_app(app=flask_app)return flask_app

6.2 创建 send_mail.py 进行发送邮件操作

还是以接口的形式进行数据的测试

from flask_mail import Messagefrom apps.users import user_dp
from base_object import mails@user_dp.route('/send/')
def send_mail():# 创建一个信息对象msg = Message(# 标题subject="测试flask_mail发送邮件",# 发送人的邮箱地址sender='2418028749@qq.com',# 发送对象 可以有多个用户同时发送,列表形式传入recipients=['2418028749@qq.com'])# 邮件内容和主体msg.body = "this is a test message"msg.html = "<h1>This is a test message</h1>"# 携带附件# with open('../../static/images/001.jpeg') as f:#     msg.attach('image.jpeg', 'image/jpeg', f.read())# 通过mails对象发送短信信息mails.send(msg)return "Send test message Success"

7 模板文件和消息闪现

7.1 模板文件

后端响应html模板文件 修改run.py

from flask import render_template, flash
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from create_app import create_app, db
# 导入模型类
from models import *
app = create_app()
# 初始化数据库执行
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
# 路由输入一个数字进行响应模板 html 文件
@app.route('/<int:num>')
def index(num):if num > 0:# 消息闪现flash('You were successfully logged in','error')return render_template('index.html')# 渲染文件return render_template('index.html')if __name__ == '__main__':manager.run()

修改create_app.py文件,指定静态文件路径和模板文件夹

from flask import Flask
import settings
from apps.users import user_dp
from base_object import db, mails
def create_app():# 配置静态文件 路径flask_app = Flask(__name__, template_folder='templates', static_folder='static', static_url_path='/static')# template_folder='templates'  	指定模板文件为templates# static_folder='static'		指定静态文件 static# static_url_path='/static'		指定静态文件路径 /static# 加载配置flask_app.config.from_object(settings.DevelopmentConfig)# 配置邮件数据对象flask_app.config['MAIL_SERVER'] = 'smtp.qq.com'flask_app.config['MAIL_PORT'] = 465flask_app.config['MAIL_USERNAME'] = '2418028749@qq.com'flask_app.config['MAIL_PASSWORD'] = 'znswdskbwnvyecdc'flask_app.config['MAIL_USE_TLS'] = Falseflask_app.config['MAIL_USE_SSL'] = True# 注册蓝图flask_app.register_blueprint(user_dp, url_prefix="/user")# 配置第三方扩展# 配置数据库db.init_app(app=flask_app)# 配置邮箱服务mails.init_app(app=flask_app)return flask_app

主模板文件 base.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><!-- 加载格式 {{ url_for('static',filename='文件路径') }}--><!--引入css文件--><link rel="stylesheet" href="{{ url_for('static',filename='/css/1.css') }}"><!--引入js文件--><script src="{{ url_for('static',filename='/js/1.js') }}"></script>
</head>
<body>
<h1>This is base page</h1>
<h1>主页返回的页面</h1>
<!--创建继承的模板块-->
{% block header %}
{% endblock %}
{#  获取稍息闪现的数据内容 #}
</body>
</html>

通过index.html 继承 base.html 文件

<!--指定继承的模板文件-->
{% extends 'base.html' %}
{# 模板继承 #}
{% block header %}
<h1>你是啊哈来看看就这个卡号就出现过咋看火箭股份</h1>
{% endblock %}

7.2 消息闪现

设置flash的消息闪现

修改run.py 文件

# 接口进行测试消息闪现
@app.route('/<int:num>')
def index(num):if num > 0:# 消息闪现  设置消息闪现内容#  flash('闪现内容','消息级别')flash('You were successfully logged in','error')flash('1111111111111111 11111111111 11111111111')flash('222222222222 2222222222222222222222222222222')flash('You were successfully logged in','error')return render_template('index.html')# 渲染文件return render_template('index.html')

模板文件处理消息闪现的格式和方法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><!--引入css文件--><link rel="stylesheet" href="{{ url_for('static',filename='/css/1.css') }}"><!--引入js文件--><script src="{{ url_for('static',filename='/js/1.js') }}"></script>
</head>
<body>
<h1>This is base page</h1>
<h1>主页返回的页面</h1>
{% block header %}
{% endblock %}
{#  获取稍息闪现的数据内容 #}
{% with messages = get_flashed_messages(with_categories=true) %}{# 如果有闪现的消息 执行下面语句 #}{% if messages %}<ul class=flashes>{#遍历所有的数据集,输出这个消息的内容#}{% for category,message in messages %}<li class="{{ category }}">{{ message }}</li>{% endfor %}</ul>{% endif %}
{% endwith %}
{#获取相对应错误信息#}
{#通过指定消息的类型,闪现指定的消息#}
{% with errors = get_flashed_messages(category_filter=["error"]) %}{% if errors %}<div class="alert-message block-message error"><a class="close" href="#">×</a><ul>{#只输出指定类型的消息#}{%- for msg in errors %}<li>{{ msg }}</li>{% endfor -%}</ul></div>{% endif %}
{% endwith %}
</body>
</html>

8 Flask-WTF扩展的使用

8.1 后端字段类型定义

在 run.py 下面定义一个类为RegisterFom的类

# 使用Flask—WTF编写表单信息
class RegisterForm(FlaskForm):"""自定义一个关于注册的方法"""username = StringField(label="用户名", validators=[DataRequired(message="用户名不能能为空!!")])password = PasswordField(label="密码", validators=[DataRequired("密码不能能为空!!"),Length(min=6, max=10, message="用户名长度在6-12位之间")])password2 = PasswordField(label="确认密码",validators=[DataRequired("密码不能能为空!!"), EqualTo("password", "两次密码不一致!")])age = IntegerField(label="年龄", validators=[DataRequired(message="年龄不能为空")])high = FloatField(label="身高单位厘米 可以为小数点", validators=[DataRequired(message="含恶搞不能为空")])submit = SubmitField(label="提交")# 自定义的函数来对指定 字段进行验证方法 # 格式 validate_要验证的字段名称def validate_username(self, field):# 验证逻辑if len(field.data) < 6:# 错误抛出的异常raise ValidationError("数据长度不能小于6位")def validate_age(self, field):if field.data < 0 or field.data > 120:raise ValidationError("请检查该字段是否有误!")

指定路由对该方法进行验证

@app.route('/test_wtf', methods=['GET', 'POST'])
def test_wtf():# 创建一个注册form表单对象form = RegisterForm()# 区分是那种请求方式if request.method == 'POST':# 验证表单的提交数据if form.validate_on_submit():# 获取表单中指定字段的数据内容username = form.username.datapassword = form.password.datapassword2 = form.password2.dataprint(username, password, password2)return "获取到了 WTF 表单中的信息"# get方法,渲染表单 将表单对象传回前端return render_template('test_wtf.html', form=form)

8.2 端模板定义

前端根据jinja2模板对表单格式进行渲染 test_wtf.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>这里是一个验证 WTF 的HTML页面</h1>
{#定义一个form表单#}
<form action="" method="post">{#开启一个跨域表单验证#}{{ form.csrf_token }}{# 用户名 #}{# 根据表单对象指定lable标签 #}{{ form.username.label }}{# 根据表单对象指定username标签的输入内容 #}<p>{{ form.username }}</p>{# 根据表单对象指定校验的时候,不的错误提示 #}{% for msg in form.username.errors %}<p>{{ msg }}</p>{% endfor %}{# 密码 #}{{ form.password.label }}<p>{{ form.password }}</p>{% for msg in form.password.errors %}<p>{{ msg }}</p>{% endfor %}{# 确认密码 #}{{ form.password2.label }}<p>{{ form.password2 }}</p>{% for msg in form.password2.errors %}<p>{{ msg }}</p>{% endfor %}{# 年龄 #}{{ form.age.label }}<p>{{ form.age }}</p>{% for msg in form.age.errors %}<p>{{ msg }}</p>{% endfor %}{# 身高 #}{{ form.high.label }}<p>{{ form.high }}</p>{% for msg in form.high.errors %}<p>{{ msg }}</p>{% endfor %}{{ form.submit }}
</form>
</body>
</html>

9 flask-Bootstrap 扩展的使用

默认的使用前端的bootstrap框架的内容,格式等文件,默认需要继承与 bootstrap表

安装扩展包:pip install flask-bootstrap

修改base_object.py中创建

# 创建引入bootstrap对象
bs = Bootstrap()

在 create_app.py 中进行注册

# 配置bootstrapd数据
bs.init_app(app=flask_app)

后端路由访问

@app.route('/test_bootstrap', methods=['GET'])
def test_bootstrap():return render_template('test_bootstrap.html')

前端的继承和使用

{% extends "bootstrap/base.html" %}{% block title %}Flasky{% endblock %}{% block navbar %}
<div class="navbar navbar-inverse" role="navigation"><div class="container"><div class="navbar-header"><button type="button" class="navbar-toggle"data-toggle="collapse" data-target=".navbar-collapse"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="/">Flasky</a></div><div class="navbar-collapse collapse"><ul class="nav navbar-nav"><li><a href="/">Home</a></li></ul></div></div>
</div>
{% endblock %}{% block content %}
<div class="container"><div class="page-header"><h1>Hello, {{ name }}!</h1></div>
</div>
{% endblock %}

展示效果

在这里插入图片描述

待继续更新下…


http://www.ppmy.cn/news/637245.html

相关文章

lxd-JDBC

第一章 JDBC概述 1.1 数据持久化 持久化&#xff1a;把数据保存到可掉电式存储设备中以供之后使用。大多数情况下&#xff0c;特别是企业级应用&#xff0c;数据持久化意味着将内存中的数据保存到硬盘加以“固化”&#xff0c;而持久化的实现过程大多通过各种关系行数据库来完…

广东省2018届高校毕业生系列供需见面活动#4月21日#、#5月12日#、#6月9日#

广东省2018届高校毕业生系列供需见面活动 举办单位 主办单位&#xff1a;广东省教育厅 承办单位&#xff1a;广东省高等学校毕业生就业促进会 时间内容 时间&#xff08;2018年度&#xff09; 地点 主题 3月11日 广东工业大学&#xff08;大学城校区&#xff09; 综合…

通讯录

实现一个&#xff1b; 通讯录可以用来存储1000个人的信息&#xff0c;每个人的信息包括&#xff1a; 姓名、性别、年龄、电话、住址 提供方法&#xff1a; 1. 添加联系人信息 2. 删除指定联系人信息 3. 查找指定联系人信息 4. 修改指定联系人信息 5. 显示所有联系人信…

云中的angel:汪涵推介手机QQ浏览器

书接上文&#xff0c;谢娜与张杰的婚礼&#xff0c;杨乐乐参与&#xff0c;汪涵缺席。为神马&#xff1f;答案在9月26日下午揭晓&#xff0c;这位芒果台一哥&#xff0c;一袭黑色西装赫然出现在希尔顿天元宫&#xff0c;主持“腾讯手机QQ浏览器品牌升级战略暨新解决方案发布会”…

Html实现QQ音乐首页(响应式)

项目访问 reset.css /*** Eric Meyers Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)* http://cssreset.com*/html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, de…

Seata-DTX|分布式事务金融场景案例介绍

文&#xff5c;魏陈豪&#xff08;花名&#xff1a;无陈 Sam) 蚂蚁集团 SOFAStack 产品专家 本文 2966 字 阅读 8 分钟 序言 今天给大家带来一篇 Seata-DTX[1] 商业版分布式事务在金融行业如何保证事务一致性的实践介绍。从一个全局视角出发看看一致性的保证、分别有哪些节点&a…

全志科技T3国产工业评估板规格书(四核ARM Cortex-A7,主频1.2GHz)

1 评估板简介 创龙科技TLT3-EVM是一款基于全志科技T3处理器设计的4核ARM Cortex-A7高性能低功耗国产评估板&#xff0c;每核主频高达1.2GHz&#xff0c;由核心板和评估底板组成。 评估板接口资源丰富&#xff0c;引出双路网口、双路CAN、双路USB、双路RS485等通信接口&#x…

拆机达人

这是土盐的第147篇原创文章 1 大家好&#xff0c;我是土盐。 昨天分享了光电工程师同事多么心灵手巧。 拆了重装&#xff0c;还没坏&#xff0c;这个感觉比较牛。 2 今天这老哥又开始拆了&#xff0c;我顺带学习了不少知识。 这次把另一台老设备的光学模块拆了。 这老哥说了一句…