You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate JPA校验删除MySQL数据时出现SQL语法错误求助

嘿,我来帮你搞定这个SQL语法错误的问题!你遇到的情况是JPA生成的SQL漏了等于号,导致MySQL报1064错误,大概率是查询方法的写法或者JPQL语句出了问题。咱们一步步来修正:

1. 先确认数据库表结构

首先确保你的santa_connections表结构是正确的,以下是符合需求的DDL语句:

CREATE TABLE santa_connections (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    santa_name VARCHAR(255) NOT NULL,
    santa_last_name VARCHAR(255) NOT NULL,
    reciving_participant_name VARCHAR(255) NOT NULL,
    reciving_participant_last_name VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2. JPA实体类(SantaConnection.java)

实体类要和数据库表字段一一对应,注意映射注解的正确性:

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "santa_connections")
public class SantaConnection {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "santa_name", nullable = false)
    private String santaName;

    @Column(name = "santa_last_name", nullable = false)
    private String santaLastName;

    @Column(name = "reciving_participant_name", nullable = false)
    private String recivingParticipantName;

    @Column(name = "reciving_participant_last_name", nullable = false)
    private String recivingParticipantLastName;

    @Column(name = "created_at")
    private LocalDateTime createdAt;

    // 空参构造函数(JPA必需)
    public SantaConnection() {}

    // Getter & Setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getSantaName() { return santaName; }
    public void setSantaName(String santaName) { this.santaName = santaName; }
    public String getSantaLastName() { return santaLastName; }
    public void setSantaLastName(String santaLastName) { this.santaLastName = santaLastName; }
    public String getRecivingParticipantName() { return recivingParticipantName; }
    public void setRecivingParticipantName(String recivingParticipantName) { this.recivingParticipantName = recivingParticipantName; }
    public String getRecivingParticipantLastName() { return recivingParticipantLastName; }
    public void setRecivingParticipantLastName(String recivingParticipantLastName) { this.recivingParticipantLastName = recivingParticipantLastName; }
    public LocalDateTime getCreatedAt() { return createdAt; }
    public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}
3. DAO层(SantaConnectionRepository.java)

这里提供两种正确的实现方式,同时指出你可能踩的坑:

方式一:Spring Data JPA方法命名(推荐,避免手写语法错误)

严格按照Spring Data的命名规范编写方法,它会自动生成正确的SQL:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Transactional;

public interface SantaConnectionRepository extends JpaRepository<SantaConnection, Long> {

    @Modifying
    @Transactional
    void deleteBySantaNameOrRecivingParticipantNameAndSantaLastNameOrRecivingParticipantLastName(
            String santaName, String recivingParticipantName,
            String santaLastName, String recivingParticipantLastName);
}

调用示例:

// 传入对应参数,实现需求中的删除逻辑
santaConnectionRepository.deleteBySantaNameOrRecivingParticipantNameAndSantaLastNameOrRecivingParticipantLastName(
    "Oscar", "Oscar", "Martinez", "Martinez"
);

你可能犯的错误:

如果方法命名拼写错误(比如把字段名写错),或者逻辑运算符顺序混乱,JPA无法正确解析,就会生成缺失=的错误SQL。

方式二:手写@Query注解(适合复杂条件)

如果方法命名太冗长,也可以直接写JPQL或原生SQL,注意语法完整性:

JPQL版本

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

public interface SantaConnectionRepository extends JpaRepository<SantaConnection, Long> {

    @Modifying
    @Transactional
    @Query("DELETE FROM SantaConnection sc WHERE " +
            "(sc.santaName = :name OR sc.recivingParticipantName = :name) " +
            "AND (sc.santaLastName = :lastName OR sc.recivingParticipantLastName = :lastName)")
    void deleteByMatchingNameAndLastName(@Param("name") String name, @Param("lastName") String lastName);
}

调用示例:

santaConnectionRepository.deleteByMatchingNameAndLastName("Oscar", "Martinez");

原生SQL版本

@Modifying
@Transactional
@Query(value = "DELETE FROM santa_connections WHERE " +
        "(santa_name = :name OR reciving_participant_name = :name) " +
        "AND (santa_last_name = :lastName OR reciving_participant_last_name = :lastName)",
        nativeQuery = true)
void deleteByMatchingNameAndLastNameNative(@Param("name") String name, @Param("lastName") String lastName);

你可能犯的错误:

手写时漏写=号(比如写成sc.santaName :name),或者实体类属性名和数据库列名混淆,都会导致SQL语法错误。

4. 错误原因总结

你遇到的SQL Error: 1064本质是生成的SQL缺失了=运算符,常见诱因:

  • Spring Data方法命名不符合规范,导致JPA解析失败;
  • 手写@Query语句时漏写=或参数绑定错误;
  • 实体类字段和数据库列名映射不匹配,导致生成的SQL列名错误。
5. 注意事项
  • 删除操作属于修改类操作,必须加上@Modifying和@Transactional注解,否则Spring Data JPA会报错;
  • 如果使用原生SQL,要确保表名、列名和数据库完全一致;
  • 测试时可以开启JPA的SQL日志(比如在application.yml中设置spring.jpa.show-sql: true),直接查看生成的SQL语句,快速定位问题。

内容的提问来源于stack exchange,提问作者MajkelEight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:17:09