Spring Boot与SpringDataJPA整合实战指南

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:在现代Java Web开发中,Spring Boot凭借其自动配置和快速启动特性广受青睐,而Spring Data JPA作为Spring生态中的核心数据访问组件,显著简化了JPA的使用。本教程详细讲解如何在Spring Boot项目中整合Spring Data JPA,涵盖依赖引入、数据库配置、Repository接口定义、自定义查询方法及事务管理等内容。通过实际代码示例,帮助开发者快速构建高效、简洁的数据持久化层,并可结合Actuator、Security等模块提升应用的可维护性与安全性。

Spring Boot与Spring Data JPA整合深度实战:从环境搭建到生产级优化

你有没有经历过这样的场景?凌晨两点,线上系统突然报警——数据库连接池被打满,用户请求大面积超时。紧急排查后发现,竟然是因为某个新上线的报表功能在循环调用 save() 方法插入十万条数据,而没人记得启用批处理配置…… 😱

这事儿听起来离谱,但在真实项目中并不少见。尤其是在微服务架构下, DAO层的每一个细节都可能成为压垮系统的最后一根稻草

今天我们就来聊聊那个看似“简单”的组合:Spring Boot + Spring Data JPA。它真的只是写个接口就能自动实现CRUD吗?当然不是!🚀

我们不仅要搞懂怎么用,更要明白背后的机制、陷阱和最佳实践——毕竟,生产环境可不会给你第二次机会。


当你第一次看到 JpaRepository 这个接口时,可能会觉得:“哇,这也太爽了吧!” 不用手写SQL,不用管理事务,甚至连分页都能一行代码搞定。但正所谓“越简单的API背后,隐藏的复杂性就越高”。一旦出问题,往往就是那种让你翻遍日志都找不到头绪的诡异Bug。

比如:

  • 为什么查个列表会触发几十次SQL?
  • 明明加了 @Transactional ,事务怎么没生效?
  • save() 到底什么时候是INSERT,什么时候是UPDATE?

别急,这些问题我们一个一个拆开来看。先从最基础的开始——环境搭建。

💡 小贴士 :本文基于 Spring Boot 3.2 + Jakarta Persistence(原Java EE命名空间)编写,如果你还在用旧版,请注意迁移路径!

环境搭建不是“复制粘贴”就完事了

很多人一上来就直接加依赖、配YAML,然后跑起来发现一堆红字报错。其实啊, 一个好的运行环境,就像一栋房子的地基 ——你不能指望靠后期装修去弥补结构上的缺陷。

Maven/Gradle依赖管理:别让“版本地狱”毁了你

首先得明确一点:Spring Boot 的核心优势之一就是它的“自动装配 + BOM 控制”。

什么意思呢?就是说只要你引入了正确的 Starter,框架就会帮你把一堆复杂的依赖关系理清楚,避免你自己去一个个找版本号。

spring-boot-starter-data-jpa 到底带来了什么?
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

这一行代码,实际上悄悄给你塞进了好几样东西:

组件 作用
Hibernate ORM JPA的具体实现引擎
Spring ORM & TX 提供EntityManager、事务支持
Jakarta Persistence API 定义标准注解如 @Entity , @Table
Spring Data Commons Repository抽象层

🤔 你知道吗? 自从 Spring Boot 3.x 开始,JPA规范已经从 javax.persistence 迁移到 jakarta.persistence 。这意味着如果你还在用 Hibernate 5.x 或更早版本,很可能会遇到类找不到的问题!

所以记住这条黄金法则:

搭配 Spring Boot 3.x 使用 Hibernate 6.x 及以上版本

否则你会在启动时报类似这样的错误:

java.lang.ClassNotFoundException: jakarta.persistence.EntityManager

这时候别说加班了,通宵排查都不一定能搞定 😭

数据库驱动选哪个?别再乱猜了!

不同数据库厂商提供的 JDBC 驱动不仅坐标不一样,行为也有差异。下面这张表你应该收藏下来,关键时刻能救命👇

数据库 Group ID Artifact ID 推荐版本
MySQL 8+ mysql mysql-connector-java 8.0.33+
PostgreSQL org.postgresql postgresql 42.6.0+
Oracle 21c com.oracle.database.jdbc ojdbc11 21.10.0.0
SQL Server com.microsoft.sqlserver mssql-jdbc 12.4.2.jre11

举个例子,如果你想用 PostgreSQL:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

