[{"content":"","date":"2025-06-24","externalUrl":null,"permalink":"/tags/git/","section":"标签","summary":"","title":"Git","type":"tags"},{"content":" 子模块 # 添加子模块\ngit submodule add child_module_url 主仓库和子模块仓库同时拉取\ngit clone --recurse-submodules repo-url 若主仓库已经拉取，单独拉取子模块\ngit submodule update --recursive ","date":"2025-06-24","externalUrl":null,"permalink":"/docs/git/","section":"文章","summary":"子模块 # 添加子模块\n","title":"Git命令","type":"docs"},{"content":"","date":"2025-06-24","externalUrl":null,"permalink":"/tags/%E5%91%BD%E4%BB%A4/","section":"标签","summary":"","title":"命令","type":"tags"},{"content":"","date":"2025-06-24","externalUrl":null,"permalink":"/categories/%E5%AD%A6%E4%B9%A0/","section":"类别","summary":"","title":"学习","type":"categories"},{"content":"","date":"2025-06-24","externalUrl":null,"permalink":"/docs/","section":"文章","summary":"","title":"文章","type":"docs"},{"content":"","date":"2025-05-17","externalUrl":null,"permalink":"/tags/log4j2/","section":"标签","summary":"","title":"Log4j2","type":"tags"},{"content":"log4j2 pattern format website\nconfig xml file # \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;Configuration status=\u0026#34;WARN\u0026#34; monitorInterval=\u0026#34;15\u0026#34;\u0026gt; \u0026lt;properties\u0026gt; \u0026lt;property name=\u0026#34;LOG_HOME\u0026#34;\u0026gt;logs\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;PATTERN_FORMAT\u0026#34;\u0026gt;%d{HH:mm:ss.SSS} [%t] [%-5level] %c.%M(%L) - %msg%n\u0026lt;/property\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;Appenders\u0026gt; \u0026lt;Console name=\u0026#34;Console\u0026#34; target=\u0026#34;SYSTEM_OUT\u0026#34;\u0026gt; \u0026lt;PatternLayout pattern=\u0026#34;${PATTERN_FORMAT}\u0026#34; /\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;DEBUG\u0026#34; onMatch=\u0026#34;ACCEPT\u0026#34; onMismatch=\u0026#34;NEUTRAL\u0026#34; /\u0026gt; \u0026lt;/Console\u0026gt; \u0026lt;RollingRandomAccessFile name=\u0026#34;DebugFile\u0026#34; fileName=\u0026#34;${LOG_HOME}/debug.log\u0026#34; filePattern=\u0026#34;${LOG_HOME}/$${date:yyyy-MM-dd}/debug-%d{yyyy-MM-dd}-%i.log.zip\u0026#34;\u0026gt; \u0026lt;Filters\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;INFO\u0026#34; onMatch=\u0026#34;DENY\u0026#34; onMismatch=\u0026#34;NEUTRAL\u0026#34; /\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;DEBUG\u0026#34; onMatch=\u0026#34;ACCEPT\u0026#34; onMismatch=\u0026#34;DENY\u0026#34; /\u0026gt; \u0026lt;/Filters\u0026gt; \u0026lt;PatternLayout pattern=\u0026#34;${PATTERN_FORMAT}\u0026#34; /\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;TimeBasedTriggeringPolicy /\u0026gt; \u0026lt;SizeBasedTriggeringPolicy size=\u0026#34;15 MB\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;DefaultRolloverStrategy max=\u0026#34;20\u0026#34; \u0026gt; \u0026lt;Delete basePath=\u0026#34;${LOG_HOME}/\u0026#34; maxDepth=\u0026#34;5\u0026#34;\u0026gt; \u0026lt;IfFileName glob=\u0026#34;*debug*.log.zip\u0026#34;/\u0026gt; \u0026lt;/Delete\u0026gt; \u0026lt;/DefaultRolloverStrategy\u0026gt; \u0026lt;/RollingRandomAccessFile\u0026gt; \u0026lt;RollingRandomAccessFile name=\u0026#34;InfoFile\u0026#34; fileName=\u0026#34;${LOG_HOME}/info.log\u0026#34; filePattern=\u0026#34;${LOG_HOME}/$${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log.zip\u0026#34;\u0026gt; \u0026lt;Filters\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;WARN\u0026#34; onMatch=\u0026#34;DENY\u0026#34; onMismatch=\u0026#34;NEUTRAL\u0026#34; /\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;INFO\u0026#34; onMatch=\u0026#34;ACCEPT\u0026#34; onMismatch=\u0026#34;DENY\u0026#34; /\u0026gt; \u0026lt;/Filters\u0026gt; \u0026lt;PatternLayout pattern=\u0026#34;${PATTERN_FORMAT}\u0026#34; /\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;TimeBasedTriggeringPolicy /\u0026gt; \u0026lt;SizeBasedTriggeringPolicy size=\u0026#34;15 MB\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;DefaultRolloverStrategy max=\u0026#34;20\u0026#34; \u0026gt; \u0026lt;Delete basePath=\u0026#34;${LOG_HOME}/\u0026#34; maxDepth=\u0026#34;5\u0026#34;\u0026gt; \u0026lt;IfFileName glob=\u0026#34;*info*.log.zip\u0026#34;/\u0026gt; \u0026lt;/Delete\u0026gt; \u0026lt;/DefaultRolloverStrategy\u0026gt; \u0026lt;/RollingRandomAccessFile\u0026gt; \u0026lt;RollingRandomAccessFile name=\u0026#34;ErrorFile\u0026#34; fileName=\u0026#34;${LOG_HOME}/error.log\u0026#34; filePattern=\u0026#34;${LOG_HOME}/$${date:yyyy-MM-dd}/error-%d{yyyy-MM-dd}-%i.log.zip\u0026#34;\u0026gt; \u0026lt;Filters\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;FATAL\u0026#34; onMatch=\u0026#34;DENY\u0026#34; onMismatch=\u0026#34;NEUTRAL\u0026#34; /\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;WARN\u0026#34; onMatch=\u0026#34;ACCEPT\u0026#34; onMismatch=\u0026#34;DENY\u0026#34; /\u0026gt; \u0026lt;/Filters\u0026gt; \u0026lt;PatternLayout pattern=\u0026#34;${PATTERN_FORMAT}\u0026#34; /\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;TimeBasedTriggeringPolicy /\u0026gt; \u0026lt;SizeBasedTriggeringPolicy size=\u0026#34;10 MB\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;DefaultRolloverStrategy max=\u0026#34;15\u0026#34; \u0026gt; \u0026lt;Delete basePath=\u0026#34;${LOG_HOME}/\u0026#34; maxDepth=\u0026#34;5\u0026#34;\u0026gt; \u0026lt;IfFileName glob=\u0026#34;*error*.log.zip\u0026#34;/\u0026gt; \u0026lt;/Delete\u0026gt; \u0026lt;/DefaultRolloverStrategy\u0026gt; \u0026lt;/RollingRandomAccessFile\u0026gt; \u0026lt;RollingRandomAccessFile name=\u0026#34;FatalFile\u0026#34; fileName=\u0026#34;${LOG_HOME}/fatal.log\u0026#34; filePattern=\u0026#34;${LOG_HOME}/$${date:yyyy-MM}/fatal-%d{yyyy-MM-dd}-%i.log.zip\u0026#34;\u0026gt; \u0026lt;Filters\u0026gt; \u0026lt;ThresholdFilter level=\u0026#34;FATAL\u0026#34; onMatch=\u0026#34;ACCEPT\u0026#34; onMismatch=\u0026#34;DENY\u0026#34; /\u0026gt; \u0026lt;/Filters\u0026gt; \u0026lt;PatternLayout pattern=\u0026#34;${PATTERN_FORMAT}\u0026#34; /\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;TimeBasedTriggeringPolicy /\u0026gt; \u0026lt;SizeBasedTriggeringPolicy size=\u0026#34;5 MB\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;DefaultRolloverStrategy max=\u0026#34;5\u0026#34; \u0026gt; \u0026lt;Delete basePath=\u0026#34;${LOG_HOME}/\u0026#34; maxDepth=\u0026#34;5\u0026#34;\u0026gt; \u0026lt;IfFileName glob=\u0026#34;*fatal*.log.zip\u0026#34;/\u0026gt; \u0026lt;/Delete\u0026gt; \u0026lt;/DefaultRolloverStrategy\u0026gt; \u0026lt;/RollingRandomAccessFile\u0026gt; \u0026lt;/Appenders\u0026gt; \u0026lt;Loggers\u0026gt; \u0026lt;Logger name=\u0026#34;org.apache\u0026#34; level=\u0026#34;ERROR\u0026#34;/\u0026gt; \u0026lt;Logger name=\u0026#34;org.mybatis\u0026#34; level=\u0026#34;DEBUG\u0026#34;/\u0026gt; \u0026lt;Root level=\u0026#34;INFO\u0026#34;\u0026gt; \u0026lt;AppenderRef ref=\u0026#34;Console\u0026#34; /\u0026gt; \u0026lt;AppenderRef ref=\u0026#34;DebugFile\u0026#34;/\u0026gt; \u0026lt;AppenderRef ref=\u0026#34;InfoFile\u0026#34; /\u0026gt; \u0026lt;AppenderRef ref=\u0026#34;ErrorFile\u0026#34; /\u0026gt; \u0026lt;AppenderRef ref=\u0026#34;FatalFile\u0026#34; /\u0026gt; \u0026lt;/Root\u0026gt; \u0026lt;/Loggers\u0026gt; \u0026lt;/Configuration\u0026gt; config yaml file # Configuration: status: warn Properties: Property: - name: LOG_HOME value: logs - name: PATTERN_FORMAT value: \u0026#34;%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%-5level] %c{1.5.*}.%M(%L) - %msg%n%throwable\u0026#34; Appenders: Console: name: ConsoleAppender target: SYSTEM_OUT PatternLayout: pattern: ${PATTERN_FORMAT} RollingRandomAccessFile: name: FileAppender fileName: ${LOG_HOME}/app.log filePattern: \u0026#34;${LOG_HOME}/%d{yyyy-MM}-week-${date:w}/%d{yyyy-MM-dd}-%i.log.zip\u0026#34; PatternLayout: pattern: ${PATTERN_FORMAT} Policies: SizeBasedTriggeringPolicy: size: 50MB TimeBasedTriggeringPolicy: interval: 1 modulate: true DefaultRolloverStrategy: max: 30 Delete: basePath: ${LOG_HOME} maxDepth: 3 IfFileName: glob: \u0026#34;*/week-*/*.log.zip\u0026#34; Loggers: Root: level: info AppenderRef: - ref: ConsoleAppender - ref: FileAppender Logger: - name: org.apache level: warn - name: org.mybatis level: debug springboot指定yaml配置文件 # logging: config: classpath:log4j2.yaml ","date":"2025-05-17","externalUrl":null,"permalink":"/docs/log4j2/","section":"文章","summary":"log4j2 pattern format website\nconfig xml file # \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e \u003cConfiguration status=\"WARN\" monitorInterval=\"15\"\u003e \u003cproperties\u003e \u003cproperty name=\"LOG_HOME\"\u003elogs\u003c/property\u003e \u003cproperty name=\"PATTERN_FORMAT\"\u003e%d{HH:mm:ss.SSS} [%t] [%-5level] %c.%M(%L) - %msg%n\u003c/property\u003e \u003c/properties\u003e \u003cAppenders\u003e \u003cConsole name=\"Console\" target=\"SYSTEM_OUT\"\u003e \u003cPatternLayout pattern=\"${PATTERN_FORMAT}\" /\u003e \u003cThresholdFilter level=\"DEBUG\" onMatch=\"ACCEPT\" onMismatch=\"NEUTRAL\" /\u003e \u003c/Console\u003e \u003cRollingRandomAccessFile name=\"DebugFile\" fileName=\"${LOG_HOME}/debug.log\" filePattern=\"${LOG_HOME}/$${date:yyyy-MM-dd}/debug-%d{yyyy-MM-dd}-%i.log.zip\"\u003e \u003cFilters\u003e \u003cThresholdFilter level=\"INFO\" onMatch=\"DENY\" onMismatch=\"NEUTRAL\" /\u003e \u003cThresholdFilter level=\"DEBUG\" onMatch=\"ACCEPT\" onMismatch=\"DENY\" /\u003e \u003c/Filters\u003e \u003cPatternLayout pattern=\"${PATTERN_FORMAT}\" /\u003e \u003cPolicies\u003e \u003cTimeBasedTriggeringPolicy /\u003e \u003cSizeBasedTriggeringPolicy size=\"15 MB\" /\u003e \u003c/Policies\u003e \u003cDefaultRolloverStrategy max=\"20\" \u003e \u003cDelete basePath=\"${LOG_HOME}/\" maxDepth=\"5\"\u003e \u003cIfFileName glob=\"*debug*.log.zip\"/\u003e \u003c/Delete\u003e \u003c/DefaultRolloverStrategy\u003e \u003c/RollingRandomAccessFile\u003e \u003cRollingRandomAccessFile name=\"InfoFile\" fileName=\"${LOG_HOME}/info.log\" filePattern=\"${LOG_HOME}/$${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log.zip\"\u003e \u003cFilters\u003e \u003cThresholdFilter level=\"WARN\" onMatch=\"DENY\" onMismatch=\"NEUTRAL\" /\u003e \u003cThresholdFilter level=\"INFO\" onMatch=\"ACCEPT\" onMismatch=\"DENY\" /\u003e \u003c/Filters\u003e \u003cPatternLayout pattern=\"${PATTERN_FORMAT}\" /\u003e \u003cPolicies\u003e \u003cTimeBasedTriggeringPolicy /\u003e \u003cSizeBasedTriggeringPolicy size=\"15 MB\" /\u003e \u003c/Policies\u003e \u003cDefaultRolloverStrategy max=\"20\" \u003e \u003cDelete basePath=\"${LOG_HOME}/\" maxDepth=\"5\"\u003e \u003cIfFileName glob=\"*info*.log.zip\"/\u003e \u003c/Delete\u003e \u003c/DefaultRolloverStrategy\u003e \u003c/RollingRandomAccessFile\u003e \u003cRollingRandomAccessFile name=\"ErrorFile\" fileName=\"${LOG_HOME}/error.log\" filePattern=\"${LOG_HOME}/$${date:yyyy-MM-dd}/error-%d{yyyy-MM-dd}-%i.log.zip\"\u003e \u003cFilters\u003e \u003cThresholdFilter level=\"FATAL\" onMatch=\"DENY\" onMismatch=\"NEUTRAL\" /\u003e \u003cThresholdFilter level=\"WARN\" onMatch=\"ACCEPT\" onMismatch=\"DENY\" /\u003e \u003c/Filters\u003e \u003cPatternLayout pattern=\"${PATTERN_FORMAT}\" /\u003e \u003cPolicies\u003e \u003cTimeBasedTriggeringPolicy /\u003e \u003cSizeBasedTriggeringPolicy size=\"10 MB\" /\u003e \u003c/Policies\u003e \u003cDefaultRolloverStrategy max=\"15\" \u003e \u003cDelete basePath=\"${LOG_HOME}/\" maxDepth=\"5\"\u003e \u003cIfFileName glob=\"*error*.log.zip\"/\u003e \u003c/Delete\u003e \u003c/DefaultRolloverStrategy\u003e \u003c/RollingRandomAccessFile\u003e \u003cRollingRandomAccessFile name=\"FatalFile\" fileName=\"${LOG_HOME}/fatal.log\" filePattern=\"${LOG_HOME}/$${date:yyyy-MM}/fatal-%d{yyyy-MM-dd}-%i.log.zip\"\u003e \u003cFilters\u003e \u003cThresholdFilter level=\"FATAL\" onMatch=\"ACCEPT\" onMismatch=\"DENY\" /\u003e \u003c/Filters\u003e \u003cPatternLayout pattern=\"${PATTERN_FORMAT}\" /\u003e \u003cPolicies\u003e \u003cTimeBasedTriggeringPolicy /\u003e \u003cSizeBasedTriggeringPolicy size=\"5 MB\" /\u003e \u003c/Policies\u003e \u003cDefaultRolloverStrategy max=\"5\" \u003e \u003cDelete basePath=\"${LOG_HOME}/\" maxDepth=\"5\"\u003e \u003cIfFileName glob=\"*fatal*.log.zip\"/\u003e \u003c/Delete\u003e \u003c/DefaultRolloverStrategy\u003e \u003c/RollingRandomAccessFile\u003e \u003c/Appenders\u003e \u003cLoggers\u003e \u003cLogger name=\"org.apache\" level=\"ERROR\"/\u003e \u003cLogger name=\"org.mybatis\" level=\"DEBUG\"/\u003e \u003cRoot level=\"INFO\"\u003e \u003cAppenderRef ref=\"Console\" /\u003e \u003cAppenderRef ref=\"DebugFile\"/\u003e \u003cAppenderRef ref=\"InfoFile\" /\u003e \u003cAppenderRef ref=\"ErrorFile\" /\u003e \u003cAppenderRef ref=\"FatalFile\" /\u003e \u003c/Root\u003e \u003c/Loggers\u003e \u003c/Configuration\u003e config yaml file # Configuration: status: warn Properties: Property: - name: LOG_HOME value: logs - name: PATTERN_FORMAT value: \"%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%-5level] %c{1.5.*}.%M(%L) - %msg%n%throwable\" Appenders: Console: name: ConsoleAppender target: SYSTEM_OUT PatternLayout: pattern: ${PATTERN_FORMAT} RollingRandomAccessFile: name: FileAppender fileName: ${LOG_HOME}/app.log filePattern: \"${LOG_HOME}/%d{yyyy-MM}-week-${date:w}/%d{yyyy-MM-dd}-%i.log.zip\" PatternLayout: pattern: ${PATTERN_FORMAT} Policies: SizeBasedTriggeringPolicy: size: 50MB TimeBasedTriggeringPolicy: interval: 1 modulate: true DefaultRolloverStrategy: max: 30 Delete: basePath: ${LOG_HOME} maxDepth: 3 IfFileName: glob: \"*/week-*/*.log.zip\" Loggers: Root: level: info AppenderRef: - ref: ConsoleAppender - ref: FileAppender Logger: - name: org.apache level: warn - name: org.mybatis level: debug springboot指定yaml配置文件 # logging: config: classpath:log4j2.yaml","title":"Log4j2模板","type":"docs"},{"content":"","date":"2025-05-17","externalUrl":null,"permalink":"/tags/xml/","section":"标签","summary":"","title":"Xml","type":"tags"},{"content":"","date":"2025-05-17","externalUrl":null,"permalink":"/tags/yaml/","section":"标签","summary":"","title":"Yaml","type":"tags"},{"content":"","date":"2025-05-17","externalUrl":null,"permalink":"/categories/%E6%A8%A1%E6%9D%BF/","section":"类别","summary":"","title":"模板","type":"categories"},{"content":"","date":"2025-05-17","externalUrl":null,"permalink":"/tags/sqlite/","section":"标签","summary":"","title":"SQLite","type":"tags"},{"content":" 创建db文件 # sqlite3 dbname.db springboot集成sqlite和druid # spring: datasource: url: jdbc:sqlite:lib/asir.db driver-class-name: org.sqlite.JDBC type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 min-idle: 5 max-active: 20 max-wait: 60000 time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000 validation-query: SELECT 1 test-while-idle: true test-on-borrow: false test-on-return: false pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 ","date":"2025-05-17","externalUrl":null,"permalink":"/docs/sqlite/","section":"文章","summary":"创建db文件 # sqlite3 dbname.db springboot集成sqlite和druid # spring: datasource: url: jdbc:sqlite:lib/asir.db driver-class-name: org.sqlite.JDBC type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 min-idle: 5 max-active: 20 max-wait: 60000 time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000 validation-query: SELECT 1 test-while-idle: true test-on-borrow: false test-on-return: false pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000","title":"SQLite配置","type":"docs"},{"content":"","date":"2025-05-17","externalUrl":null,"permalink":"/categories/%E6%95%99%E7%A8%8B/","section":"类别","summary":"","title":"教程","type":"categories"},{"content":"","date":"2025-05-02","externalUrl":null,"permalink":"/tags/docker/","section":"标签","summary":"","title":"Docker","type":"tags"},{"content":" 安装docker # 卸载旧版本 # 无论之前有没有下载过皆可执行\nsudo yum remove docker \\ docker-client \\ docker-client-latest \\ docker-common \\ docker-latest \\ docker-latest-logrotate \\ docker-logrotate \\ docker-engine 设置yum库 # sudo yum install -y yum-utils sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安装最新版本docker引擎 # sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 启动docker # sudo systemctl start docker 测试docker # sudo docker run hello-world 出现上述界面代表安装成功\n若出现拉取失败，且显示访问的是docker官方镜像，则需要配置docker加速器\nsudo mkdir -p /etc/docker vim /etc/docker/daemon.json 在daemon.json中添加如下内容(一定要注意json格式问题！否则docker可能启动失败或不生效)：\n{ \u0026#34;registry-mirrors\u0026#34;: [ \u0026#34;https://7sbs9twe.mirror.aliyuncs.com\u0026#34;, \u0026#34;https://docker.m.daocloud.io\u0026#34;, \u0026#34;https://hub-mirror.c.163.com\u0026#34;, \u0026#34;https://registry.aliyuncs.com\u0026#34; ] } 然后执行\nsudo systemctl daemon-reload sudo systemctl restart docker 删除下载的镜像 # docker ps -a 找到hello wolrd容器对应的id docker rm 容器ID docker images 找到hello world镜像的id docker rmi 镜像ID 出现上述界面代表删除成功\n测试docker compose # docker compose version 出现docker compose版本号即为成功\n配置docker对外开放 # 修改配置文件 # vim /usr/lib/systemd/system/docker.service 输入/ExecStart，注释掉这一行，复制然后修改为\nExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock -H fd:// --containerd=/run/containerd/containerd.sock 重载docker # systemctl daemon-reload \u0026amp;\u0026amp; systemctl restart docker 防火墙开放2375端口 # firewall-cmd --zone=public --add-port=2375/tcp --permanent firewall-cmd --reload 配置docker开机自启 # systemctl enable docker ","date":"2025-05-02","externalUrl":null,"permalink":"/docs/docker/","section":"文章","summary":"安装docker # 卸载旧版本 # 无论之前有没有下载过皆可执行\n","title":"Docker安装","type":"docs"},{"content":"","date":"2025-05-02","externalUrl":null,"permalink":"/tags/%E5%AE%89%E8%A3%85/","section":"标签","summary":"","title":"安装","type":"tags"},{"content":"","date":"2025-05-02","externalUrl":null,"permalink":"/tags/virtualbox/","section":"标签","summary":"","title":"VirtualBox","type":"tags"},{"content":" 一、搭建后台运行的centos7服务器 # VirtualBox官网 ；centOS7镜像网站列表 ；清华大学镜像网站链接\n首先安装VirtualBox虚拟机，最新版就可以。下载centos7镜像文件，首先打开网站列表，搜索框输入Asia寻找亚洲地区，然后找一个链接点进去，选择版本7，选择isos目录，无脑往下点，然后选择CentOS-7-x86_64-Minimal-2009.iso 镜像文件，下载即可（也可直接点击清华大学的链接，就能直接选对应iso文件下载了）\nminimal是最小体积的centos，无界面，想要有界面下载everything或者dvd都可以\nWarning: VirtualBox7.0之后的版本安装可能会出现Invalid installation directory错误, 直接给出省流解决办法，管理员打开cmd控制台，一定是cmd不是powershell，然后输入以下命令：\nicacls D:\\VBox /reset /t /c icacls D:\\VBox /inheritance:d /t /c icacls D:\\VBox /grant *S-1-5-32-545:(OI)(CI)(RX) icacls D:\\VBox /deny *S-1-5-32-545:(DE,WD,AD,WEA,WA) icacls D:\\VBox /grant *S-1-5-11:(OI)(CI)(RX) icacls D:\\VBox /deny *S-1-5-11:(DE,WD,AD,WEA,WA) D:\\VBox是你的VirtualBox安装目录，最好是在盘符根目录下创建安装目录，否则你就要递归所有目录执行一遍上述命令！！！且在执行上述命令时会更改对应目录下的所有文件权限。例如：D:\\app\\VBox是你的安装目录，则需要执行：\nicacls D:\\app /reset /t /c icacls D:\\app\\VBox /reset /t /c 这两条命令，你的安装目录层级有多深就要幂等执行多少条，所以建议一定要安装在最上层目录下！该解决方案来源于官网，为什么要这么做里面也有讨论和说明。\n命令解释说明：\nicacls: 用于显示或修改访问控制列表 (ACL)。 /reset: 用于将 ACL 重置为默认的权限。 /t: 递归处理所有子目录和文件。 /c: 继续执行命令，即使发生错误。 /inheritance:d: 移除继承的权限。 /grant: 授予访问权限。 *S-1-5-32-545: Users组的SID。 (OI)(CI)(RX): 对象继承、容器继承、读取和执行权限。 /deny: 拒绝访问权限。 *S-1-5-11: Authenticated Users组的SID。 (DE,WD,AD,WEA,WA): 删除、写入数据、添加数据、写入扩展属性、写入属性权限。 1、新建虚拟电脑 # 2、配置硬件 # 3、创建虚拟硬盘 # 4、点击下一步，点击完成，创建成功 # 5、配置服务器 # 对新建的服务器右键选择设置打开以下页面\n5.1、选择系统，勾选启动顺序中的网络，然后点击光驱，点击右边的向上箭头将光驱放到第一位 # 5.2、选择网络，选择网卡2，点击启动网络连接，连接方式选择仅主机Host-only网络 # 这一步如果没有显示其余网卡，则可以先跳过，等安装完系统之后关闭虚拟机，然后再次打开设置，就会显示其余网卡了\n注：网卡1也要已经启动网络连接，连接方式默认为网络地址转换NAT即可\n5.3、点击右下角确定即配置完毕，配置完成之后的主界面往下滑动如下图 # 注：马赛克是因为这个地方的教程是后续添加的，so ψ(._. )\u0026gt;\n6、选中服务器，点击右上角启动，启动服务器(第一次需正常图形化界面启动) # 选择第一个，敲击回车\n7、等待安装的过程，直到出现选择语言界面，如下图 # 左边滑到最下面选择中文，右边选择简体中文，点击继续(可选，可以直接默认使用英文)\n8、出现如下界面 # 9、配置键盘和语言支持(可选，增加英语键盘和语言) # 10、配置系统安装位置 # 选择本地标准磁盘，点击完成即可（外面不再显示黄色警告，如果还出现再次点进来选中再点击完成）\n11、配置网络 # 选择第一个网卡enp0s3，点击右边的关闭按钮变成打开，网络显示已连接即成功，点击完成\n12、配置完成，点击开始安装 # 13、设置root密码(必须)，添加用户(可选)，等待安装 # 14、安装完成，点击重启 # 15、重启之后默认选择第一个进入即可，然后输入root和密码进行登录，如下图即成功 # 16、检查网卡配置和网络是否连接 # 输入ip addr查看网卡，然后输入ping www.baidu.com查看能够连接外网(按ctrl+c终止)\n17、配置静态ip地址 # 17.1、查看virtualboxip地址 # 17.1.1、右键电脑右下角wifi标志，点击打开网络设置 # 17.1.2、选择更改适配器选项 # 17.1.3、找到含有VirtualBox Host-Only Ethernet标志的网络，右键点击属性 # 17.1.4、找到ipv4，点击右下方属性 # 17.1.5、查看ip地址 # 这里如果不是这样显示，配置成这样，然后点击确定\n17.2、进入服务器，编辑网络地址 # 17.2.1、查看是否含有网卡配置文件(敲击tab快捷输入) # ls /etc/sysconfig/network-scripts/\n17.2.2、编辑第二块网卡配置文件(即ifcfg-enp0s8，如果没有请先返回第5条配置服务器) # 如果返回之后配置完毕使用ip addr命令能够显示两张网卡，但是net-word-scripts中没有ifcfg-enp0s8文件，那么就使用以下命令生成一个网卡配置文件：\nnmcli con add con-name enp0s8 type ethernet ifname enp0s8 这个时候就会出现这个配置文件了，然后进行下列操作。\nvi /etc/sysconfig/network-scripts/ifcfg-enp0s8\n编辑红框区域，如果没有就自己添加（vi编写文件，:wq保存退出）\n17.2.3、重启网络服务 # systemctl restart network\n17.3、输入ip addr查看配置是否成功 # 成功显示ip地址即为成功\n18、配置xshell远程连接 # 点击确定后会弹框，选择接受并保存即可，然后如下图显示就表示远程连接成功\n二、配置初始的centos7 # 1、更新yum # yum update -y\n如果命令执行失败，提示yum源错误，则需要下载yum华为云镜像源，然后备份/etc/yum.repos.d下的所有文件：\ncd /etc/yum.repos.d find . -type f exec cp {} {}.bak \\; 将下载的文件上传到该目录下，原有的CentOS-Base.repo文件删除，上传的文件重命名为CentOS-Base.repo，执行以下命令：\nyum clean all yum makecache yum repolist all 这时候就可以重新执行yum update -y命令了\n2、安装vim # yum install -y vim\n3、解决xshell连接显示警告(The remote SSH server rejected X11 forwarding request) # 3.1、安装xorg-x11-xauth # yum install -y xorg-x11-xauth\n3.2、防火墙开放22端口 # firewall-cmd \u0026ndash;zone=public \u0026ndash;add-port=22/tcp \u0026ndash;permanent\n3.3、重新加载防火墙 # firewall-cmd \u0026ndash;reload\n这时候你断开xshell连接，然后重新连接就会发现警告消失了，但是会一个文件不存在的语句（/usr/bin/xauth: file /root/.Xauthority does not exist）\n3.4、创建指定文件(解决/usr/bin/xauth: file /root/.Xauthority does not exist) # touch ~/.Xauthority\n现在重新连接xshell就不会显示任何报错了\n三、配置windows自启 # win11任务计划脚本\n$VBoxManagePath = \u0026#34;E:\\VBox\\VBoxManage.exe\u0026#34; $VMName = \u0026#34;remote1\u0026#34; $TaskName = \u0026#34;StartVM-$VMName\u0026#34; if (-not (Test-Path $VBoxManagePath)) { Write-Error \u0026#34;VirtualBox not found in: $($VBoxManagePath).please check path or update script!\u0026#34; exit 1 } $ActionArgument = \u0026#34;startvm \u0026#34;\u0026#34;$VMName\u0026#34;\u0026#34; --type headless\u0026#34; $TaskAction = New-ScheduledTaskAction -Execute $VBoxManagePath -Argument $ActionArgument -WorkingDirectory (Split-Path $VBoxManagePath) $TaskTrigger = New-ScheduledTaskTrigger -AtLogon $TaskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries:$false -DontStopIfGoingOnBatteries:$false $TaskPrincipal = New-ScheduledTaskPrincipal -UserId \u0026#34;Blue\u0026#34; -RunLevel Highest $ScheduledTask = New-ScheduledTask -Action $TaskAction -Trigger $TaskTrigger -Settings $TaskSettings -Principal $TaskPrincipal try{ Register-ScheduledTask -TaskName $TaskName -InputObject $ScheduledTask -Force Write-Host \u0026#34;create startup task \u0026#39;$TaskName\u0026#39; success!\u0026#34; } catch { Write-Error \u0026#34;create or update task fail:$($_.Exception.Message)\u0026#34; exit 1 } 参数解释说明：\n$VBoxManagePath: VirtualBoxManager的路径，修改为你自己的路径 $VMName: 虚拟机的名称，修改为你自己的虚拟机名称 $TaskName: 任务名称，默认是StartVM-$VMName $TaskAction: 任务执行的操作，在目标工作目录启动虚拟机 $TaskTrigger: 任务触发器，系统启动时触发 $TaskSettings: 任务设置，默认是使用交流电才启动任务,如果使用电池则不启动 $TaskPrincipal: 任务主体，UserId是当前登录的用户名(最好具有管理员权限)，RunLevel是最高权限 复制到txt文件中,重命名为startvm.ps1，放在你想要的目录下，然后以管理员身份运行powershell，执行此脚本:脚本所在目录\\startvm.ps1直接回车,输出create startup task \u0026lsquo;StartVM-remote1\u0026rsquo; success!即成功\n","date":"2025-05-02","externalUrl":null,"permalink":"/docs/virtualbox/","section":"文章","summary":"一、搭建后台运行的centos7服务器 # VirtualBox官网 ；centOS7镜像网站列表 ；清华大学镜像网站链接\n","title":"VirtualBox最小化安装","type":"docs"},{"content":"","date":"2025-01-14","externalUrl":null,"permalink":"/tags/github/","section":"标签","summary":"","title":"Github","type":"tags"},{"content":"","date":"2025-01-14","externalUrl":null,"permalink":"/tags/numpy/","section":"标签","summary":"","title":"Numpy","type":"tags"},{"content":"","date":"2025-01-14","externalUrl":null,"permalink":"/tags/pandas/","section":"标签","summary":"","title":"Pandas","type":"tags"},{"content":"","date":"2025-01-14","externalUrl":null,"permalink":"/tags/picgo/","section":"标签","summary":"","title":"PicGO","type":"tags"},{"content":"","date":"2025-01-14","externalUrl":null,"permalink":"/tags/python/","section":"标签","summary":"","title":"Python","type":"tags"},{"content":" 一、 numpy # 下标提取\n# x为开始位置,y为结束位置,z为步长 a[x:y:z] # 逗号前为行,后为行 a[x:y:z,x1:y1:z1] # 取出满足x\u0026gt;3并且x\u0026lt;10的元素 a[(x \u0026gt; 3) \u0026amp; (x \u0026lt; 10)] 反转数组\nz = z[::-1] 改变数组形状\nreshape(3,3) 找出不为0的数，返回下标\nnp.nonzero([1,2,0,0,4,0]) 随机生成3*3*3的矩阵\nnp.random.random((3,3,3)) 提取主对角线上面/下面斜线的元素\n# -1:主对角线下面,1:主对角线上面,0:主对角线 np.diag(x, k=-1/1/0) 创建一个只包含主对角线元素的n*m矩阵(其他元素为0)\n# 负数:主对角线向下偏移,0:主对角线,正数:主对角线向上偏移 np.eye(n,m,k=负数/0/正数) 创建一个矩阵（基于另外一个矩阵重复reps次）\n# 重复矩阵A(reps=数字:单纯重复次数,reps=(y,x):重复行y次,列x次) np.tile(A,reps) 矩阵相乘\nnp.dot(A,B) 获取日期\n#(今天,昨天,明天) yesterday = np.datetime64(\u0026#39;today\u0026#39;) - np.timedelta64(1) today = np.datetime64(\u0026#39;today\u0026#39;) tomorrow = np.datetime64(\u0026#39;today\u0026#39;) + np.timedelta64(1) #某一个月所有的日期(np.arange(\u0026#39;2016-07\u0026#39;, \u0026#39;2016-08\u0026#39;, dtype=\u0026#39;datetime64[D]\u0026#39;)) np.arange(\u0026#39;某个月\u0026#39;,\u0026#39;下个月\u0026#39;,dtype=\u0026#39;datetime64[D]\u0026#39;) 随机生成均匀分布的矩阵\nnp.random.uniform(low,high,size) 生成不包含x,y的在x到y的z个数的线性数组\nnp.linspace(x,y,z,endpoint=False)[1:] 快速计算小数组求和\nZ = np.arange(10) np.add.reduce(Z) 矩阵只读\nZ.flags.writeable = False 将矩阵的最大值改成x\nZ[Z.argmax()] = x 找出矩阵中最接近x的值\nZ.flat[np.abs(Z - x).argmin()] 找到在矩阵中最接近给定值的值\nZ.flat[np.abs(Z - 给定值).argmin()] 二、pandas # 提取某一列含有nan的行\ndf[df[\u0026#39;col_name\u0026#39;].isnull()] 统计某一列不同元素的个数\ndf[\u0026#39;col_name\u0026#39;].value_counts() 将某一列元素值对应更改(映射更改某列)\ndf[\u0026#39;col_name\u0026#39;].map({\u0026#39;old_value1\u0026#39;: new_value1, \u0026#39;old_value2\u0026#39;: new_value2}) 某一列元素值直接替换\ndf[\u0026#39;col_name\u0026#39;].replace(\u0026#39;old_value\u0026#39;, \u0026#39;new_value\u0026#39;) 生成数据透视表\ndf.pivot_table(index=\u0026#39;col_name1\u0026#39;, columns=\u0026#39;col_name2\u0026#39;, values=\u0026#39;col_name3\u0026#39;, aggfunc=\u0026#39;method_name\u0026#39;) 找到某一列最大的几个元素\ndf[\u0026#39;col_name\u0026#39;].nlargest(num) 拆分某一列(按照字符串拆分)\nt = df[\u0026#39;col_name\u0026#39;].str.split(\u0026#39;\u0026#39;,expand=True) t.columns = [\u0026#39;col_name1\u0026#39;,\u0026#39;col_\u0026#39;,...] 删除某一列\ndel df[\u0026#39;col_name\u0026#39;] 获取不连续位置数据集\ndf[[\u0026#39;col_name1\u0026#39;,\u0026#39;col_name2\u0026#39;...]] 获取内层索引数据\ndf[:,\u0026#39;inner_index_name\u0026#39;] ","date":"2025-01-14","externalUrl":null,"permalink":"/docs/python/","section":"文章","summary":"一、 numpy # 下标提取\n","title":"Python数据分析","type":"docs"},{"content":"","date":"2025-01-14","externalUrl":null,"permalink":"/tags/spring/","section":"标签","summary":"","title":"Spring","type":"tags"},{"content":"","date":"2025-01-14","externalUrl":null,"permalink":"/tags/springmvc/","section":"标签","summary":"","title":"SpringMVC","type":"tags"},{"content":" 执行流程 # DispatcherServlet表示前置控制器，是整个SpringMVC的控制中心，用户发出请求，DispatcherServlet接收请求并拦截请求 假设URL为：http://localhost:8080/SpringMVC/hello 如上URL拆分为三部分 http://localhost:8080服务器域名 SpringMVC部署在服务器上的web站点 hello表示控制器 通过分析，url表示为：请求位于服务器localhost:8080上的SpringMVC站点的hello控制器 HandlerMapping为处理器映射，DispatcherServlet调用HandlerMapping，HandlerMapping根据请求url查找Handler HandlerExecution表示具体的Handler，其主要作用是根据url查找控制器 HandlerExecution将解析后的信息传递给DispatcherServlet HandlerAdapter表示处理适配器，其按照特定的规则去执行Handler Handler让具体的Controller执行 Controller将具体的执行信息返回给HandlerAdapter HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet DispatcherServlet调用视图解析器（ViewResolver）来解析HandlerAdapter传递的逻辑视图名 视图解析器将解析的逻辑视图名传给DispatcherServlet DispatcherServlet根据视图解析器解析的视图结果，调用具体的视图 最终视图呈现给用户 基于XML实现 # 1.引入相关依赖 # \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-webmvc\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;5.3.0\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;javax.servlet\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;servlet-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;2.5\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;javax.servlet.jsp\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;jsp-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;2.2\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;javax.servlet\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;jstl\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.2\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 2.创建类 # public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); //业务代码 String result = \u0026#34;你好，我是MVC\u0026#34;; mv.addObject(\u0026#34;msg\u0026#34;,result); //视图跳转 mv.setViewName(\u0026#34;test\u0026#34;); return mv; } } 3.配置web.xml文件 # \u0026lt;!--配置DispatcherServlet,这个是sptingmvc的核心--\u0026gt; \u0026lt;servlet\u0026gt; \u0026lt;servlet-name\u0026gt;springmvc\u0026lt;/servlet-name\u0026gt; \u0026lt;servlet-class\u0026gt;org.springframework.web.servlet.DispatcherServlet\u0026lt;/servlet-class\u0026gt; \u0026lt;!--DispatcherServlet要绑定的spring配置文件--\u0026gt; \u0026lt;init-param\u0026gt; \u0026lt;param-name\u0026gt;contextConfigLocation\u0026lt;/param-name\u0026gt; \u0026lt;param-value\u0026gt;classpath:springmvc-servlet.xml\u0026lt;/param-value\u0026gt; \u0026lt;/init-param\u0026gt; \u0026lt;!--启动级别：1--\u0026gt; \u0026lt;load-on-startup\u0026gt;1\u0026lt;/load-on-startup\u0026gt; \u0026lt;/servlet\u0026gt; \u0026lt;!-- springmvc中， / /* /:只匹配所有的请求，不会去匹配jsp页面 /*:匹配所有的请求，包括jsp页面 --\u0026gt; \u0026lt;servlet-mapping\u0026gt; \u0026lt;servlet-name\u0026gt;springmvc\u0026lt;/servlet-name\u0026gt; \u0026lt;url-pattern\u0026gt;/\u0026lt;/url-pattern\u0026gt; \u0026lt;/servlet-mapping\u0026gt; 4.配置springmvc-servlet.xml文件 # \u0026lt;!--处理器映射器--\u0026gt; \u0026lt;bean class=\u0026#34;org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping\u0026#34;/\u0026gt; \u0026lt;!--处理器适配器--\u0026gt; \u0026lt;bean class=\u0026#34;org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter\u0026#34;/\u0026gt; \u0026lt;!--处理器解析器--\u0026gt; \u0026lt;bean class=\u0026#34;org.springframework.web.servlet.view.InternalResourceViewResolver\u0026#34; id=\u0026#34;internalResourceViewResolver\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;prefix\u0026#34; value=\u0026#34;/WEB-INF/jsp/\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;suffix\u0026#34; value=\u0026#34;.jsp\u0026#34;/\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;!--创建对象--\u0026gt; \u0026lt;bean id=\u0026#34;/hello\u0026#34; class=\u0026#34;org.learn.demon.HelloController\u0026#34;/\u0026gt; 5.创建jsp文件 # \u0026lt;%@ page contentType=\u0026#34;text/html;charset=UTF-8\u0026#34; language=\u0026#34;java\u0026#34; %\u0026gt; \u0026lt;html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;title\u0026gt;Title\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; ${msg} \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; 6.配置Tomcat服务器 # 添加服务器之后，到工程结构，浏览tomcat打包的war包中有没有lib文件，没有就创建一个，把所有需要的jar包放进去\n7.运行结果 # 浏览器输入/hello显示：你好，我是MVC界面\n四、基于注解实现 # 1.导入依赖 # 同三、-\u0026gt;1.依赖配置相同\n2.编写web.xml配置文件 # \u0026lt;servlet\u0026gt; \u0026lt;servlet-name\u0026gt;springmvc\u0026lt;/servlet-name\u0026gt; \u0026lt;servlet-class\u0026gt;org.springframework.web.servlet.DispatcherServlet\u0026lt;/servlet-class\u0026gt; \u0026lt;init-param\u0026gt; \u0026lt;param-name\u0026gt;contextConfigLocation\u0026lt;/param-name\u0026gt; \u0026lt;param-value\u0026gt;classpath:springmvc-servlet.xml\u0026lt;/param-value\u0026gt; \u0026lt;/init-param\u0026gt; \u0026lt;load-on-startup\u0026gt;1\u0026lt;/load-on-startup\u0026gt; \u0026lt;/servlet\u0026gt; \u0026lt;servlet-mapping\u0026gt; \u0026lt;servlet-name\u0026gt;springmvc\u0026lt;/servlet-name\u0026gt; \u0026lt;url-pattern\u0026gt;/\u0026lt;/url-pattern\u0026gt; \u0026lt;/servlet-mapping\u0026gt; 3.编写spring配置文件 # mvc:default-servlet-handler：使springmvc不处理静态资源 .css .js .mp4 .html .mp3 mvc:annotation-driven：支持mvc注解驱动，spirng中一般采用@RequestMapping注解完成映射关系，要想使注解生效，就需要配置DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例，这两个实例分别在类级别和方法级别处理，而annotation-driven可以帮我们自动完成上面的配置 配置视图解析器，prefix为前缀，suffix为后缀 \u0026lt;context:component-scan base-package=\u0026#34;org.learn.demon\u0026#34;/\u0026gt; \u0026lt;mvc:default-servlet-handler/\u0026gt; \u0026lt;mvc:annotation-driven/\u0026gt; \u0026lt;bean class=\u0026#34;org.springframework.web.servlet.view.InternalResourceViewResolver\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;prefix\u0026#34; value=\u0026#34;/WEB-INF/jsp/\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;suffix\u0026#34; value=\u0026#34;.jsp\u0026#34;/\u0026gt; \u0026lt;/bean\u0026gt; 4.创建对应的控制类 # @Controller public class HelloController { @RequestMapping(\u0026#34;/h1\u0026#34;) public String hello1(Model model){ //向模型中添加属性msg与值，可以在jsp页面中取出并渲染 model.addAttribute(\u0026#34;msg\u0026#34;,\u0026#34;Hello 你好\u0026#34;); return \u0026#34;hello\u0026#34;; } } 5.完善前端视图和controller之间的关系 # \u0026lt;%@ page contentType=\u0026#34;text/html;charset=UTF-8\u0026#34; language=\u0026#34;java\u0026#34; %\u0026gt; \u0026lt;html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;title\u0026gt;Title\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; ${msg} \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; 6.运行调试 # 五、注解说明 # 1.@Controller # 被这个注解的类中的所有的方法，如果返回值是String，并且有具体页面可以跳转，那么就会被视图解析器解析。\n\u0026mdash;注意：返回的字符串如果没有组成页面跳转拼接成的正确的URL，那么就会报错404\n2.@RequestMapping # 用于映射url到控制器类或一个特定的处理程序方法，可用于类或方法上。在类上，表示类中的所有请求的方法都是以该地址作为父路径\n1.method方法属性值 # RequestMethod.GET\nRequestMethod.POST\nRequestMethod.DELETE\u0026hellip;\u0026hellip;\n可以点击method方法进入详细查看\n以上所有的method都可以直接写为一个单独的注解（例如：@PostMapping(value=\u0026ldquo;url地址\u0026rdquo;) 或 @GetMapping(value=\u0026ldquo;url地址\u0026rdquo;) 等等）\n2.@PathVariable # 让方法参数中的值对应绑定到一个URL模板变量上\n加入该注解后，方法中的变量可以使URL地址发生改变，RequestMapping中value中的值就可以写为类似\u0026quot;/login/{a}/{b}\u0026ldquo;的方式\n六、详解 # 1.RESTFUL风格 # 通过不同的请求方式来实现不同的效果（同一个URL地址，不同的请求方式结果不同）\n2.转发和重定向 # return里面默认写字符串即为转发，字符串里面写上redirect:页面路径即可重定向页面（例:\u0026ldquo;redirect:/index.jsp\u0026rdquo;）\n3.接收请求参数及数据回显 # 接收前端用户传递的参数，判断参数的名字，假设名字直接在方法上，可以直接使用 假设传递的是一个对象User，匹配User对象中的字段名；如果字段名一致则接收，否则，匹配不到 4.数据回显方式区别 # Model：只有几个方法适用于存储数据\nModelMap：继承了LinkedMap，除了实现了自身的一些方法，同样继承了LinkedMap的方法和特性\nModelAndView：在存储数据的同时，进行设置返回的逻辑视图，进行控制层的跳转\n5.乱码问题 # 在web.xml文件中配置spring过滤器\n注意这里映射需要设置/*，因为需要匹配jsp页面\n\u0026lt;filter\u0026gt; \u0026lt;filter-name\u0026gt;encodingFilter\u0026lt;/filter-name\u0026gt; \u0026lt;filter-class\u0026gt;org.springframework.web.filter.CharacterEncodingFilter\u0026lt;/filter-class\u0026gt; \u0026lt;init-param\u0026gt; \u0026lt;param-name\u0026gt;encoding\u0026lt;/param-name\u0026gt; \u0026lt;param-value\u0026gt;utf-8\u0026lt;/param-value\u0026gt; \u0026lt;/init-param\u0026gt; \u0026lt;/filter\u0026gt; \u0026lt;filter-mapping\u0026gt; \u0026lt;filter-name\u0026gt;encodingFilter\u0026lt;/filter-name\u0026gt; \u0026lt;url-pattern\u0026gt;/*\u0026lt;/url-pattern\u0026gt; \u0026lt;/filter-mapping\u0026gt; 或者tomcat服务器中conf文件夹下server.xml文件中添加编码格式\n\u0026lt;Connector port=\u0026#34;8080\u0026#34; protocol=\u0026#34;HTTP/1.1\u0026#34; connectionTimeout=\u0026#34;20000\u0026#34; redirectPort=\u0026#34;8443\u0026#34; URIEncoding=\u0026#34;utf-8\u0026#34;/\u0026gt; 七、JSON # 一、概念 # 1.什么是json # JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式 采用完全独立于编程语言的文本格式来存储和表示数据 简洁和清晰的层次结构使得JSON成为理想的数据交换语言 易于人阅读和编写，同时也易于机器解析和生成，并有效的提升网络传输效率 2.语法 # 对象表示为键值对，数据由逗号分隔 花括号保存对象 方括号保存数组 3.配置依赖 # maven中添加jackson依赖（或者fast-json也可以）\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;com.fasterxml.jackson.core\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;jackson-databind\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;2.12.3\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 4.创建类 # 添加@ResponseBody注解，返回json字符串，创建ObjectMapper对象，接收json字符串\n@RequestMapping(value = \u0026#34;/t1\u0026#34;) @ResponseBody public String test1() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); User user = new User(\u0026#34;路飞\u0026#34;,1,20); String str = mapper.writeValueAsString(user); return str; } 5.乱码处理 # 在spirng配置文件中配置\n\u0026lt;mvc:annotation-driven\u0026gt; \u0026lt;mvc:message-converters register-defaults=\u0026#34;true\u0026#34;\u0026gt; \u0026lt;bean class=\u0026#34;org.springframework.http.converter.StringHttpMessageConverter\u0026#34;\u0026gt; \u0026lt;constructor-arg value=\u0026#34;UTF-8\u0026#34;/\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;bean class=\u0026#34;org.springframework.http.converter.json.MappingJackson2HttpMessageConverter\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;objectMapper\u0026#34;\u0026gt; \u0026lt;bean class=\u0026#34;org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;failOnEmptyBeans\u0026#34; value=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;/mvc:message-converters\u0026gt; \u0026lt;/mvc:annotation-driven\u0026gt; 6.@RestController和@ResponseBody注解 # @RestController作用在类上，代替@Controller，使用该注解默认该类返回的都是json字符串，不会被视图解析器解析 @ResponseBody作用在方法上，配合@Controller使用，被该注解注解的方法返回json字符串，不会被视图解析器解析 ","date":"2025-01-14","externalUrl":null,"permalink":"/docs/springmvc/","section":"文章","summary":"执行流程 # DispatcherServlet表示前置控制器，是整个SpringMVC的控制中心，用户发出请求，DispatcherServlet接收请求并拦截请求 假设URL为：http://localhost:8080/SpringMVC/hello 如上URL拆分为三部分 http://localhost:8080服务器域名 SpringMVC部署在服务器上的web站点 hello表示控制器 通过分析，url表示为：请求位于服务器localhost:8080上的SpringMVC站点的hello控制器 HandlerMapping为处理器映射，DispatcherServlet调用HandlerMapping，HandlerMapping根据请求url查找Handler HandlerExecution表示具体的Handler，其主要作用是根据url查找控制器 HandlerExecution将解析后的信息传递给DispatcherServlet HandlerAdapter表示处理适配器，其按照特定的规则去执行Handler Handler让具体的Controller执行 Controller将具体的执行信息返回给HandlerAdapter HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet DispatcherServlet调用视图解析器（ViewResolver）来解析HandlerAdapter传递的逻辑视图名 视图解析器将解析的逻辑视图名传给DispatcherServlet DispatcherServlet根据视图解析器解析的视图结果，调用具体的视图 最终视图呈现给用户 基于XML实现 # 1.引入相关依赖 # \u003cdependency\u003e \u003cgroupId\u003eorg.springframework\u003c/groupId\u003e \u003cartifactId\u003espring-webmvc\u003c/artifactId\u003e \u003cversion\u003e5.3.0\u003c/version\u003e \u003c/dependency\u003e \u003cdependency\u003e \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e \u003cartifactId\u003eservlet-api\u003c/artifactId\u003e \u003cversion\u003e2.5\u003c/version\u003e \u003c/dependency\u003e \u003cdependency\u003e \u003cgroupId\u003ejavax.servlet.jsp\u003c/groupId\u003e \u003cartifactId\u003ejsp-api\u003c/artifactId\u003e \u003cversion\u003e2.2\u003c/version\u003e \u003c/dependency\u003e \u003cdependency\u003e \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e \u003cartifactId\u003ejstl\u003c/artifactId\u003e \u003cversion\u003e1.2\u003c/version\u003e \u003c/dependency\u003e 2.创建类 # public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); //业务代码 String result = \"你好，我是MVC\"; mv.addObject(\"msg\",result); //视图跳转 mv.setViewName(\"test\"); return mv; } } 3.配置web.xml文件 # \u003c!--配置DispatcherServlet,这个是sptingmvc的核心--\u003e \u003cservlet\u003e \u003cservlet-name\u003espringmvc\u003c/servlet-name\u003e \u003cservlet-class\u003eorg.springframework.web.servlet.DispatcherServlet\u003c/servlet-class\u003e \u003c!--DispatcherServlet要绑定的spring配置文件--\u003e \u003cinit-param\u003e \u003cparam-name\u003econtextConfigLocation\u003c/param-name\u003e \u003cparam-value\u003eclasspath:springmvc-servlet.xml\u003c/param-value\u003e \u003c/init-param\u003e \u003c!--启动级别：1--\u003e \u003cload-on-startup\u003e1\u003c/load-on-startup\u003e \u003c/servlet\u003e \u003c!-- springmvc中， / /* /:只匹配所有的请求，不会去匹配jsp页面 /*:匹配所有的请求，包括jsp页面 --\u003e \u003cservlet-mapping\u003e \u003cservlet-name\u003espringmvc\u003c/servlet-name\u003e \u003curl-pattern\u003e/\u003c/url-pattern\u003e \u003c/servlet-mapping\u003e 4.配置springmvc-servlet.xml文件 # \u003c!--处理器映射器--\u003e \u003cbean class=\"org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping\"/\u003e \u003c!--处理器适配器--\u003e \u003cbean class=\"org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter\"/\u003e \u003c!--处理器解析器--\u003e \u003cbean class=\"org.springframework.web.servlet.view.InternalResourceViewResolver\" id=\"internalResourceViewResolver\"\u003e \u003cproperty name=\"prefix\" value=\"/WEB-INF/jsp/\"/\u003e \u003cproperty name=\"suffix\" value=\".jsp\"/\u003e \u003c/bean\u003e \u003c!--创建对象--\u003e \u003cbean id=\"/hello\" class=\"org.learn.demon.HelloController\"/\u003e 5.创建jsp文件 # \u003c%@ page contentType=\"text/html;charset=UTF-8\" language=\"java\" %\u003e \u003chtml\u003e \u003chead\u003e \u003ctitle\u003eTitle\u003c/title\u003e \u003c/head\u003e \u003cbody\u003e ${msg} \u003c/body\u003e \u003c/html\u003e 6.配置Tomcat服务器 # 添加服务器之后，到工程结构，浏览tomcat打包的war包中有没有lib文件，没有就创建一个，把所有需要的jar包放进去\n","title":"SpringMVC学习","type":"docs"},{"content":" IOC # 基本概念 # 控制反转（Inversion of Control，缩写为IoC），面向对象编程的一种设计原则，可以用来减低计算机代码之间的耦合度。最常见的方式叫做依赖注入（Dependency Injection，简称DI），还有一种方式叫依赖查找（Dependency Lookup）。 通过控制反转，对象在被创建的时候，由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说，依赖被注入到对象中。 IOC思想基于IOC容器完成，IOC容器底层就是对象工厂 Spring提供IOC容器实现两种方式 # BeanFactory：IOC容器基本实现，是spring内部的使用接口，不提供开发人员进行使用（加载配置文件的时候不会创建对象，在获取对象才去创建对象）\nApplicationContext：BeanFactory接口的子接口，提供更多更强大的功能，一般由开发人员进行使用（加载配置文件的时候就会创建对象）\nApplicaitonContext接口实现类 # 1.FileSystemXmlApplicationContext\n2.ClassPathXmlApplicationContex\nApplicationContext context = new ClassPathXmlApplicationContext(\u0026#34;配置bean文件名称.xml\u0026#34;); IOC操作bean管理：XML方式 # 基于xml方式进行属性注入 # 第一种使用property完成属性注入（name：类里面属性名称，value：向属性里面注入的值） # \u0026lt;bean id=\u0026#34;book\u0026#34; class=\u0026#34;org.learn.demon01.Book\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;bauthor\u0026#34; value=\u0026#34;author\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;bname\u0026#34; value=\u0026#34;name\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; 第二种注入方式，使用有参数构造进行注入 # 创建类，定义属性，创建属性对应有参数的构造方法 # //属性 private String oname; private String address; //构造方法 public Orders(String oname, String address) { this.oname = oname; this.address = address; } 在spring配置文件中进行配置 # \u0026lt;bean id=\u0026#34;orders\u0026#34; class=\u0026#34;org.learn.demon01.Orders\u0026#34;\u0026gt; \u0026lt;constructor-arg name=\u0026#34;oname\u0026#34; value=\u0026#34;name\u0026#34;\u0026gt;\u0026lt;/constructor-arg\u0026gt; \u0026lt;constructor-arg name=\u0026#34;address\u0026#34; value=\u0026#34;address\u0026#34;\u0026gt;\u0026lt;/constructor-arg\u0026gt; \u0026lt;/bean\u0026gt; 构造器中也可以使用Index替换name,值0代表第一个参数，1代表第二个参数。。。。\n第三种p名称空间注入 # 第一步添加p名称空间在配置文件头部xml标签中 \u0026lt;beans xmlns=\u0026#34;http://www.springframework.org/schema/beans\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xmlns:p=\u0026#34;http://www.springframework.org/schema/p\u0026#34; \u0026lt;!--添加这个语句--\u0026gt; xsi:schemaLocation=\u0026#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\u0026#34;\u0026gt; 第二步进行属性注入，在bean标签里面进行操作 \u0026lt;bean id=\u0026#34;book\u0026#34; class=\u0026#34;org.learn.demon01.Book\u0026#34; p:bauthor=\u0026#34;author\u0026#34; p:bname=\u0026#34;name\u0026#34;\u0026gt;\u0026lt;/bean\u0026gt; xml注入其他类型属性 # 字面量 # null值\n\u0026lt;property name=\u0026#34;填写属性名\u0026#34;\u0026gt; \u0026lt;null\u0026gt;\u0026lt;/null\u0026gt; \u0026lt;/property\u0026gt; 属性值包含特殊符号\n把符号进行转义 \u0026amp;lt \u0026amp;gt\n把特殊符号内容写到CDATA\n\u0026lt;value\u0026gt;\u0026lt;![CDATA[带有特殊符号的内容]]\u0026gt;\u0026lt;/value\u0026gt; 注入属性-外部bean # 创建两个类service类和dao类\n在service调用dao里面的方法\npublic class UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add(){ System.out.println(\u0026#34;service add ...........\u0026#34;); userDao.update(); } } 在spring配置文件中进行配置\n\u0026lt;!--创建service和dao对象--\u0026gt; \u0026lt;bean id=\u0026#34;userService\u0026#34; class=\u0026#34;org.learn.demon01.service.UserService\u0026#34;\u0026gt; \u0026lt;!--注入userdao对象--\u0026gt; \u0026lt;property name=\u0026#34;userDao\u0026#34; ref=\u0026#34;userDaoImpl\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;bean id=\u0026#34;userDaoImpl\u0026#34; class=\u0026#34;org.learn.demon01.dao.UserDaoimpl\u0026#34;\u0026gt;\u0026lt;/bean\u0026gt; 注入属性-内部bean # 一对多关系：部门和员工\n一个部门有多个员工，一个员工属于一个部门，部门是一，员工是多\n在实体类之间表示一对多关系，员工表示所属部门，使用对象类型属性进行表示\npublic class Emp { private String ename; private String gender; private Dept dept; public void setDept(Dept dept) { this.dept = dept; } public void setGender(String gender) { this.gender = gender; } public void setEname(String ename) { this.ename = ename; } } 在spirng配置文件中进行配置\n\u0026lt;bean id=\u0026#34;emp\u0026#34; class=\u0026#34;org.learn.demon01.bean.Emp\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;ename\u0026#34; value=\u0026#34;empname\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;gender\u0026#34; value=\u0026#34;nan\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;dept\u0026#34;\u0026gt; \u0026lt;!--内部bean创建对象--\u0026gt; \u0026lt;bean id=\u0026#34;dept\u0026#34; class=\u0026#34;org.learn.demon01.bean.Dept\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;dname\u0026#34; value=\u0026#34;deptname\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; 注入属性-级联赋值 # 外部bean写法，在外部bean里赋值\n外部bean创建对象，内部属性赋值\n\u0026lt;bean id=\u0026#34;emp\u0026#34; class=\u0026#34;org.learn.demon01.bean.Emp\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;ename\u0026#34; value=\u0026#34;empname\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;gender\u0026#34; value=\u0026#34;nan\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;dept\u0026#34; ref=\u0026#34;dept\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;!--获取对象属性值需要设置get方法--\u0026gt; \u0026lt;property name=\u0026#34;dept.dname\u0026#34; value=\u0026#34;dept\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;bean id=\u0026#34;dept\u0026#34; class=\u0026#34;org.learn.demon01.bean.Dept\u0026#34;\u0026gt;\u0026lt;/bean\u0026gt; xml注入集合属性 # 注入数组类型属性 注入List集合类型属性 注入Map集合类型属性 创建类，传入数组，集合对象\npublic class Stu { private String[] courses; private List\u0026lt;String\u0026gt; list; private Map\u0026lt;String,String\u0026gt; maps; private Set\u0026lt;String\u0026gt; sets; public void setSets(Set\u0026lt;String\u0026gt; sets) { this.sets = sets; } public void setList(List\u0026lt;String\u0026gt; list) { this.list = list; } public void setMaps(Map\u0026lt;String, String\u0026gt; maps) { this.maps = maps; } public void setCourses(String[] courses) { this.courses = courses; } } 在spring配置文件中进行配置\n\u0026lt;bean id=\u0026#34;stu\u0026#34; class=\u0026#34;org.learn.collectiontype.Stu\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;courses\u0026#34;\u0026gt; \u0026lt;!--数组形式注入--\u0026gt; \u0026lt;array\u0026gt; \u0026lt;value\u0026gt;JAVA课程\u0026lt;/value\u0026gt; \u0026lt;value\u0026gt;数据库课程\u0026lt;/value\u0026gt; \u0026lt;/array\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;list\u0026#34;\u0026gt; \u0026lt;!--列表形式注入--\u0026gt; \u0026lt;list\u0026gt; \u0026lt;value\u0026gt;张三\u0026lt;/value\u0026gt; \u0026lt;value\u0026gt;李四\u0026lt;/value\u0026gt; \u0026lt;/list\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;maps\u0026#34;\u0026gt; \u0026lt;!--map形式注入--\u0026gt; \u0026lt;map\u0026gt; \u0026lt;entry key=\u0026#34;JAVA\u0026#34; value=\u0026#34;java\u0026#34;\u0026gt;\u0026lt;/entry\u0026gt; \u0026lt;entry key=\u0026#34;PHP\u0026#34; value=\u0026#34;php\u0026#34;\u0026gt;\u0026lt;/entry\u0026gt; \u0026lt;/map\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;sets\u0026#34;\u0026gt; \u0026lt;!--集合形式注入--\u0026gt; \u0026lt;set\u0026gt; \u0026lt;value\u0026gt;MySql\u0026lt;/value\u0026gt; \u0026lt;value\u0026gt;Redis\u0026lt;/value\u0026gt; \u0026lt;/set\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; 在集合里面设置对象类型值 # 设置类\nprivate List\u0026lt;Course\u0026gt; courseList; public void setCourseList(List\u0026lt;Course\u0026gt; courseList) { this.courseList = courseList; } 在spring中配置对象集合\n\u0026lt;bean id=\u0026#34;stu\u0026#34; class=\u0026#34;org.learn.collectiontype.Stu\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;courseList\u0026#34;\u0026gt; \u0026lt;!--注入List对象--\u0026gt; \u0026lt;list\u0026gt; \u0026lt;ref bean=\u0026#34;couse1\u0026#34;\u0026gt;\u0026lt;/ref\u0026gt; \u0026lt;ref bean=\u0026#34;couse2\u0026#34;\u0026gt;\u0026lt;/ref\u0026gt; \u0026lt;/list\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;bean id=\u0026#34;couse1\u0026#34; class=\u0026#34;org.learn.collectiontype.Course\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;cname\u0026#34; value=\u0026#34;spring框架5\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;bean id=\u0026#34;couse2\u0026#34; class=\u0026#34;org.learn.collectiontype.Course\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;cname\u0026#34; value=\u0026#34;框架\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; 集合注入部分提取 # 在spring配置文件中引入名称空间util(IDEA写util标签可以自动引入头部配置) \u0026lt;beans xmlns=\u0026#34;http://www.springframework.org/schema/beans\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xmlns:util=\u0026#34;http://www.springframework.org/schema/util\u0026#34; xsi:schemaLocation=\u0026#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd\u0026#34;\u0026gt; 使用util标签完成list集合注入提取 \u0026lt;!--提取list集合类型属性注入--\u0026gt; \u0026lt;util:list id=\u0026#34;bookList\u0026#34;\u0026gt; \u0026lt;value\u0026gt;JAVA\u0026lt;/value\u0026gt; \u0026lt;value\u0026gt;C\u0026lt;/value\u0026gt; \u0026lt;value\u0026gt;JS\u0026lt;/value\u0026gt; \u0026lt;/util:list\u0026gt; \u0026lt;!--提取list集合类型属性使用--\u0026gt; \u0026lt;bean id=\u0026#34;book\u0026#34; class=\u0026#34;org.learn.collectiontype.Book\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;list\u0026#34; ref=\u0026#34;bookList\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; Bean # 类型分类及介绍 # Spring有两种bean，一种普通bean,另外一种工厂bean(FactoryBean)\n普通bean 在spring配置文件中，bean定义什么类型就返回什么类型\n工厂bean 在配置文件定义bean类型可以和返回类型不一样\n第一步：创建类，让这个类作为工厂bean，实现接口FactoryBean\n第二步：实现接口里面的方法，在实现的方法中定义返回的bean类型\npublic class MyBean implements FactoryBean\u0026lt;Course\u0026gt;{ //定义返回bean @Override public Course getObject() throws Exception { Course course = new Course(); course.setCname(\u0026#34;abc\u0026#34;); return course; } @Override public Class\u0026lt;?\u0026gt; getObjectType() { return null; } @Override public boolean isSingleton() { return FactoryBean.super.isSingleton(); } } bean的作用域 # 在spring里面，默认情况下，bean是单实例对象 # 验证方法：把一个对象获取多次，然后输出，输出之后比较地址，观察地址是否相同\n@Test public void testT2(){ ApplicationContext context = new ClassPathXmlApplicationContext(\u0026#34;bean2.xml\u0026#34;); Book book1 = context.getBean(\u0026#34;book\u0026#34;, Book.class); Book book2 = context.getBean(\u0026#34;book\u0026#34;, Book.class); System.out.println(book1); System.out.println(book2); } 设置bean为单实例或多实例 # 在spring配置文件里面有一个属性（scope）用于设置单实例还是多实例\nscope属性值：\n第一个值：默认值singleton，表示是单实例对象\n第二个值：prototype，表示是多实例对象\n\u0026lt;bean id=\u0026#34;book\u0026#34; class=\u0026#34;org.learn.collectiontype.Book\u0026#34; scope=\u0026#34;prototype\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;list\u0026#34; ref=\u0026#34;bookList\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; singleton和prototype区别\n第一：singleton单实例，prototype多实例\n第二：设置scope值是singleton时候，加载spring配置文件时候就会创建单实例对象\n​\t设置scope值是prototype时候，不是在加载spring配置文件时候创建对象，在调用getBean方法时候创建多实例对象\nscope还有两个属性是request和session，表示向浏览器发送一次请求或者一次会话\nbean的生命周期 # 生命周期：从对象创建到对象销毁的过程\n通过构造器创建bean实例（无参数构造） 为bean的属性设置值和对其他bean的引用（调用set方法） 把bean实例传递bean后置处理器的方法（配置后置处理器生效） 调用bean的初始化的方法 把bean实例传递bean后置处理器的方法（配置后置处理器生效） bean可以使用（成功获取对象） 当容器关闭的时候，调用bean的销毁的方法（配置销毁的方法） bean生命周期5步示例代码（配置后置处理器为7步）\n主类：\npublic class Orders { private String oname; public Orders() { System.out.println(\u0026#34;第1步构造器创建bean实例\u0026#34;); } public void setOname(String oname) { this.oname = oname; System.out.println(\u0026#34;第2步调用set方法\u0026#34;); } public void initMethod(){ System.out.println(\u0026#34;第3步调用bean初始化方法\u0026#34;); } public void destoryMethod(){ System.out.println(\u0026#34;第5步调用bean销毁方法\u0026#34;); } } 后置处理器继承类（可不配置）：\npublic class MyBeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(\u0026#34;初始化之前运行的方法\u0026#34;); return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(\u0026#34;初始化之后运行的方法\u0026#34;); return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName); } } 测试类：\n@Test public void test4(){ //ClassPathXmlApplicationContext有close方法，applicationContext里没有销毁方法 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(\u0026#34;bean4.xml\u0026#34;); Orders orders = context.getBean(\u0026#34;orders\u0026#34;, Orders.class); System.out.println(\u0026#34;第4步获取bean对象\u0026#34;+orders); //第5步手动配置bean销毁 context.close(); } spring配置文件：\n\u0026lt;!--手动配置初始化和销毁bean方法--\u0026gt; \u0026lt;bean id=\u0026#34;orders\u0026#34; class=\u0026#34;org.learn.collectiontype.bean.Orders\u0026#34; init-method=\u0026#34;initMethod\u0026#34; destroy-method=\u0026#34;destoryMethod\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;oname\u0026#34; value=\u0026#34;JAVA\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; \u0026lt;!--后置处理器配置，配置之后任何bean实例都会自动调用（可不配置）--\u0026gt; \u0026lt;bean id=\u0026#34;myBeanPost\u0026#34; class=\u0026#34;org.learn.collectiontype.bean.MyBeanPost\u0026#34;\u0026gt;\u0026lt;/bean\u0026gt; 五步运行结果截图示例：\n配置后置处理器，七步运行结果截图示例：\nxml自动装配 # 什么是自动装配 # 根据指定装配规则（属性名称或者属性类型），spring自动将匹配的属性值进行注入\n自动装配过程 # bean标签属性autowire，配置自动装配\nautowire属性两个常用值\nbyName:根据属性名称注入，注入值bean的id值和类属性名称一样\nbyType:根据属性类型注入(用bean创建多个相同类型的对象时该属性会报错)\n\u0026lt;bean id=\u0026#34;emp\u0026#34; class=\u0026#34;org.learn.collectiontype.autowire.Emp\u0026#34; autowire=\u0026#34;byName\u0026#34;\u0026gt;\u0026lt;/bean\u0026gt; \u0026lt;bean id=\u0026#34;dept\u0026#34; class=\u0026#34;org.learn.collectiontype.autowire.Dept\u0026#34;\u0026gt;\u0026lt;/bean\u0026gt; 外部属性文件 # 直接配置数据库信息 # 引入druid连接池依赖 \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;com.alibaba\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;druid\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.1.9\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;mysql\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mysql-connector-java\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;8.0.24\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 配置druid连接池 \u0026lt;bean id=\u0026#34;dataSource\u0026#34; class=\u0026#34;com.alibaba.druid.pool.DruidDataSource\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;driverClassName\u0026#34; value=\u0026#34;com.mysql.cj.jdbc.Driver\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;url\u0026#34; value=\u0026#34;jdbc:mysql://localhost:3306/userDb\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;username\u0026#34; value=\u0026#34;root\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;password\u0026#34; value=\u0026#34;Tmh010625\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; 引入外部属性文件配置数据库连接池 # 创建外部属性文件，properties格式文件，写数据库信息 prop.driverClass=com.mysql.cj.jdbc.Driver prop.url=jdbc:mysql://localhost:3306/userDb prop.userName=root prop.password=Tmh010625 把外部properties属性文件引入到spring配置文件中（使用context需要配置xml头文件） \u0026lt;!--使用IDEA写context：属性即可直接导入--\u0026gt; \u0026lt;!--xml头文件配置--\u0026gt; \u0026lt;beans xmlns=\u0026#34;http://www.springframework.org/schema/beans\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xmlns:context=\u0026#34;http://www.springframework.org/schema/context\u0026#34; xsi:schemaLocation=\u0026#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd\u0026#34;\u0026gt; \u0026lt;!--具体配置--\u0026gt; \u0026lt;context:property-placeholder location=\u0026#34;classpath:jdbc.properties\u0026#34;/\u0026gt; \u0026lt;bean id=\u0026#34;dataSource\u0026#34; class=\u0026#34;com.alibaba.druid.pool.DruidDataSource\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;driverClassName\u0026#34; value=\u0026#34;${prop.driverClass}\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;url\u0026#34; value=\u0026#34;${prop.url}\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;username\u0026#34; value=\u0026#34;${prop.userName}\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;password\u0026#34; value=\u0026#34;${prop.password}\u0026#34;\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/bean\u0026gt; IOC操作bean管理：注解方式 # 注解概念 # 注解是代码特殊标记。格式：@注解名称（属性名称=属性值，属性名称=属性值\u0026hellip;\u0026hellip;） 使用注解，注解可以作用在类上面，方法上面，属性上面 使用注解目的：简化xml配置，把配置用更优雅更简洁的方式实现 spring针对bean管理创建对象提供的注解 # @Component @Service @Controller @Repository 上面四个注解功能是一样的，都可以用来创建bean实例\n基于注解方式实现对象创建 # 引入依赖(或者导入aop的jar包) # \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-aop\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;5.3.8\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 开启组件扫描 # 引入context标签 # 见一、-\u0026gt;五、-\u0026gt;2.-\u0026gt;2.具体context配置\n扫描多个包 # 多个包使用逗号隔开 \u0026lt;context:component-scan base-package=\u0026#34;org.learn.demon.dao,org.learn.demon.service\u0026#34;\u0026gt;\u0026lt;/context:component-scan\u0026gt; 直接扫描上层目录 \u0026lt;context:component-scan base-package=\u0026#34;org.learn\u0026#34;\u0026gt;\u0026lt;/context:component-scan\u0026gt; 创建类，在类上面添加创建对象注解 # @Component(value = \u0026#34;userService\u0026#34;) public class UserService { public void add(){ System.out.println(\u0026#34;service add.....\u0026#34;); } } vlaue的值和id的值是等价的 在注解里value属性值可以省略不写，默认是类名称，首字母小写 开启组件扫描里的细节配置 # include-filter # \u0026lt;context:component-scan base-package=\u0026#34;org.learn\u0026#34; use-default-filters=\u0026#34;false\u0026#34;\u0026gt; \u0026lt;context:include-filter type=\u0026#34;annotation\u0026#34; expression=\u0026#34;org.springframework.stereotype.Component\u0026#34;/\u0026gt; \u0026lt;/context:component-scan\u0026gt; use-default-filters=\u0026ldquo;false\u0026rdquo;：不使用系统默认的filter扫描组件\ncontext:include-filter：包含后面expression表达式内容的组件会被扫描\nexclude-filter # \u0026lt;context:component-scan base-package=\u0026#34;org.learn\u0026#34;\u0026gt; \u0026lt;context:exclude-filter type=\u0026#34;annotation\u0026#34; expression=\u0026#34;org.springframework.stereotype.Component\u0026#34;/\u0026gt; \u0026lt;/context:component-scan\u0026gt; context:exclude-filter：包含后面expression表达式内容的组件不会被扫描\n基于注解方式实现属性注入 # @Autowired # 根据属性类型进行自动装配\n第一步 # 把service和dao对象创建，在service和dao类添加创建对象注解\n@Repository public class UserDaoImpl1 implements UserDao{ @Override public void add() { System.out.println(\u0026#34;dao add......\u0026#34;); } } 第二步 # 在service注入dao对象，在service类添加dao类型属性，在属性上面使用注解\n@Service public class UserService { @Autowired private UserDao userDao; public void add(){ userDao.add(); System.out.println(\u0026#34;service add.....\u0026#34;); } } 定义dao类型属性，不需要添加set方法\n@Qualifier # 根据属性名称进行注入（和@Autowired注解一起使用）\n@Autowired @Qualifier(value = \u0026#34;userDaoImpl1\u0026#34;) private UserDao userDao; 当一个接口有多个实现类时，@Autowired就无法知道是哪个实现类，需要@Qualifier根据名称来具体定位\n@Resource # 可以根据类型注入，也可以根据名称注入\n//@Resource//根据类型进行注入 @Resource(name = \u0026#34;userDaoImpl1\u0026#34;)//根据名称进行注入 private UserDao userDao; @Resource是javax提供的，并不是由spring提供的，因此更建议用@Autowired和@Qualifier\n@Value # 注入普通类型属性\n@Value(value = \u0026#34;abc\u0026#34;) private String name; 完全注解开发 # 这一部分一般使用springboot开发\n创建配置类，替代xml配置文件 # @Configuration @ComponentScan(basePackages = {\u0026#34;org.learn\u0026#34;}) public class SpringConfig{ } @Configuration 作为配置类，替代xml配置文件\n@ComponentScan(basePackages = {\u0026ldquo;扫描包路径\u0026rdquo;}) 替代xml配置文件中context:component-scan\n编写测试类 # @Test public void test2(){ ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean(\u0026#34;userService\u0026#34;, UserService.class); System.out.println(userService); userService.add(); } 实例化bean对象时使用AnnotationConfigApplicationContext替代以前xml文件接口实现\nAOP # 基本概念 # AOP为Aspect Oriented Programming的缩写，意为：面向切面编程，通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。 利用AOP可以对业务逻辑的各个部分进行隔离，从而使得业务逻辑各部分之间的耦合度降低，提高程序的可重用性，同时提高了开发的效率。 通俗描述：不通过修改源代码方式，在主干功能里添加新功能 使用登录流程展示AOP概念\nAOP底层原理 # AOP底层使用动态代理 # 动态代理两种情况 # 有接口情况：使用JDK动态代理 创建接口实现类代理对象，增强类的方法\n无接口情况：使用CGLIB动态代理 创建子类的代理对象，增强类的方法\nJDK动态代理实现 # 调用newProxyInstance方法 # static Object newProxyInstance(ClassLoader loader,Class\u0026lt;?\u0026gt;[] interface,InvocationHandler h); 方法所在位置java.lang.reflect.Proxy 第一个参数，类加载器 第二个参数，增强方法所在的类，这个类实现的接口，支持多个接口 第三个参数，实现这个接口InvocationHandler，创建代理对象，写增强的方法 动态代码实例展示 # 主类 public class JDKProxy { public static void main(String[] args) { UserDaoImpl dao = new UserDaoImpl(); Class[] interfaces = {UserDao.class}; UserDao res = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(dao)); int add = res.add(1, 2); String s = res.update(\u0026#34;名字\u0026#34;); System.out.println(add); System.out.println(s); } } class UserDaoProxy implements InvocationHandler{ private Object obj; public UserDaoProxy(Object obj){ this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(\u0026#34;方法之前执行：：\u0026#34;+method.getName()+\u0026#34;传递的参数\u0026#34;+ Arrays.toString(args)); Object res = method.invoke(obj, args); System.out.println(\u0026#34;方法之后执行：：\u0026#34;+obj); return res; } } 被代理类 public class UserDaoImpl implements UserDao{ @Override public int add(int a, int b) { System.out.println(\u0026#34;add方法执行了\u0026#34;); return a+b; } @Override public String update(String id) { System.out.println(\u0026#34;update方法执行了\u0026#34;); return id; } } AOP操作 # AOP术语 # 连接点 类里面可以增强的方法，这些方法称为连接点\n切入点 实际被真正增强的方法，称为切入点\n通知（增强）\n实际增强的逻辑部分称为通知（增强）\n通知类型分类\n前置通知 后置通知 环绕通知 异常通知 最终通知 切面（动作） 把通知应用到切入点过程\n准备工作 # Spring框架一般都是基于AspectJ实现AOP操作 # 什么是AspectJ # AspectJ不是Spring组成部分，独立AOP框架，一般把AspectJ和Spring框架一起使用，进行AOP操作\n基于AspectJ实现AOP操作 # 基于xml配置文件实现\n基于注解方式实现（使用）\n在项目工程引入AOP相关依赖\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;cglib\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;cglib\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;3.0\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;aopalliance\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;aopalliance\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.0\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.aspectj\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;aspectjweaver\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.9.6\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 切入点表达式\n切入点表达式作用\n知道对哪个类里面的哪个方法进行增强\n2. 语法结构 execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))\n","date":"2025-01-14","externalUrl":null,"permalink":"/docs/spring/","section":"文章","summary":"IOC # 基本概念 # 控制反转（Inversion of Control，缩写为IoC），面向对象编程的一种设计原则，可以用来减低计算机代码之间的耦合度。最常见的方式叫做依赖注入（Dependency Injection，简称DI），还有一种方式叫依赖查找（Dependency Lookup）。 通过控制反转，对象在被创建的时候，由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说，依赖被注入到对象中。 IOC思想基于IOC容器完成，IOC容器底层就是对象工厂 Spring提供IOC容器实现两种方式 # BeanFactory：IOC容器基本实现，是spring内部的使用接口，不提供开发人员进行使用（加载配置文件的时候不会创建对象，在获取对象才去创建对象）\n","title":"Spring学习","type":"docs"},{"content":" download picgo program https://github.com/Molunerfinn/PicGo open github personal page, choose settings and open develper settings, create a new classic token and check the repo box, then generate and copy the token set up the picgo program, choose github as the storage service, paste the token, choose the repo and the branch, then save ","date":"2025-01-14","externalUrl":null,"permalink":"/docs/picbed/","section":"文章","summary":" download picgo program https://github.com/Molunerfinn/PicGo open github personal page, choose settings and open develper settings, create a new classic token and check the repo box, then generate and copy the token set up the picgo program, choose github as the storage service, paste the token, choose the repo and the branch, then save ","title":"图床搭建","type":"docs"},{"content":"","date":"2024-01-28","externalUrl":null,"permalink":"/tags/%E7%AE%97%E6%B3%95/","section":"标签","summary":"","title":"算法","type":"tags"},{"content":" 高精度 # 加法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序) int a[N],b[N],c[N];//1~N,0号位存储数组长度 void g_add(int* A,int* B,int* C){ C[0] = 1;//数组长度,从第一位开始 int t = 0;//保存进位和结果信息 for(int i = A[0],j = B[0];i \u0026gt; 0 || j \u0026gt; 0;--i,--j,++C[0]){ t += i \u0026gt; 0 ? A[i] : 0; t += j \u0026gt; 0 ? B[j] : 0; C[C[0]] = t % 10; t /= 10; } C[C[0]] = t ? t : C[--C[0]];//如果最高位进位,则将进位信息保存,否则长度-1(循环导致长度+1) } 减法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序),f:确定正负 int a[N],b[N],c[N],f;//1~N,0号位存储数组长度 int g_cmp(int* A,int* B){//A\u0026gt;=B返回1,否则返回0 if(A[0] != B[0]) return A[0] \u0026gt; B[0]; for(int i = 1;i \u0026lt;= A[0];++i) if(A[i] != B[i]) return A[i] \u0026gt; B[i]; return 1; } void g_sub(int* A,int* B,int* C){ C[0] = 1; int t = 0;//存储借位和结果信息 for(int i = A[0],j = B[0];i \u0026gt; 0 || j \u0026gt; 0;--i,--j,++C[0]){ t = i \u0026gt; 0 ? A[i] - t : t; t -= j \u0026gt; 0 ? B[j] : 0; C[C[0]] = (t + 10) % 10; t = t \u0026lt; 0 ? 1 : 0; } while(C[0] \u0026gt; 1 \u0026amp;\u0026amp; !C[--C[0]]);//删除前导0 } int main(){ ~~~ if((f = g_cmp(a,b))) g_sub(a,b,c); else g_sub(b,a,c); cout \u0026lt;\u0026lt; (f ? \u0026#34;\u0026#34; : \u0026#34;-\u0026#34;); ~~~ return 0; } 乘法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序) int a[N],b[N],c[2*N];//1~N,0号位存储数组长度 void g_mul(int* A,int* B,int* C){ C[0] = A[0] + B[0];//长度多一位,方便判断结果为0的情况 for(int i = A[0];i \u0026gt; 0;--i) for(int j = B[0];j \u0026gt; 0;--j) C[C[0]-i-j+1] += A[i] * B[j];//逆序放置结果 for(int i = 1;i \u0026lt; C[0]-1;++i){//处理每一位进位 C[i+1] += C[i] / 10; C[i] %= 10; } while(C[0] \u0026gt; 1 \u0026amp;\u0026amp; !C[--C[0]]);//结果为0时删除多余0 } 除法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序),r:存储余数(正序) int a[N],b[N],c[N],r[N];//1~N,0号位存储数组长度 void g_div(int* A,int* B,int* C,int* R){ if(!g_cmp(A,B)) {//如果B比A大，则直接商0,余数就是A C[0] = 1; for(int i = 0;i \u0026lt;= A[i];++i) R[i] = A[i]; return; } int T[A[0]+1] = {0};//商的结果 C[0] = A[0] + 1;//商的位数预处理和被除数相同 for(int i = A[0];i \u0026gt; 0;--i){ T[++T[0]] = A[A[0]-i+1]; while(g_cmp(T,B)){ ++C[i]; g_sub(T,B,R); if(!R[R[0]==1]) T[0] = 0; else{ for(int j = R[0];j \u0026gt; 0;--j) T[R[0]-j+1] = R[j]; T[0] = R[0]; } } while(T[1] == 0 \u0026amp;\u0026amp; T[0] \u0026gt; 0) --T[0]; } while(C[0] \u0026gt; 1 \u0026amp;\u0026amp; !C[--C[0]]); for(int i = 0;i \u0026lt;= T[0];++i) R[i] = T[i]; if(T[0] == 0) R[0]= 1; } 数学 # 质数筛法 # //p:存储质数,idx:p的指针,vis:存储当前元素是否被访问 int p[N],idx,vis[N]; void get_primes(int x){ for(int i = 2;i \u0026lt;= x;++i){ if(!vis[i]) p[idx++] = i; for(int j = 0;p[j] \u0026lt;= x/i;++j){ vis[p[j]*i] = 1; if(i % p[j] == 0) break; } } } 高斯消元 # const double eps = 1e-6;//精度判断(是否为0) double a[N][N];//存储方程组矩阵 int gauss(){ int r,c;//行,列 for(c = 0,r = 0;c \u0026lt; n;++c){//系数矩阵第一列开始，遍历到最后一列 int t = r;//记录当前列绝对值最大值所在行 for(int i = r;i \u0026lt; n;++i) if(fabs(a[i][c]) \u0026gt; fabs(a[t][c])) t = i; if(fabs(a[t][c]) \u0026lt; eps) continue;//如果当前为0,则直接进入下一列,利用eps防止c++小数精度问题 for(int i = c;i \u0026lt;= n;++i) swap(a[t][i],a[r][i]);//交换当前行与当前列最大值所在的行 for(int i = n;i \u0026gt;= c;--i) a[r][i] /= a[r][c];//当前行当前列元素置为1,当前行其余元素也要更新,防止影响当前元素,逆序遍历 for(int i = r+1;i \u0026lt; n;++i)//从下一行开始,更新当前列的下面所有行的值为0,更新当前行下面的所有行 if(fabs(a[i][c]) \u0026gt; eps)//当前元素不是0 for(int j = n;j \u0026gt;= c;--j)//逆序计算 a[i][j] -= a[r][j] * a[i][c]; ++r;//如果当前行列不为0,则计算到这里,行数加一,否则就是当前行的下一列开始计算 } if(r \u0026lt; n){//矩阵不满秩 for(int i = r;i \u0026lt; n;++i)//判断是否存在系数为0,常s if(fabs(a[i][n]) \u0026gt; eps) return 2;//无解 return 1;//无穷多解 } for(int i = n-1;i \u0026gt;= 0;--i)//最后一行开始 for(int j = i+1;j \u0026lt; n;++j)//当前行所在对角线的后面所有列 a[i][n] -= a[i][j] * a[j][n];//存储最后结果(当前行其他列全部消为0) return 0;//唯一解 } //使用方式 int t = gauss(); if(t == 0) for(int i = 0;i \u0026lt; n;++i) cout \u0026lt;\u0026lt; fixed \u0026lt;\u0026lt; setprecision(2) \u0026lt;\u0026lt; (fabs(a[i][n]) \u0026lt; eps ? 0 : a[i][n]) \u0026lt;\u0026lt; endl;//防止输出-0.00 else if(t == 1) cout \u0026lt;\u0026lt; \u0026#34;无穷多解\u0026#34; \u0026lt;\u0026lt; endl; else cout \u0026lt;\u0026lt; \u0026#34;无解\u0026#34; \u0026lt;\u0026lt; endl; 快速幂 # int qmi(int a,int k,int p){ int ret = 1; while(k){ if(k \u0026amp; 1) ret = (LL) ret * a % p; a = (LL) a * a % p; k \u0026gt;\u0026gt;= 1; } return ret; } 最大公约数 # int gcd(int x,int y){ return y ? gcd(y,x%y) : x; } 二分查找 # // 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用： int bsearch_1(int l, int r) { while (l \u0026lt; r) { int mid = l + r \u0026gt;\u0026gt; 1; if (check(mid)) r = mid;//最左边的结果 else l = mid + 1; } return l; } // 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用： int bsearch_2(int l, int r) { while (l \u0026lt; r) { int mid = l + r + 1 \u0026gt;\u0026gt; 1; if (check(mid)) l = mid;//最右边的结果 else r = mid - 1; } return l; } 字符串 # 读取整行字符 # //如果读取该行前有读取其他字符或者换行，则需要多加一个getline(cin,s);读取上一行遗留的换行符 getline(cin,s);//会读取一整行包括空格和换行符，但是会自动删去换行符 分割字符串 # //构造原始字符串s的字符串流 stringstream ssin(s); //以delim作为分割符,分割后的字符串存储到t中 string t; while(getline(ssin,t,\u0026#39;delim\u0026#39;)){...} 图 # 基本操作 # int h[N],e[N],ne[N],idx; void add(int a,int b){//a-\u0026gt;b e[idx] = b;ne[idx] = h[a];h[a] = idx++; } memset(h,-1,sizeof h);//初始化头节点为-1 for(int i = h[a];~i;i = ne[i]){...}//遍历邻接表 边多就用for循环，邻接矩阵存储。边少就用堆优化，连接表存储。\ndijkstra # int dis[N],vis[N],h[N],ne[2*N],e[2*N],w[2*N],idx; void add(int a,int b,int c){//a-\u0026gt;b,权重为c e[idx] = b;ne[idx] = h[a];w[idx] = c;h[a] = idx++; } void dijkstra(int u){//计算从u出发，到其他顶点的最短距离 memset(dis,0x3f,sizeof dis);//dis[i]表示u到i的最短距离 dis[u] = 0; priority_queue\u0026lt;PII,vector\u0026lt;PII\u0026gt;,greater\u0026lt;PII\u0026gt;\u0026gt; heap; heap.push({0,u}); vis[u] = 1; while(!heap.empty()){ auto cur = heap.top().second,len = heap.top().first; heap.pop(); if(vis[cur]) continue; vis[cur] = 1; for(int i = h[cur];~i;i = ne[i]){ int j = e[i]; if(dis[j] \u0026gt; len + w[i]){ dis[j] = len + w[i]; heap.push({dis[j],j}); } } } } floyd # int g[N][N];//g[i][j]存储的是原始数组,同时也是最终结果数组,i-\u0026gt;j的最短距离 void floyd(int g[][N]){ for(int k = 1;k \u0026lt;= n;++k){ for(int i = 1;i \u0026lt;= n;++i){ for(int j = 1;j \u0026lt;= n;++j){ g[i][j] = min(g[i][j],g[i][k] + g[k][j]); } } } } kruskal # int n,m,p[N];//p[]并查集数组 struct Edge{ int a,b,w;//a和b之间的无向边,权重为w bool operator\u0026lt; (const Edge \u0026amp;e) const{ return w \u0026lt; e.w; } }edges[M]; int find(int x){ return x != p[x] ? p[x] = find(p[x]) : p[x]; } int kruskal(){//返回最小生成树的权重之和 sort(edges,edges + m);//从权重最小的边开始 for(int i = 1;i \u0026lt;= n;++i) p[i] = i; int ret = 0,cnt = 0;//ret存储结果,cnt存储构成树的边的数量 for(int i = 0;i \u0026lt; m;++i){ int a = edges[i].a,b = edges[i].b,w = edges[i].w; a = find(a),b = find(b); if(a != b){//如果a,b所在连通块不连通 p[a] = b;ret += w;++cnt;//将a,b连通,权重累加,树边+1 } }//最小生成树为顶点数-1,判断是否构成最小生成树 if(cnt \u0026lt; n - 1) return INF; return ret; } prim # int prim(){ memset(dis,0x3f,sizeof dis); int ret = 0; for(int i = 0;i \u0026lt; n;++i){ int t = -1; for(int j = 1;j \u0026lt;= n;++j) if(!vis[j] \u0026amp;\u0026amp; (t == -1 || dis[t] \u0026gt; dis[j])) t = j; if(i \u0026amp;\u0026amp; dis[t] == INF) return INF; if(i) ret += dis[t]; vis[t] = 1; for(int j = 1;j \u0026lt;= n;++j) dis[j] = min(dis[j],g[t][j]); } return ret; } 树状数组 # int tr[N];//从1开始输入 memset(tr,0,sizeof tr);//开始全部置为0 int lowbit(int x){//求x二进制末尾有几个0 return x \u0026amp; -x; } void add(int j,int x){//第j个位置加上x for(int i = j;i \u0026lt;= n;i += lowbit(i)) tr[i] += x; } int query(int j){//查询1~j区间的和 int ret = 0; for(int i = j;i;i -= lowbit(i)) ret += tr[i]; return ret; } for(int i = 1;i \u0026lt;= n;++i) add(i,a[i]);//初始化树状数组,a[i]为原数组 query(l)-query(r-1)//查询l~r区间的和 线段树 # struct node{ int l,r; int sum;//可以替换为其他需要求得条件 }tr[4*N]; void pushup(int u){//回溯时进行的操作 tr[u].sum = tr[u \u0026lt;\u0026lt; 1].sum + tr[u \u0026lt;\u0026lt; 1 | 1].sum; } void build(int u,int l,int r){//建树 if(l == r) tr[u] = {l,r,a[u]};//到达叶子节点 else{ tr[u] = {l,r,0};//初始化当前节点 int mid = (l + r) \u0026gt;\u0026gt; 1; build(u \u0026lt;\u0026lt; 1, l, mid),build(u \u0026lt;\u0026lt; 1 | 1, mid+1, r); pushup(u);//从叶子节点回溯到根节点，更新需要的值 } } void modify(int u,int j,int x){//将j上的值加上x if(tr[u].l == tr[u].r) tr[u].sum += x;//到达叶节点，先更新叶节点 else{ int mid = (tr[u].l + tr[u].r) \u0026gt;\u0026gt; 1; if(j \u0026lt;= mid) modify(u \u0026lt;\u0026lt; 1,j,x);//需要更新的节点在左边 if(j \u0026gt; mid) modify(u \u0026lt;\u0026lt; 1 | 1,j,x);//需要更新的节点在右边 pushup(u);//回溯时更新路径上的所有节点 } } int query(int u,int l,int r){ //查询的区间l,r包含了当前节点u的区间，则直接返回当前区间存储的值 if(tr[u].l \u0026gt;= l \u0026amp;\u0026amp; tr[u].r \u0026lt;= r) return tr[u].sum; int ret = 0,mid = (tr[u].l + tr[u].r) \u0026gt;\u0026gt; 1; if(l \u0026lt;= mid) ret += query(u \u0026lt;\u0026lt; 1,l,r);//左半区间需要查询 if(r \u0026gt; mid) ret += query(u \u0026lt;\u0026lt; 1 | 1,l,r);//右半区间需要查询 return ret; } 前缀和 # 一维 # a[N],s[N];//下标从1开始读入 s[i] = s[i-1] + a[i];//初始化 s[r] - s[l-1] //区间[l,r]的和 二维 # a[N][M],s[N][M];//下标从(1,1)开始读入 s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j];//初始化 //左上角(x1,y1)到右下角(x2,y2)的子矩阵和 s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1] 差分 # 一维 # a[N],b[N];//定 void insert(int l,int r,int c){//[l,r]区间内全部+c b[l] += c;b[r+1] -= c; } insert(i,i,a[i]);//初始化差分数组 for(int i = 1;i \u0026lt;= n;++i) b[i] += b[i-1];//恢复数组 二维 # a[N][M],b[N][M]; //左上角(x1,y1)到右下角(x2,y2)全部加上c void insert(int x1,int y1,int x2,int y2,int c){ b[x1][y1] += c; b[x1][y2+1] -= c; b[x2+1][y1] -= c; b[x2+1][y2+1] += c; } insert(i,j,i,j,a[i][j]);//初始化差分数组 b[i][j] += b[i-1][j] + b[i][j-1] - b[i-1][j-1];//恢复数组 KMP # c s[N]; cin \u0026gt;\u0026gt; s+1; //s[]原始串(长串),p[]模式串(短串),n是s的长度,m是p的长度 for (int i = 2, j = 0; i \u0026lt;= m; i ++){//求next数组 while (j \u0026amp;\u0026amp; p[i] != p[j + 1]) j = ne[j]; if (p[i] == p[j + 1]) j ++ ; ne[i] = j; } for (int i = 1, j = 0; i \u0026lt;= n; i ++ ){//匹配 while (j \u0026amp;\u0026amp; s[i] != p[j + 1]) j = ne[j]; if (s[i] == p[j + 1]) j ++ ; if (j == m) { j = ne[j]; // 匹配成功后的逻辑 } } STL # priority_queue # push(),pop(),top(),empty(),size(),emplace(),swap() queue # front(),pop(),push(),back(),empty(),size(),emplace(),swap() deque # pop_back(),pop_front(),push_back(),push_front(),empty(),size(),back(),front() at(),begin(),emplace(),emplace_back(),emplace_front(),end(),erase(),insert(),rbegin(),rend() map # insert(),find(),empty(),size(),clear(),count(),lower_bound(),upper_bound() begin(),emplace(),end(),erase(),equal_range(),rbegin(),rend() unordered_map # insert(),find(),empty(),size(),clear(),count() begin(),emplace(),end(),erase(),reserve(),swap(),rehash(),hash_function() set # insert(),find(),empty(),size(),clear(),count(),lower_bound(),upper_bound() begin(),emplace(),end(),erase(),equal_range(),rbegin(),rend() unordered_set # insert(),find(),empty(),size(),clear(),count() begin(),emplace(),end(),erase(),reserve(),swap(),rehash(),hash_function() stack # push(),pop(),top(),size(),empty(),emplace() Java # 快读快写模板 # import java.io.*; static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); static StreamTokenizer st = new StreamTokenizer(reader); static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));//写 public static void main( String[] args ) throws IOException { // TODO pw.flush(); } static int ri() throws IOException{//读int st.nextToken(); return (int) st.nval; } static String rs() throws IOException{//读S st.nextToken(); return st.sval; } 排序 # 快排 # static void qs(int[] a, int low, int high) { if(low \u0026gt;= high) return; int i = low - 1, j = high + 1, t = a[low + high \u0026gt;\u0026gt; 1]; while(i \u0026lt; j){ do i++; while (a[i] \u0026lt; t); do j--; while (a[j] \u0026gt; t); if(i \u0026lt; j) { int x = a[i]; a[i] = a[j]; a[j] = x; } } qs(a, low, j); qs(a ,j + 1, high); } ","date":"2024-01-28","externalUrl":null,"permalink":"/docs/algorithm/","section":"文章","summary":"高精度 # 加法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序) int a[N],b[N],c[N];//1~N,0号位存储数组长度 void g_add(int* A,int* B,int* C){ C[0] = 1;//数组长度,从第一位开始 int t = 0;//保存进位和结果信息 for(int i = A[0],j = B[0];i \u003e 0 || j \u003e 0;--i,--j,++C[0]){ t += i \u003e 0 ? A[i] : 0; t += j \u003e 0 ? B[j] : 0; C[C[0]] = t % 10; t /= 10; } C[C[0]] = t ? t : C[--C[0]];//如果最高位进位,则将进位信息保存,否则长度-1(循环导致长度+1) } 减法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序),f:确定正负 int a[N],b[N],c[N],f;//1~N,0号位存储数组长度 int g_cmp(int* A,int* B){//A\u003e=B返回1,否则返回0 if(A[0] != B[0]) return A[0] \u003e B[0]; for(int i = 1;i \u003c= A[0];++i) if(A[i] != B[i]) return A[i] \u003e B[i]; return 1; } void g_sub(int* A,int* B,int* C){ C[0] = 1; int t = 0;//存储借位和结果信息 for(int i = A[0],j = B[0];i \u003e 0 || j \u003e 0;--i,--j,++C[0]){ t = i \u003e 0 ? A[i] - t : t; t -= j \u003e 0 ? B[j] : 0; C[C[0]] = (t + 10) % 10; t = t \u003c 0 ? 1 : 0; } while(C[0] \u003e 1 \u0026\u0026 !C[--C[0]]);//删除前导0 } int main(){ ~~~ if((f = g_cmp(a,b))) g_sub(a,b,c); else g_sub(b,a,c); cout \u003c\u003c (f ? \"\" : \"-\"); ~~~ return 0; } 乘法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序) int a[N],b[N],c[2*N];//1~N,0号位存储数组长度 void g_mul(int* A,int* B,int* C){ C[0] = A[0] + B[0];//长度多一位,方便判断结果为0的情况 for(int i = A[0];i \u003e 0;--i) for(int j = B[0];j \u003e 0;--j) C[C[0]-i-j+1] += A[i] * B[j];//逆序放置结果 for(int i = 1;i \u003c C[0]-1;++i){//处理每一位进位 C[i+1] += C[i] / 10; C[i] %= 10; } while(C[0] \u003e 1 \u0026\u0026 !C[--C[0]]);//结果为0时删除多余0 } 除法 # //初始条件：a:存储第一个大数(正序),b:存储第二个大数(正序),c:存储结果(逆序),r:存储余数(正序) int a[N],b[N],c[N],r[N];//1~N,0号位存储数组长度 void g_div(int* A,int* B,int* C,int* R){ if(!g_cmp(A,B)) {//如果B比A大，则直接商0,余数就是A C[0] = 1; for(int i = 0;i \u003c= A[i];++i) R[i] = A[i]; return; } int T[A[0]+1] = {0};//商的结果 C[0] = A[0] + 1;//商的位数预处理和被除数相同 for(int i = A[0];i \u003e 0;--i){ T[++T[0]] = A[A[0]-i+1]; while(g_cmp(T,B)){ ++C[i]; g_sub(T,B,R); if(!R[R[0]==1]) T[0] = 0; else{ for(int j = R[0];j \u003e 0;--j) T[R[0]-j+1] = R[j]; T[0] = R[0]; } } while(T[1] == 0 \u0026\u0026 T[0] \u003e 0) --T[0]; } while(C[0] \u003e 1 \u0026\u0026 !C[--C[0]]); for(int i = 0;i \u003c= T[0];++i) R[i] = T[i]; if(T[0] == 0) R[0]= 1; } 数学 # 质数筛法 # //p:存储质数,idx:p的指针,vis:存储当前元素是否被访问 int p[N],idx,vis[N]; void get_primes(int x){ for(int i = 2;i \u003c= x;++i){ if(!vis[i]) p[idx++] = i; for(int j = 0;p[j] \u003c= x/i;++j){ vis[p[j]*i] = 1; if(i % p[j] == 0) break; } } } 高斯消元 # const double eps = 1e-6;//精度判断(是否为0) double a[N][N];//存储方程组矩阵 int gauss(){ int r,c;//行,列 for(c = 0,r = 0;c \u003c n;++c){//系数矩阵第一列开始，遍历到最后一列 int t = r;//记录当前列绝对值最大值所在行 for(int i = r;i \u003c n;++i) if(fabs(a[i][c]) \u003e fabs(a[t][c])) t = i; if(fabs(a[t][c]) \u003c eps) continue;//如果当前为0,则直接进入下一列,利用eps防止c++小数精度问题 for(int i = c;i \u003c= n;++i) swap(a[t][i],a[r][i]);//交换当前行与当前列最大值所在的行 for(int i = n;i \u003e= c;--i) a[r][i] /= a[r][c];//当前行当前列元素置为1,当前行其余元素也要更新,防止影响当前元素,逆序遍历 for(int i = r+1;i \u003c n;++i)//从下一行开始,更新当前列的下面所有行的值为0,更新当前行下面的所有行 if(fabs(a[i][c]) \u003e eps)//当前元素不是0 for(int j = n;j \u003e= c;--j)//逆序计算 a[i][j] -= a[r][j] * a[i][c]; ++r;//如果当前行列不为0,则计算到这里,行数加一,否则就是当前行的下一列开始计算 } if(r \u003c n){//矩阵不满秩 for(int i = r;i \u003c n;++i)//判断是否存在系数为0,常s if(fabs(a[i][n]) \u003e eps) return 2;//无解 return 1;//无穷多解 } for(int i = n-1;i \u003e= 0;--i)//最后一行开始 for(int j = i+1;j \u003c n;++j)//当前行所在对角线的后面所有列 a[i][n] -= a[i][j] * a[j][n];//存储最后结果(当前行其他列全部消为0) return 0;//唯一解 } //使用方式 int t = gauss(); if(t == 0) for(int i = 0;i \u003c n;++i) cout \u003c\u003c fixed \u003c\u003c setprecision(2) \u003c\u003c (fabs(a[i][n]) \u003c eps ? 0 : a[i][n]) \u003c\u003c endl;//防止输出-0.00 else if(t == 1) cout \u003c\u003c \"无穷多解\" \u003c\u003c endl; else cout \u003c\u003c \"无解\" \u003c\u003c endl; 快速幂 # int qmi(int a,int k,int p){ int ret = 1; while(k){ if(k \u0026 1) ret = (LL) ret * a % p; a = (LL) a * a % p; k \u003e\u003e= 1; } return ret; } 最大公约数 # int gcd(int x,int y){ return y ? gcd(y,x%y) : x; } 二分查找 # // 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用： int bsearch_1(int l, int r) { while (l \u003c r) { int mid = l + r \u003e\u003e 1; if (check(mid)) r = mid;//最左边的结果 else l = mid + 1; } return l; } // 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用： int bsearch_2(int l, int r) { while (l \u003c r) { int mid = l + r + 1 \u003e\u003e 1; if (check(mid)) l = mid;//最右边的结果 else r = mid - 1; } return l; } 字符串 # 读取整行字符 # //如果读取该行前有读取其他字符或者换行，则需要多加一个getline(cin,s);读取上一行遗留的换行符 getline(cin,s);//会读取一整行包括空格和换行符，但是会自动删去换行符 分割字符串 # //构造原始字符串s的字符串流 stringstream ssin(s); //以delim作为分割符,分割后的字符串存储到t中 string t; while(getline(ssin,t,'delim')){...} 图 # 基本操作 # int h[N],e[N],ne[N],idx; void add(int a,int b){//a-\u003eb e[idx] = b;ne[idx] = h[a];h[a] = idx++; } memset(h,-1,sizeof h);//初始化头节点为-1 for(int i = h[a];~i;i = ne[i]){...}//遍历邻接表 边多就用for循环，邻接矩阵存储。边少就用堆优化，连接表存储。\n","title":"算法模板","type":"docs"},{"content":"","date":"2024-01-28","externalUrl":null,"permalink":"/tags/oracle/","section":"标签","summary":"","title":"Oracle","type":"tags"},{"content":" 1、查看表中索引 # 显示索引名称，索引作用的列 select * from user_ind_columns where table_name=\u0026#39;表名\u0026#39;; 显示索引的具体信息（创建时间、类型、内存大小） select * from all_indexes where table_name=\u0026#39;表名\u0026#39;; 2、删除序列 # delete sequence 序列名; 3、查看存储过程/触发器编译错误信息 # select * from SYS.USER_ERRORS where NAME=upper(\u0026#39;出错的名称（触发器/存储过程m）\u0026#39;); 4、约束条件相关操作 # 查看表的约束条件 select * from user_constraints where table_name=\u0026#39;表名\u0026#39;; 删除约束条件 alter table 表名 drop constraint 约束条件名; 失效约束条件 alter table 表名 disable constraint 约束条件名; 生效约束条件 alter table 表名 enable constraint 约束条件名; 5、查看所有存储过程、触发器、视图、表 # select * From user_triggers; --所有触发器 select * From user_procedures; --所有存储过程 select * From user_views; --所有视图 select * From user_tables; --所有表 6、查看当前数据库连接的sid实例 # select instance_name from v$instance; 7、查看用户拥有的表空间 # select tablespace_name from user_tablespaces; ","date":"2024-01-28","externalUrl":null,"permalink":"/docs/oracle/","section":"文章","summary":"1、查看表中索引 # 显示索引名称，索引作用的列 select * from user_ind_columns where table_name='表名'; 显示索引的具体信息（创建时间、类型、内存大小） select * from all_indexes where table_name='表名'; 2、删除序列 # delete sequence 序列名; 3、查看存储过程/触发器编译错误信息 # select * from SYS.USER_ERRORS where NAME=upper('出错的名称（触发器/存储过程m）'); 4、约束条件相关操作 # 查看表的约束条件 select * from user_constraints where table_name='表名'; 删除约束条件 alter table 表名 drop constraint 约束条件名; 失效约束条件 alter table 表名 disable constraint 约束条件名; 生效约束条件 alter table 表名 enable constraint 约束条件名; 5、查看所有存储过程、触发器、视图、表 # select * From user_triggers; --所有触发器 select * From user_procedures; --所有存储过程 select * From user_views; --所有视图 select * From user_tables; --所有表 6、查看当前数据库连接的sid实例 # select instance_name from v$instance; 7、查看用户拥有的表空间 # select tablespace_name from user_tablespaces;","title":"Oracle命令","type":"docs"},{"content":"","date":"2024-01-28","externalUrl":null,"permalink":"/tags/mybatis/","section":"标签","summary":"","title":"Mybatis","type":"tags"},{"content":" 1、环境搭建 # 1.1、搭建数据库 # CREATE DATABASE `mybatis`; USE `mybatis`; CREATE TABLE `user`( `id` INT(20) PRIMARY KEY, `name` VARCHAR(30) DEFAULT NULL, `pwd` VARCHAR(30) DEFAULT NULL ); INSERT INTO `user` VALUES (1,\u0026#34;tom\u0026#34;,\u0026#34;123456\u0026#34;), (2,\u0026#34;jack\u0026#34;,\u0026#34;123456\u0026#34;), (3,\u0026#34;tim\u0026#34;,\u0026#34;123456\u0026#34;); 1.2、导入依赖 # \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;mysql\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mysql-connector-java\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;8.0.25\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.mybatis\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;mybatis\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;3.5.6\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 1.3、编写DAO接口 # 还要编写pojo层具体实体类\npublic interface UserDao { List\u0026lt;User\u0026gt; getUserList(); } 1.4、编写mybatis工具类 # public class MybaisUtils { private static SqlSessionFactory sqlSessionFactory; static { try { String resource = \u0026#34;mybatis.xml\u0026#34;; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); } } 1.5、编写配置文件 # \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; ?\u0026gt; \u0026lt;!DOCTYPE configuration PUBLIC \u0026#34;-//mybatis.org//DTD Config 3.0//EN\u0026#34; \u0026#34;http://mybatis.org/dtd/mybatis-3-config.dtd\u0026#34;\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;environments default=\u0026#34;development\u0026#34;\u0026gt; \u0026lt;environment id=\u0026#34;development\u0026#34;\u0026gt; \u0026lt;transactionManager type=\u0026#34;JDBC\u0026#34;/\u0026gt; \u0026lt;dataSource type=\u0026#34;POOLED\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;driver\u0026#34; value=\u0026#34;com.mysql.cj.jdbc.Driver\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;url\u0026#34; value=\u0026#34;jdbc:mysql://localhost:3306/mybatis?useSSL=true\u0026amp;amp;useUnicode=true\u0026amp;amp;characterEncoding=UTF-8\u0026amp;amp;serverTimeZone=UTC\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;username\u0026#34; value=\u0026#34;root\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;password\u0026#34; value=\u0026#34;Tmh010625\u0026#34;/\u0026gt; \u0026lt;/dataSource\u0026gt; \u0026lt;/environment\u0026gt; \u0026lt;/environments\u0026gt; \u0026lt;mappers\u0026gt; \u0026lt;mapper resource=\u0026#34;UserMapper.xml\u0026#34;/\u0026gt; \u0026lt;/mappers\u0026gt; \u0026lt;/configuration\u0026gt; 1.5.1、外部链接配置方法 # 在configuration标签内第一行写明properties标签\n\u0026lt;properties resource=\u0026#34;db.properties\u0026#34;/\u0026gt; \u0026lt;environments default=\u0026#34;development\u0026#34;\u0026gt; \u0026lt;environment id=\u0026#34;development\u0026#34;\u0026gt; \u0026lt;transactionManager type=\u0026#34;JDBC\u0026#34;/\u0026gt; \u0026lt;dataSource type=\u0026#34;POOLED\u0026#34;\u0026gt; \u0026lt;property name=\u0026#34;driver\u0026#34; value=\u0026#34;${db.driver}\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;url\u0026#34; value=\u0026#34;${db.url}\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;username\u0026#34; value=\u0026#34;${db.username}\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;password\u0026#34; value=\u0026#34;${db.password}\u0026#34;/\u0026gt; \u0026lt;/dataSource\u0026gt; \u0026lt;/environment\u0026gt; \u0026lt;/environments\u0026gt; 1.5.2、配置properties文件 # db.driver=com.mysql.cj.jdbc.Driver db.url=jdbc:mysql://localhost:3306/mybatis?useSSL=true\u0026amp;useUnicode=true\u0026amp;characterEncoding=UTF-8\u0026amp;serverTimeZone=UTC db.username=root db.password=Tmh010625 1.6、编写SQL映射xml文件 # \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; ?\u0026gt; \u0026lt;!DOCTYPE mapper PUBLIC \u0026#34;-//mybatis.org//DTD Mapper 3.0//EN\u0026#34; \u0026#34;http://mybatis.org/dtd/mybatis-3-mapper.dtd\u0026#34;\u0026gt; \u0026lt;mapper namespace=\u0026#34;org.learn.demon.dao.UserDao\u0026#34;\u0026gt; \u0026lt;select id=\u0026#34;getUserList\u0026#34; resultType=\u0026#34;org.learn.demon.pojo.User\u0026#34;\u0026gt; select * from mybatis.user \u0026lt;/select\u0026gt; \u0026lt;/mapper\u0026gt; 1.7、MAVEN额外配置 # 约定大于配置，在resources文件夹外编写xml文件或其他文件时，配置pom.xml\n\u0026lt;build\u0026gt; \u0026lt;resources\u0026gt; \u0026lt;resource\u0026gt; \u0026lt;directory\u0026gt;src/main/resources\u0026lt;/directory\u0026gt; \u0026lt;includes\u0026gt; \u0026lt;include\u0026gt;**/*.properties\u0026lt;/include\u0026gt; \u0026lt;include\u0026gt;**/*.xml\u0026lt;/include\u0026gt; \u0026lt;/includes\u0026gt; \u0026lt;filtering\u0026gt;false\u0026lt;/filtering\u0026gt; \u0026lt;/resource\u0026gt; \u0026lt;resource\u0026gt; \u0026lt;directory\u0026gt;src/main/java\u0026lt;/directory\u0026gt; \u0026lt;includes\u0026gt; \u0026lt;include\u0026gt;**/*.properties\u0026lt;/include\u0026gt; \u0026lt;include\u0026gt;**/*.xml\u0026lt;/include\u0026gt; \u0026lt;/includes\u0026gt; \u0026lt;filtering\u0026gt;false\u0026lt;/filtering\u0026gt; \u0026lt;/resource\u0026gt; \u0026lt;/resources\u0026gt; \u0026lt;/build\u0026gt; 2、CRUD # 2.1、namespace # namespace中的包名要和Dao/mapper接口的包名一致！\n2.2、select # 语法：\n增删改方法中必须提交事务才能执行\nSqlSession sqlSession = MybaisUtils.getSqlSession(); sqlSession.commit(); id:就是对应的namespace中的方法名 resultType:Sql语句执行的返回值 parameterType:参数类型 2.2.1、在接口中写方法 # //查询全部用户 List\u0026lt;User\u0026gt; getUserList(); 2.2.2、在mapper.xml映射文件中编写sql语句 # \u0026lt;select id=\u0026#34;getUserList\u0026#34; resultType=\u0026#34;org.learn.demon.pojo.User\u0026#34;\u0026gt; select * from mybatis.user \u0026lt;/select\u0026gt; 2.2.3、编写测试方法 # @Test public void test1(){ SqlSession sqlSession = MybaisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List\u0026lt;User\u0026gt; userList = mapper.getUserList(); for(User user:userList){ System.out.println(user); } sqlSession.close(); } 2.3、insert # 2.3.1、在接口中写方法 # //insert一个用户 int addUser(User user); 2.3.2、在mapper.xml映射文件中编写sql语句 # \u0026lt;insert id=\u0026#34;addUser\u0026#34; parameterType=\u0026#34;org.learn.demon.pojo.User\u0026#34;\u0026gt; insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd}); \u0026lt;/insert\u0026gt; 2.3.3、编写测试方法 # @Test public void test3(){ SqlSession sqlSession = MybaisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.addUser(new User(4, \u0026#34;哈哈\u0026#34;, \u0026#34;123123\u0026#34;)); sqlSession.commit(); sqlSession.close(); } 2.4、update # \u0026lt;update id=\u0026#34;updateUser\u0026#34; parameterType=\u0026#34;org.learn.demon.pojo.User\u0026#34;\u0026gt; update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id}; \u0026lt;/update\u0026gt; 2.5、delete # \u0026lt;delete id=\u0026#34;deleteUser\u0026#34; parameterType=\u0026#34;int\u0026#34;\u0026gt; delete from mybatis.user where id = #{id}; \u0026lt;/delete\u0026gt; 2.6、万能map # Map传递参数，在sql中取出key\n对象传递参数，在sql中取出对象的属性\n只有一个基本类型参数，直接在sql中取出\n2.7、模糊查询 # java代码执行的时候，传递通配符%%\nList\u0026lt;User\u0026gt; userList = mapper.getUserLike(\u0026#34;%李%\u0026#34;); 在sql拼接中使用通配符\nselect * from mybatis.user where name like \u0026#34;%\u0026#34;#{value}\u0026#34;%\u0026#34;; 3、配置解析 # 3.1、类型别名（typeAliases） # 类型别名是为java类型设置一个短的名字\n用来减少完全限定名的冗余\n在mybatis配置xml文件中配置 3.1.1、别名（typeAlias） # \u0026lt;typeAliases\u0026gt; \u0026lt;typeAlias type=\u0026#34;org.learn.demon.pojo.User\u0026#34; alias=\u0026#34;user\u0026#34;/\u0026gt; \u0026lt;/typeAliases\u0026gt; 可以用user来代替org.learn.demon.pojo.User的书写\n3.1.2、扫描包(package) # \u0026lt;typeAliases\u0026gt; \u0026lt;package name=\u0026#34;org.learn.demon.pojo\u0026#34;/\u0026gt; \u0026lt;/typeAliases\u0026gt; mybatis在包名下面搜索需要的java bean\n扫描实体类的包，默认别名为这个类的类名，首字母小写\n第二种添加别名则需要在实体类上配置注解\n@Alias(value = \u0026#34;hello\u0026#34;) public class User {} 4、解决属性名和字段名不一致的问题 # 4.1、在查询语句中起别名，别名与属性名一致(as) # 4.2、xml文件中使用resultMap # java实体类属性为password，数据库中字段名为pwd\n\u0026lt;resultMap id=\u0026#34;userMap\u0026#34; type=\u0026#34;org.learn.demon.pojo.User\u0026#34;\u0026gt; \u0026lt;result column=\u0026#34;pwd\u0026#34; property=\u0026#34;password\u0026#34;/\u0026gt; \u0026lt;/resultMap\u0026gt; \u0026lt;select id=\u0026#34;selectOneUser\u0026#34; resultMap=\u0026#34;userMap\u0026#34; parameterType=\u0026#34;int\u0026#34;\u0026gt; select * from mybatis.user where id = #{id}; \u0026lt;/select\u0026gt; 5、日志 # mybatis配置xml文件，使用settings标签选择生成日志功能，常见的日志有以下几种：\nSLF4J *** LOG4J *** LOG4J2 JDK_LOGGING COMMONS_LOGGING STDOUT_LOGGING *** NO_LOGGING \u0026lt;settings\u0026gt; \u0026lt;setting name=\u0026#34;logImpl\u0026#34; value=\u0026#34;STDOUT_LOGGING\u0026#34;/\u0026gt; \u0026lt;/settings\u0026gt; 5.1、log4j # 创建log4j的properties文件，配置如下内容\n#将等级为DEBUG的日志信息输出到console file这两个目的地，console file的定义在下面的代码 1og4j.rootLogger=DEBUG,console,file #控制台输出的相关设置 1og4j.appender.console=org.apache.1og4j.ConsoleAppender 1og4j.appender.console.Target=System.out 1og4j.appender.console.Threshold=DEBUG 1og4j.appender.console.1ayout=org.apache.1og4j.PatternLayout 1og4j.appender.console.layout.ConversionPattern=[%c]-%m%n #文件输出的相关设置 1og4j.appender.file=org.apache.1og4j.RollingFlAppedr 1og4j.appender.file.File=./1og/kuang.log 1og4j.appender.file.MaxFileSize=10mb 1og4j.appender.file.Threshold=DEBUG 1og4j.appender.file.layout=org.apache.log4j.PatternLayout 1og4j.appender.filelayout.ConversionPattern=[%p][%d{yy-M-dd}][%c]%m%n #日志输出级别 1og4j.logger.org.mybatis=DEBUG 1og4j.logger.java.sq1=DEBUG 1og4j.logger.java.sq1.Statement=DEBUG 1og4j.1ogger.java.sq1.ResultSet=DEBUG log4j.logger.java.sq1.Preparedstatement=DEBUG 6、使用注解开发（不建议） # 本质是反射，底层是动态代理\n6.1、注解在接口上实现 # @select(\u0026#34;select * from user\u0026#34;) List\u0026lt;User\u0026gt; getUser(); 6.2、核心配置文件中绑定接口 # \u0026lt;mapper\u0026gt; \u0026lt;mapper class=\u0026#34;org.learn.demon.dao.UserMapper\u0026#34;/\u0026gt; \u0026lt;/mapper\u0026gt; 6.3、@Param()注解 # 基本类型的参数或者String类型，需要加上 引用类型不需要加 如果只有一个基本类型可以忽略，建议都写上 在SQL中引用的就是我们这里的@Param()中设定的属性名 7、多表关联查询 # 建议使用联表查询\n创建数据库 7.1、多对一 # JAVA中表示为类中的属性含有对象\n创建实体类\n@Data public class Student { private int id; private String name; private Teacher teacher; } @Data public class Teacher { private int id; private String name; } 7.1.1、子查询 # \u0026lt;select id=\u0026#34;getAllStudentInfo\u0026#34; resultMap=\u0026#34;studentMap\u0026#34;\u0026gt; select * from mybatis.student; \u0026lt;/select\u0026gt; \u0026lt;resultMap id=\u0026#34;studentMap\u0026#34; type=\u0026#34;Student\u0026#34;\u0026gt; \u0026lt;result property=\u0026#34;id\u0026#34; column=\u0026#34;id\u0026#34;/\u0026gt; \u0026lt;result property=\u0026#34;name\u0026#34; column=\u0026#34;name\u0026#34;/\u0026gt; \u0026lt;association property=\u0026#34;teacher\u0026#34; column=\u0026#34;tid\u0026#34; javaType=\u0026#34;Teacher\u0026#34; select=\u0026#34;getAllTeacher\u0026#34;/\u0026gt; \u0026lt;/resultMap\u0026gt; \u0026lt;select id=\u0026#34;getAllTeacher\u0026#34; resultType=\u0026#34;Teacher\u0026#34;\u0026gt; select * from mybatis.teacher; \u0026lt;/select\u0026gt; 7.1.2、联表查询 # \u0026lt;select id=\u0026#34;getAllStudentInfo2\u0026#34; resultMap=\u0026#34;stuTeaMap\u0026#34;\u0026gt; select s.id as sid,s.name as sname,t.name as tname,t.id as tid from mybatis.student as s,mybatis.teacher as t where s.tid = t.id; \u0026lt;/select\u0026gt; \u0026lt;resultMap id=\u0026#34;stuTeaMap\u0026#34; type=\u0026#34;Student\u0026#34;\u0026gt; \u0026lt;result property=\u0026#34;id\u0026#34; column=\u0026#34;sid\u0026#34;/\u0026gt; \u0026lt;result property=\u0026#34;name\u0026#34; column=\u0026#34;sname\u0026#34;/\u0026gt; \u0026lt;association property=\u0026#34;teacher\u0026#34; column=\u0026#34;Teacher\u0026#34;\u0026gt; \u0026lt;result property=\u0026#34;name\u0026#34; column=\u0026#34;tname\u0026#34;/\u0026gt; \u0026lt;result property=\u0026#34;id\u0026#34; column=\u0026#34;tid\u0026#34;/\u0026gt; \u0026lt;/association\u0026gt; \u0026lt;/resultMap\u0026gt; 7.2、一对多 # JAVA中表示为类中的属性含有集合对象\n创建实体类\n@Data public class Student{ private Integer id; private String name; private Integer tid; } @Data public class Teacher{ private Integer id; private String name; private List\u0026lt;Student\u0026gt; students; } 7.2.1、联表查询 # \u0026lt;select id=\u0026#34;selectTeacherById\u0026#34; resultMap=\u0026#34;getStudentMap\u0026#34; parameterType=\u0026#34;int\u0026#34;\u0026gt; select t.id as tid,t.name as tname,s.name as sname,s.id as sid,s.tid as stid from mybatis.teacher as t,mybatis.student as s where t.id = s.tid and t.id = #{tid}; \u0026lt;/select\u0026gt; \u0026lt;resultMap id=\u0026#34;getStudentMap\u0026#34; type=\u0026#34;Teacher\u0026#34;\u0026gt; \u0026lt;result column=\u0026#34;tname\u0026#34; property=\u0026#34;name\u0026#34;/\u0026gt; \u0026lt;result column=\u0026#34;tid\u0026#34; property=\u0026#34;id\u0026#34;/\u0026gt; \u0026lt;collection property=\u0026#34;students\u0026#34; ofType=\u0026#34;Student\u0026#34;\u0026gt; \u0026lt;result property=\u0026#34;name\u0026#34; column=\u0026#34;sname\u0026#34;/\u0026gt; \u0026lt;result property=\u0026#34;id\u0026#34; column=\u0026#34;sid\u0026#34;/\u0026gt; \u0026lt;result property=\u0026#34;tid\u0026#34; column=\u0026#34;tid\u0026#34;/\u0026gt; \u0026lt;/collection\u0026gt; \u0026lt;/resultMap\u0026gt; 8、动态SQL # 8.1、where/if # 自动去除and添加and\n\u0026lt;select id=\u0026#34;selectBlogJudge\u0026#34; resultType=\u0026#34;myBlog\u0026#34; parameterType=\u0026#34;map\u0026#34;\u0026gt; select * from mybatis.myblog \u0026lt;where\u0026gt; \u0026lt;if test=\u0026#34;title != null\u0026#34;\u0026gt; title = #{title} \u0026lt;/if\u0026gt; \u0026lt;if test=\u0026#34;author != null\u0026#34;\u0026gt; and author = #{author} \u0026lt;/if\u0026gt; \u0026lt;/where\u0026gt; \u0026lt;/select\u0026gt; 8.2、set # 自动去除逗号\n\u0026lt;set\u0026gt; \u0026lt;if test=\u0026#34;author != null\u0026#34;\u0026gt; author = #{author}, \u0026lt;/if\u0026gt; \u0026lt;/set\u0026gt; \u0026lt;where\u0026gt; id = #{id} \u0026lt;/where\u0026gt; 8.4、foreach # collection表示传入为集合元素\nitem表示传入的具体元素\nopen表示开头用什么\nclose表示结尾用什么\nseparator表示中间判断条件的连接符\n\u0026lt;select id=\u0026#34;selectBlogById\u0026#34; resultType=\u0026#34;myBlog\u0026#34; parameterType=\u0026#34;map\u0026#34;\u0026gt; select * from mybatis.myblog \u0026lt;where\u0026gt; \u0026lt;foreach collection=\u0026#34;names\u0026#34; item=\u0026#34;author\u0026#34; open=\u0026#34;and (\u0026#34; close=\u0026#34;)\u0026#34; separator=\u0026#34;or\u0026#34;\u0026gt; author = #{author} \u0026lt;/foreach\u0026gt; \u0026lt;/where\u0026gt; \u0026lt;/select\u0026gt; 8.5、SQL # 标签内的id可以被别的SQL语句用include语句引用，提高代码可重用性\n\u0026lt;sql id=\u0026#34;if-text-title\u0026#34;\u0026gt; \u0026lt;if test=\u0026#34;title != null\u0026#34;\u0026gt; title = #{title} \u0026lt;/if\u0026gt; \u0026lt;if test=\u0026#34;author != null\u0026#34;\u0026gt; and author = #{author} \u0026lt;/if\u0026gt; \u0026lt;/sql\u0026gt; \u0026lt;select id=\u0026#34;selectBlogJudge\u0026#34; resultType=\u0026#34;myBlog\u0026#34; parameterType=\u0026#34;map\u0026#34;\u0026gt; select * from mybatis.myblog \u0026lt;where\u0026gt; \u0026lt;include refid=\u0026#34;if-text-title\u0026#34;\u0026gt;\u0026lt;/include\u0026gt; \u0026lt;/where\u0026gt; \u0026lt;/select\u0026gt; 9、二级缓存 # 基于namespace级别缓存，一个名称空间对应一个二级缓存，也叫全局缓存 工作机制 一个会话查询一条数据，这个数据就会被放在当前会话的一级缓存中 如果当前会话关闭，对应的一级缓存清除 新的会话查询信息，可以从二级缓存中获取内容 不同的mapper查出的数据会放在自己对应的缓存（map）中 ","date":"2024-01-28","externalUrl":null,"permalink":"/docs/mybatis/","section":"文章","summary":"1、环境搭建 # 1.1、搭建数据库 # CREATE DATABASE `mybatis`; USE `mybatis`; CREATE TABLE `user`( `id` INT(20) PRIMARY KEY, `name` VARCHAR(30) DEFAULT NULL, `pwd` VARCHAR(30) DEFAULT NULL ); INSERT INTO `user` VALUES (1,\"tom\",\"123456\"), (2,\"jack\",\"123456\"), (3,\"tim\",\"123456\"); 1.2、导入依赖 # \u003cdependency\u003e \u003cgroupId\u003emysql\u003c/groupId\u003e \u003cartifactId\u003emysql-connector-java\u003c/artifactId\u003e \u003cversion\u003e8.0.25\u003c/version\u003e \u003c/dependency\u003e \u003cdependency\u003e \u003cgroupId\u003eorg.mybatis\u003c/groupId\u003e \u003cartifactId\u003emybatis\u003c/artifactId\u003e \u003cversion\u003e3.5.6\u003c/version\u003e \u003c/dependency\u003e 1.3、编写DAO接口 # 还要编写pojo层具体实体类\n","title":"Mybatis学习","type":"docs"},{"content":"","date":"2024-01-28","externalUrl":null,"permalink":"/tags/servelet/","section":"标签","summary":"","title":"Servelet","type":"tags"},{"content":" 一、Servlet规范介绍 # 1.Servlet规范来自于JAVAEE规范中的一种 # 2.作用： # 在Servlet规范中，指定动态资源文件开发步骤 在Servlet规范中，指定Http服务器调用动态资源文件规则 在Servlet规范中，指定Http服务器管理动态资源文件实例对象规则 二、Servlet接口实现类 # Servlet接口来自于Servlet规范下一个接口，这个接口存在Http服务器提供jar包 Tomcat服务器下Lib文件有一个servlet-api.jar存放的Servlet接口（java.servlet.Servlet接口） Servlet规范中任务，Http服务器能调用的动态资源文件必须是一个Servlet接口实现类 三、Servlet接口实现类开发步骤 # 第一步：创建一个JAVA类继承与HttpServlet父类，使之成为一个Servlet接口实现类\n第二步：重写httpServlet父类两个方法，doGet或doPost\n","date":"2024-01-28","externalUrl":null,"permalink":"/docs/servlet/","section":"文章","summary":"一、Servlet规范介绍 # 1.Servlet规范来自于JAVAEE规范中的一种 # 2.作用： # 在Servlet规范中，指定动态资源文件开发步骤 在Servlet规范中，指定Http服务器调用动态资源文件规则 在Servlet规范中，指定Http服务器管理动态资源文件实例对象规则 二、Servlet接口实现类 # Servlet接口来自于Servlet规范下一个接口，这个接口存在Http服务器提供jar包 Tomcat服务器下Lib文件有一个servlet-api.jar存放的Servlet接口（java.servlet.Servlet接口） Servlet规范中任务，Http服务器能调用的动态资源文件必须是一个Servlet接口实现类 三、Servlet接口实现类开发步骤 # 第一步：创建一个JAVA类继承与HttpServlet父类，使之成为一个Servlet接口实现类\n","title":"Servlet学习","type":"docs"},{"content":"","externalUrl":null,"permalink":"/en/","section":"AzurTian","summary":"","title":"AzurTian","type":"page"},{"content":"","externalUrl":null,"permalink":"/en/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/en/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"}]