2024-09-02



import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureRenderData;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
@RestController
public class WordController {
 
    @GetMapping("/download-word")
    public void downloadWord(HttpServletResponse response) throws IOException {
        // 创建模板对象
        XWPFTemplate template = XWPFTemplate.compile(new ByteArrayInputStream(createWord().toByteArray()));
 
        // 模拟数据
        Map<String, Object> data = new HashMap<>();
        data.put("title", "标题");
        data.put("image", new PictureRenderData(100, 100, "image.jpg"));
 
        // 替换模板中的占位符
        template.render(data);
 
        // 写入输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        template.write(outputStream);
 
        // 设置响应头
        response.setHeader("Content-Disposition", "attachment;filename=example.docx");
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
 
        // 写入响应流并下载
        response.getOutputStream().write(outputStream.toByteArray());
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }
 
    private ByteArrayOutputStream createWord() throws IOException {
        // 创建Word文档
        XWPFTemplate template = XWPFTemplate.compile("template.docx").render(new HashMap<>());
 
        // 写入内存
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        template.write(outputStream);
 
        // 关闭模板
        template.close();
 
        return outputStream;
    }
}

这段代码使用了deepoove-poi库来动态替换Word文档中的占位符,并下载生成的Word文档。在Spring Boot环境中,它创建了一个REST控制器,提供了一个接口来处理文档的下载。代码中包含了创建模板、替换数据、写入输出流、设置

2024-09-02



# 安装Django Simple Captcha模块
# 打开终端或命令行,输入以下命令:
pip install django-simple-captcha
 
# 在Django项目的settings.py中添加captcha应用
INSTALLED_APPS = [
    ...
    'captcha',
    ...
]
 
# 运行数据库迁移命令
# 终端或命令行中,输入以下命令:
python manage.py migrate captcha
 
# 在urls.py中添加captcha的URL
from django.urls import path, include
 
urlpatterns = [
    ...
    path('captcha/', include('captcha.urls')),
    ...
]
 
# 使用CaptchaField在表单中
from django import forms
from captcha.fields import CaptchaField
 
class ContactForm(forms.Form):
    your_name = forms.CharField(label='Your name')
    your_email = forms.EmailField(label='Your email')
    content = forms.CharField(widget=forms.Textarea, label='Content')
    captcha = CaptchaField()
 
# 在视图中处理表单提交
from django.shortcuts import render
from .forms import ContactForm
 
def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # 处理表单数据
            pass
    else:
        form = ContactForm()
    return render(request, 'contact.html', {'form': form})
 
# 在模板中显示表单
<form method="post" action="">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit">
</form>

以上代码展示了如何在Django项目中安装和使用Django Simple Captcha模块。首先,使用pip安装captcha模块,然后在settings.py中添加captcha应用,运行数据库迁移。接着,在urls.py中添加captcha的URL,并在表单中使用CaptchaField。最后,在视图和模板中处理和显示表单。

2024-09-02

Redis 是一个开源的使用 C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

基本部署

1. 下载和安装




# 下载
wget http://download.redis.io/releases/redis-6.2.6.tar.gz
# 解压
tar xzf redis-6.2.6.tar.gz
# 进入目录
cd redis-6.2.6
# 编译
make

2. 运行 Redis 服务器




# 运行
src/redis-server

3. 运行 Redis 客户端




# 新开一个终端,进入redis目录
# 运行
src/redis-cli
# 测试
ping

如果返回 PONG,则表示 Redis 安装成功并可以正常使用。

基本命令

1. 设置键值对




SET key value

2. 获取键对应的值




GET key

3. 删除键




DEL key

4. 检查键是否存在




EXISTS key

5. 设置键的过期时间




EXPIRE key seconds

6. 列出所有键




KEYS *

7. 获取键的数据类型




TYPE key

进阶应用

Redis 支持复杂的数据结构,如字符串、列表、集合、有序集合、哈希表等。

8. 使用列表(list)




# 在列表左侧插入元素
LPUSH key value
# 在列表右侧插入元素
RPUSH key value
# 获取列表指定范围内的元素
LRANGE key start stop

9. 使用集合(set)




# 添加成员
SADD key member
# 获取集合所有成员
SMEMBERS key

10. 使用有序集合(sorted set)




# 添加成员及其分数
ZADD key score member
# 获取有序集合范围内成员
ZRANGE key start stop

11. 使用哈希表




# 设置哈希表字段的值
HSET key field value
# 获取哈希表中字段的值
HGET key field
# 获取哈希表中所有字段及值
HGETALL key

持久化