注意到那个 <scope>runtime</scope> 了吗?它的意思是:编译期不需要引用这个包,只在运行时加载。这样可以减少编译污染,提升构建效率。

🔍 进阶技巧 :建议使用 <dependencyManagement> 来统一锁定所有依赖版本!

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.2.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

这样一来,整个项目的依赖版本都被官方BOM控制住了,再也不怕传递依赖带来“惊喜”了~


第三方连接池:HikariCP为何是首选?

Spring Boot 2.x 起,默认连接池换成了 HikariCP ,它可不是随便选的。

相比老一代的 Tomcat JDBC Pool 或 Apache DBCP2,HikariCP 凭借极低延迟、高吞吐量和出色的内存管理能力,在并发环境下表现优异得多。

虽然它已经被包含在 spring-boot-starter-data-jpa 中了,但我们还是要学会如何调优它。

HikariCP 核心参数该怎么设?
参数名 默认值 推荐值 说明
maximumPoolSize 根据CPU核数计算 10–20(OLTP) 太大会拖垮DB
minimumIdle 同最大值 5–10 快速响应突发流量
connectionTimeout 30s 20s 防止客户端无限等待
idleTimeout 10min 5min 空闲太久就释放
maxLifetime 30min 20min 防止长时间持有连接导致老化
leakDetectionThreshold 关闭 60s 检测连接泄漏

来看看实际配置长什么样:

spring:
  datasource:
    hikari:
      maximum-pool-size: 15
      minimum-idle: 5
      connection-timeout: 20000
      idle-timeout: 300000
      max-lifetime: 1200000
      leak-detection-threshold: 60000
      pool-name: "AppHikariPool"
      validation-timeout: 5000

这些数字不是拍脑袋来的!比如 maximumPoolSize ,一般建议设置为 CPU 核数 × (2~4),但 OLTP 系统通常不超过 20,防止数据库被打爆。

而且你有没有想过一个问题:当应用试图获取连接时,到底发生了什么?

让我们通过一个流程图看看 HikariCP 内部是如何工作的:

sequenceDiagram
    participant App as Application
    participant Hikari as HikariCP
    participant DB as Database

    App->>Hikari: getConnection()
    alt 连接池中有可用连接
        Hikari-->>App: 返回活跃连接
    else 池中无空闲连接且未达上限
        Hikari->>DB: 创建新连接
        Hikari-->>App: 返回新建连接
    else 达到最大连接数
        Hikari->>Hikari: 等待直到超时
        alt 超时前获得连接
            Hikari-->>App: 返回连接
        else 超时仍未获取
            Hikari--x App: 抛出SQLTimeoutException
        end
    end

    App->>DB: 执行SQL操作
    App->>Hikari: close()(归还连接)
    Hikari->>Hikari: 校验连接有效性
    alt 连接有效且未超限
        Hikari->>Hikari: 放入空闲队列
    else 连接无效或池满
        Hikari->>DB: 关闭物理连接
    end

看到了吧?HikariCP 并不是简单地维护一个List,而是有一套完整状态机控制连接生命周期。这也是它性能强悍的原因之一。


多数据源配置:读写分离怎么做才对?

很多同学一开始都会犯一个错误:以为 Spring Data JPA 原生支持多数据源绑定。其实不然!它默认只认一个主数据源。

要在同一个应用里操作两个数据库(比如主库写、从库读),必须手动配置多个 EntityManagerFactory TransactionManager

怎么做?三步走战略!

1️⃣ 定义两个数据源Bean
2️⃣ 分别配置各自的 EntityManagerFactory TransactionManager
3️⃣ 用 @EnableJpaRepositories 指定包路径和工厂引用

看代码最直观:

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.repo.primary",
    entityManagerFactoryRef = "primaryEntityManagerFactory",
    transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDataSourceConfig {

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(primaryDataSource())
                .packages("com.example.entity.primary")
                .persistenceUnit("primary")
                .build();
    }

    @Bean
    @Primary
    public PlatformTransactionManager primaryTransactionManager(
            @Qualifier("primaryEntityManagerFactory") EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }
}

对应的 YAML 配置也很清晰:

spring:
  datasource:
    primary:
      url: jdbc:postgresql://master:5432/appdb
      username: masteruser
      password: masterpass
      hikari:
        maximum-pool-size: 20
    secondary:
      url: jdbc:postgresql://replica:5432/appdb
      username: readonly
      password: readpass
      hikari:
        maximum-pool-size: 10