Redis 支持两种持久化方式:RDB(默认)和 AOF。

12. RDB 持久化

定时将内存中的数据快照保存到磁盘的一个压缩二进制文件中。

13. AOF 持久化

记录每个写操作,将它们追加到文件中。

可以在 redis.conf 中配置持久化。

高级特性

14. 发布/订阅




# 发布消息
PUBLISH channel message
# 订阅频道
SUBSCRIBE channel

15. 事务




# 开启事务
MULTI
# 将多个命令入队到事务中
...
# 执行事务
EXEC

16. Lua 脚本




# 执行Lua脚本
EVAL script key
2024-09-02

在C#中,你可以使用Windows的加密API来加密和解密SQLite数据库文件。以下是一个简单的例子,展示了如何使用BCrypt进行加密和解密:

首先,你需要安装System.Security.Cryptography.Algorithms NuGet包。




using System;
using System.IO;
using System.Security.Cryptography;
 
public class SQLiteEncrypter
{
    private readonly string _encryptionKey;
 
    public SQLiteEncrypter(string encryptionKey)
    {
        _encryptionKey = encryptionKey;
    }
 
    public void EncryptDatabase(string inputFilePath, string outputFilePath)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(_encryptionKey);
            aes.GenerateIV();
 
            using (FileStream fsIn = new FileStream(inputFilePath, FileMode.Open))
            using (FileStream fsOut = new FileStream(outputFilePath, FileMode.Create))
            using (CryptoStream cs = new CryptoStream(fsOut, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                fsIn.CopyTo(cs);
                fsOut.FlushFinalBlock();
 
                // Save the IV and the ciphertext to the output file
                byte[] iv = aes.IV;
                byte[] ciphertext = fsOut.ToArray();
                byte[] combined = CombineArrays(iv, ciphertext);
 
                // Write the IV and the ciphertext to the output file
                fsOut.Seek(0, SeekOrigin.Begin);
                fsOut.Write(combined, 0, combined.Length);
            }
        }
    }
 
    public void DecryptDatabase(string inputFilePath, string outputFilePath)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(_encryptionKey);
 
            using (FileStream fsIn = new FileStream(inputFilePath, FileMode.Open))
            using (FileStream fsOut = new FileStream(outputFilePath, FileMode.Create))
            using (CryptoStream cs = new CryptoStream(fsOut, aes.CreateDecryptor(), CryptoStreamMode.Write))
            {
                byte[] buffer = new byte[1024];
                int read;
 
                // Read t
2024-09-02

在使用MyBatis-Plus实现多租户数据权限隔离时,可以通过自定义拦截器来实现。以下是一个简化的示例代码:




import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
 
@Configuration
public class MybatisPlusConfig {
 
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加多租户拦截器
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
            @Override
            public Expression getTenantId() {
                // 获取当前租户ID
                String tenantId = "your_tenant_id";
                return new StringValue(tenantId);
            }
 
            @Override
            public String getTenantIdColumn() {
                // 租户ID字段名
                return "tenant_id";
            }
 
            @Override
            public boolean ignoreTable(String tableName) {
                // 忽略不需要租户隔离的表
                return "user".equals(tableName); // 假设user表不需要租户隔离
            }
        }));
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

在这个配置类中,我们定义了一个MybatisPlusInterceptor,并添加了TenantLineInnerInterceptor以及PaginationInnerInterceptorTenantLineInnerInterceptor使用了自定义的TenantLineHandler来提供租户ID以及相关配置。在执行数据库操作时,MyBatis-Plus会根据配置自动注入租户ID,从而实现多租户数据权限隔离。

注意:这只是一个简化的示例,实际应用中你需要根据自己的需求来实现getTenantIdignoreTable方法。同时,getTenantIdColumn方法中的字段名需要和数据库中实际存储租户ID的列名一致。

2024-09-02



import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 
@EnableEurekaServer // 启用Eureka服务端功能
@SpringBootApplication
public class EurekaServerApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

这段代码是一个Spring Cloud Eureka服务端的入门示例,它通过@EnableEurekaServer注解启用Eureka服务端的功能,并且通过SpringBootApplication注解开启Spring Boot的自动配置功能。在main方法中,使用SpringApplication.run启动了Spring Boot应用。这个应用将作为Eureka服务注册中心,其他服务可以将自己注册到这个中心,也可以从这个中心获取其他服务的信息。

2024-09-02

在Django中,我们可以使用模型(models)来定义数据库中的数据结构,并使用Django表达式来处理这些数据。

例如,我们可以定义一个简单的模型来表示一个图书:




from django.db import models
 
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()

然后,我们可以使用Django表达式来查询和处理这些数据。例如,我们可以查询所有作者名字为"John Doe"的图书:




from myapp.models import Book
 
books = Book.objects.filter(author='John Doe')

在这个例子中,Book.objects.filter(author='John Doe')是一个Django表达式,它查询了所有author字段为"John Doe"的Book对象。

另外,我们可以在模型中使用表达式来定义字段的默认值:




from django.db import models
from django.utils import timezone
 
class MyModel(models.Model):
    created_at = models.DateTimeField(default=timezone.now)

在这个例子中,default=timezone.now是一个表达式,它设置了created_at字段的默认值为当前时间。

2024-09-02

MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。

MyBatis 的核心配置主要包括以下几个部分:

  1. 配置数据库信息
  2. 配置事务管理
  3. 配置连接池
  4. 配置Mapper映射文件

以下是一个简单的MyBatis配置示例:




<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="database.properties"/>
 
  <settings>
    <!-- 全局配置的设置 -->
    <setting name="cacheEnabled" value="true"/>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="multipleResultSetsEnabled" value="true"/>
    <setting name="useColumnLabel" value="true"/>
    <setting name="useGeneratedKeys" value="false"/>
    <setting name="defaultExecutorType" value="SIMPLE"/>
    <setting name="defaultStatementTimeout" value="25000"/>
  </settings>
 
  <typeAliases>
    <!-- 别名定义 -->
    <typeAlias alias="User" type="com.example.domain.User"/>
  </typeAliases>
 
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
 
  <mappers>
    <!-- Mapper文件注册 -->
    <mapper resource="com/example/mapper/UserMapper.xml"/>
  </mappers>
</configuration>

在这个配置文件中,我们定义了数据库的连接信息,包括驱动、URL、用户名和密码。我们也配置了事务管理器和数据源。最后,我们注册了Mapper XML文件,这个文件包含了SQL语句和映射规则。

在实际开发中,你需要根据自己的数据库和需求来修改这些配置信息。

2024-09-02



import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import com.ververica.cdc.connectors.postgresql.PostgreSQLSource;
import com.ververica.cdc.debezium.StringDebeziumDeserializationSchema;
 
public class FlinkCDCPostgresExample {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
 
        Properties properties = new Properties();
        properties.setProperty("connector", "postgres-cdc");
        properties.setProperty("hostname", "your-db-host");
        properties.setProperty("port", "5432");
        properties.setProperty("username", "your-username");
        properties.setProperty("password", "your-password");
        properties.setProperty("database", "your-db-name");
        // 指定同步的表和字段,这里使用通配符同步所有表
        properties.setProperty("table-include-list", "your-db-name.%");
 
        // 创建 PostgreSQL-CDC source
        PostgreSQLSource<String> source = new PostgreSQLSource<>(
            properties,
            StringDebeziumDeserializationSchema.builder().build()
        );
 
        env.addSource(source).print();
 
        env.execute("Flink CDC Postgres Job");
    }
}

这段代码展示了如何使用Flink CDC连接器来同步PostgreSQL数据库的所有表。它创建了一个PostgreSQLSource,并将Debezium提供的变更事件(JSON字符串格式)作为数据源添加到Flink DataStream中。这个例子中使用了通配符来同步数据库中的所有表,并且没有指定具体的表名。实际使用时,需要根据具体情况调整配置属性,例如数据库的连接信息。

2024-09-02

在Spring Cloud Gateway中实现分布式限流,可以使用Spring Cloud Gateway内置的请求过滤器RequestRateLimiterGatewayFilterFactory,结合Redis实现分布式限流。

  1. 添加依赖(pom.xml):



<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
  1. 配置application.yml:



spring:
  cloud:
    gateway:
      routes:
        - id: requestratelimiter_route
          uri: http://example.com
          filters:
            - name: RequestRateLimiter
              args:
                key-resolver: '#{@ipAddressKeyResolver}'
                redis-rate-limiter.replenishRate: 1 # 每秒填充平均速率
                redis-rate-limiter.burstCapacity: 3 # 限流容量
    redis:
      host: localhost
      port: 6379
  1. 配置限流策略的KeyResolver:



@Configuration
public class GatewayConfig {
 
    @Bean
    public KeyResolver ipAddressKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
    }
}

这样配置后,每个IP地址访问路由时都会受到限流管理,每秒只允许1个请求通过,超过限制的请求会被拦截。

注意:RequestRateLimiterGatewayFilterFactory是依赖于Hystrix的,因此确保已经添加了spring-cloud-starter-netflix-hystrix依赖。