🔍 提示 :别忘了 @Primary 注解!它是解决 @Autowired 歧义的关键。

否则当你注入 DataSource 却有两个候选Bean时,Spring 就懵了:“我该注入哪一个?” —— 直接抛异常。


JPA 行为配置:DDL生成策略千万别乱用!

开发阶段图方便用了 ddl-auto: update ,结果上线之后忘记改回来……这种事故我已经见过不下五次了。

记住一句话:

生产环境严禁使用 create/update!应该由 Liquibase/Flyway 管理 Schema 变更

那我们该怎么配置?

# application-dev.yml
spring:
  jpa:
    hibernate:
      ddl-auto: update

# application-prod.yml
spring:
  jpa:
    hibernate:
      ddl-auto: validate
适用场景
create 单元测试
create-drop 集成测试
update 开发环境
validate 准/生产环境
none 生产环境推荐

validate 是什么意思?就是在启动时检查实体类映射的表结构是否与数据库一致。如果不一致,直接启动失败,提醒你去同步脚本。

这才是安全的做法!


命名策略定制:你的驼峰字段真能正确映射吗?

默认情况下,JPA 会把 userId 映射成 user_id ,这是通过内置的命名策略完成的。

但如果你想统一加上前缀,比如所有表都叫 t_user t_order ,那就得自定义了。

@Component
public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return Identifier.toIdentifier("t_" + name.getText(), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return Identifier.toIdentifier(name.getText().replace("UUID", "_id"), name.isQuoted());
    }
}

注册方式:

spring:
  jpa:
    properties:
      hibernate:
        physical_naming_strategy: com.example.config.CustomPhysicalNamingStrategy

效果如下:

Java字段 自定义映射
entity t_entity
userId user_id

是不是瞬间感觉专业了不少?😎


实体建模才是持久化的灵魂

很多人以为“只要加了 @Entity 就万事大吉”,其实错了。 实体模型的质量,决定了整个系统的可维护性和扩展性

实体类基本规范:别小看这几个注解

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username", nullable = false, length = 50)
    private String username;

    @Column(name = "email", unique = true)
    private String email;
}

重点来了:

  • @Entity :声明这是一个JPA实体
  • @Table :指定表名,不写则默认类名转小写下划线
  • @Id :必须有且仅有一个主键
  • @GeneratedValue :主键生成策略

说到主键策略,这里有个大坑要特别注意!

主键生成策略怎么选?
策略 适合场景 注意事项
IDENTITY MySQL AUTO_INCREMENT 分布式环境慎用
SEQUENCE Oracle/PostgreSQL 高并发友好
TABLE 跨数据库兼容 性能较差
AUTO 快速上手 不可控

⚠️ 在分布式或高并发环境下,建议避免 IDENTITY ,因为它会导致ID间隙过大甚至冲突。

更好的选择是使用 UUID 或 Snowflake 算法生成全局唯一ID。


嵌入式对象:别重复建模了!

假设你有多个实体都要用到地址信息——用户收货地址、公司注册地址、仓库位置……难道每个都复制一遍字段?

Nope!用 @Embeddable 才是正道。

@Embeddable
public class Address {
    @Column(name = "street") private String street;
    @Column(name = "city") private String city;
    @Column(name = "zip_code") private String zipCode;
}

@Entity
public class Customer {
    @Id private Long id;

    @Embedded
    private Address billingAddress;

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "street", column = @Column(name = "shipping_street")),
        @AttributeOverride(name = "city", column = @Column(name = "shipping_city"))
    })
    private Address shippingAddress;
}

这样数据库里的 Customer 表就会有这些列:

  • billing_address_street
  • billing_address_city
  • shipping_street
  • shipping_city

完美复用,还不影响查询性能!


枚举类型怎么存?ORDINAL很危险!

你是不是经常这么干?

@Enumerated(EnumType.ORDINAL)
private Role role; // ADMIN=0, USER=1, GUEST=2

听着挺合理,但如果哪天你要在中间插个 MODERATOR 角色呢?原来的 USER=1 就变成 MODERATOR=1 了,所有历史数据全乱套!

所以永远记住:

✅ 使用 EnumType.STRING 存储枚举名称

@Enumerated(EnumType.STRING)
private Role role; // "ADMIN", "USER", "GUEST"

更高级的做法是用 AttributeConverter 自定义编码:

@Converter
public class RoleAttributeConverter implements AttributeConverter<Role, String> {
    @Override
    public String convertToDatabaseColumn(Role role) {
        return switch (role) {
            case ADMIN -> "A";
            case USER  -> "U";
            case GUEST -> "G";
        };
    }

    @Override
    public Role convertToEntityAttribute(String dbData) {
        return switch (dbData) {
            case "A" -> Role.ADMIN;
            case "U" -> Role.USER;
            case "G" -> Role.GUEST;
            default -> throw new IllegalArgumentException("Unknown value: " + dbData);
        };
    }
}

然后在实体中启用:

@Convert(converter = RoleAttributeConverter.class)
private Role role;

这种方式既节省空间又便于与其他系统对接。


CRUD不只是增删改查那么简单

你以为继承 JpaRepository 就完事了?Too young too simple!

save() 方法的真相:到底是insert还是update?

这个问题困扰了无数开发者。

答案是: 看实体状态!

  • 如果 id == null !existsById(id) → INSERT
  • 否则 → UPDATE

但注意!如果传入的对象有ID但不在当前Session缓存中,Hibernate 会先尝试 SELECT 加载一下,再决定是 merge 还是 persist。

这就可能导致 N+1 查询!

所以建议:

✅ 对于已知存在的对象,优先使用 findById() + 修改字段 + save()

而不是盲目传一个带ID的对象进去。


批量操作性能爆炸怎么办?

导入Excel一次插一万条?循环调用 save()

拜托,这样做每条记录都会发起一次SQL,效率极低!

正确姿势是:

userRepository.saveAll(users); // 一次性提交

但这还不够!你还得开启 JDBC 批处理:

spring:
  jpa:
    properties:
      hibernate:
        jdbc:
          batch_size: 50
        order_inserts: true
        order_updates: true

✅ batch_size ≤ 数据库允许的最大参数数量
✅ order_inserts: 让同类型SQL合并发送,提升吞吐量

看看性能对比有多夸张👇

方式 10k条耗时 SQL次数
循环save() ~8,500ms 10,000
saveAll() ~4,200ms 10,000
saveAll()+batch=50 ~950ms 200批次

快了近9倍!这就是配置的力量 💪

流程图展示原理:

flowchart TD
    A[开始导入数据] --> B{数据是否为Iterable?}
    B -->|是| C[调用saveAll()]
    C --> D[Hibernate收集Entities]
    D --> E{达到batch_size?}
    E -->|否| F[继续缓存]
    E -->|是| G[执行PreparedStatement.addBatch()]
    G --> H[定期executeBatch()]
    H --> I[提交事务]
    I --> J[结束]
    F --> D

关联关系建模:小心那些看不见的坑

真正复杂的不是单表操作,而是关联查询。

一对一、一对多、多对多怎么建?

一对多示例:部门与员工
@Entity
public class Department {
    @Id private Long id;
    private String name;

    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
    private List<Employee> employees = new ArrayList<>();
}

@Entity
public class Employee {
    @Id private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "dept_id")
    private Department department;
}

✅ 推荐在 @ManyToOne 侧维护外键,避免多余UPDATE语句

多对多示例:学生选课
@Entity
public class Student {
    @Id private Long id;

    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private Set<Course> courses = new HashSet<>();
}

双向配置时记得一端用 mappedBy ,另一端用 @JoinTable


FetchType.LAZY 的陷阱:LazyInitializationException

最经典的报错之一:

org.hibernate.LazyInitializationException: 
failed to lazily initialize a collection of role...

原因很简单:你在事务关闭后访问了懒加载字段。

解决方案有三种:

1️⃣ 使用 @EntityGraph 提前加载
2️⃣ 在Service层提前初始化
3️⃣ 返回DTO而非实体

推荐做法:

@EntityGraph(attributePaths = { "orders", "profile" })
Optional<User> findById(Long id);

或者干脆返回投影对象:

interface UserInfoDto {
    String getName();
    String getEmail();
}

彻底规避实体暴露风险。


动态查询才是业务的灵魂

前端搜索框一堆条件,你怎么应对?

方法命名查询:强大但有限

List<User> findByNameOrEmail(String name, String email);
Page<User> findByCreatedAtAfter(LocalDateTime date, Pageable pageable);

Spring Data JPA 会自动解析成 JPQL。

支持关键字包括:

关键字 操作
And / Or 逻辑与/或
Between 区间判断
Like 模糊匹配
In / NotIn 集合包含
IsNull / IsNotNull 空值判断

但它也有局限:

❌ 不支持深层嵌套过滤
❌ 无法动态组合条件

这时候就得请出 Specifications 了!


Specifications:动态拼接查询条件

public class UserSpecs {
    public static Specification<User> hasStatus(String status) {
        return (root, query, cb) -> 
            cb.equal(root.get("status"), status);
    }

    public static Specification<User> nameContains(String keyword) {
        return (root, query, cb) -> 
            cb.like(cb.lower(root.get("name")), "%" + keyword.toLowerCase() + "%");
    }
}

组合使用:

Specification<User> spec = Specification.where(UserSpecs.hasStatus("ACTIVE"))
                                        .and(UserSpecs.nameContains("john"));

List<User> results = userRepository.findAll(spec);

生成等价SQL:

SELECT u FROM User u 
WHERE u.status = 'ACTIVE' AND LOWER(u.name) LIKE '%john%'

完全动态,零硬编码SQL,还能单元测试,香不香?😍


事务管理:别让数据一致性崩塌

@Transactional 的传播行为怎么选?

行为 说明
REQUIRED 有则加入,无则新建(默认)
REQUIRES_NEW 总是新建事务,挂起当前
SUPPORTS 支持当前事务,但不要求
NEVER 不允许事务存在

典型应用场景:

@Service
public class OrderService {
    @Transactional
    public void createOrder(Order order) {
        orderRepo.save(order);
        inventoryService.deduct(); // 复用同一事务
        auditLogService.log();     // 新事务,失败不影响主流程
    }
}

@Service
class AuditLogService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void log() { ... } // 日志独立事务
}

回滚规则:不是所有异常都会回滚!

默认只对 RuntimeException 回滚。如果你抛的是 Exception 子类(比如 IOException ),事务是不会自动回滚的!

解决办法:

@Transactional(rollbackFor = BusinessException.class)
public void process() throws BusinessException {
    if (balance < amount) {
        throw new BusinessException("余额不足");
    }
}

这样就能精准控制哪些业务异常需要回滚。


性能优化:N+1查询怎么破?

最常见的性能杀手就是 N+1 查询。

例如:

List<Author> authors = repo.findAll();
authors.forEach(a -> System.out.println(a.getBooks().size())); // 每个作者触发一次查询

解决方案:

✅ 使用 @EntityGraph

@EntityGraph(attributePaths = "books")
List<Author> findAllWithBooks();

✅ 或者用 JOIN FETCH

@Query("SELECT a FROM Author a LEFT JOIN FETCH a.books")
List<Author> findAllWithBooks();

都能生成一条带JOIN的SQL,一次性拉取所有数据。


生产部署前必做的10件事 ✅

最后送大家一份《上线前审查清单》,建议收藏打印贴工位!

检查项 是否完成
所有频繁查询字段已建立索引
外键约束已在数据库定义
FetchType 设置合理
分页禁用大OFFSET
启用慢查询日志
连接池大小合理
二级缓存命中率监控
唯一索引防重复提交
EXPLAIN分析关键SQL
乐观锁版本号字段存在
EXPLAIN SELECT * FROM posts WHERE author_id = 100 AND status = 'PUBLISHED';

确保输出显示 type=ref index ,绝不能是 ALL 全表扫描!


结语:技术没有银弹,只有权衡

Spring Boot + Spring Data JPA 确实极大地提升了开发效率,但它不是万能药。

真正的高手,不是只会用框架的人,而是知道它什么时候该用、什么时候不该用、出了问题怎么快速定位的人。

希望这篇文章能帮你建立起一套完整的认知体系,下次面对数据库瓶颈时,不再是慌张地重启服务,而是冷静地说一句:

“让我看看是哪里的查询没走索引。” 😎

Keep coding, stay awesome! 💻✨

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:在现代Java Web开发中,Spring Boot凭借其自动配置和快速启动特性广受青睐,而Spring Data JPA作为Spring生态中的核心数据访问组件,显著简化了JPA的使用。本教程详细讲解如何在Spring Boot项目中整合Spring Data JPA,涵盖依赖引入、数据库配置、Repository接口定义、自定义查询方法及事务管理等内容。通过实际代码示例,帮助开发者快速构建高效、简洁的数据持久化层,并可结合Actuator、Security等模块提升应用的可维护性与安全性。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

先展示下效果 https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方和的例子。 简单的平方和问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值