DEV Community

tumit
tumit

Posted on

P6Spy - มา debug SQL command จาก JPA

เวลาเราใช้ Spring Data ปัญหาที่เราจะเจอกันบ่อย ๆ คือ พอมีปัญหาอยาก debug เราอยากรู้ว่า ไอ้ JPQL หรือ query ที่มาจาก method name strategy จริงแล้วมัน run SQL command อะไรกันแน่ ทำไงดี

ข้อควรระวัง

ถ้าเป็นไปได้ควรใช้แค่ none-prod env เท่านั้น หรือถ้าจะใช้ใน prod ให้ระวังเพิ่มอีกนิดเพราะอาจจะมีปัญหาเรื่อง sensitive information ใน log ได้

ท่าปกติ : spring.jpa.show-sql=true

ในที่นี้เราใช้ Spring Boot (เป็นท่ามาตราฐานของ Java ไปแล้วมั้ง) สมมุติว่าเรามี code ไว้สำหรับ CRUD ข้อมูลใน DB หน้าตาประมาณนี้

Entity

package ga.tumit.p6spyspbdemo.member;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Getter
@Setter
@Entity(name = "MEMBER")
public class MemberEntity {

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

    private String memberName;
}
Enter fullscreen mode Exit fullscreen mode

Repository

public interface MemberRepository extends JpaRepository<MemberEntity, Long> { }
Enter fullscreen mode Exit fullscreen mode

Test

package ga.tumit.p6spyspbdemo.member;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
public class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    void findById() {
        long id = 999L;
        Optional<MemberEntity> member = memberRepository.findById(id);
        assertThat(member.isPresent()).isFalse();
    }
}
Enter fullscreen mode Exit fullscreen mode

ถ้าเราอยากจะ debug SQL command ก็สามารถ enable ของ show-sql ได้ประมาณนี้

# enable show-sql
spring.jpa.show-sql=true
Enter fullscreen mode Exit fullscreen mode

เราก็จะได้ log หน้าตาประมาณนี้

Hibernate: select memberenti0_.member_id as member_i1_0_0_, memberenti0_.member_name as member_n2_0_0_ from member memberenti0_ where memberenti0_.member_id=?
Enter fullscreen mode Exit fullscreen mode

แต่ชีวิตมันไม่ง่ายเหมือนบะหมี่กึ่งสำเร็จรูป ข้อเสียของ option นี้คือมันแค่ log ที่เป็น query command เท่านั้น เช่นในตัวอย่างจะได้แค่

where memberenti0_.member_id=?
Enter fullscreen mode Exit fullscreen mode

ในส่วนของ params ต้องไปนั่งไล่ใส่เองซึ่งในการ debug มันก็ยังไม่ง่ายเท่าไหร่นัก เราเลยมีตัวช่วยคือ p6spy นั้นเองงงง

ท่าเพิ่มเติม: p6spy

เป็น lib ที่ทำตัวเหมือน proxy ช่วยในการเพิ่ม params เข้าไปใน log ให้เราสามารถเอาไป debug ได้ง่ายขึ้น โดยเฉพาะตัวอย่างนี้ที่เป็น Spring Boot เราสามารถเพิ่ม dependencies

ผป

implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.8.0'
Enter fullscreen mode Exit fullscreen mode

แล้ว config application.properties เพิ่มอีกนิด เพราะค่า default log มีข้อมูลเกินความต้องการไปนิด (log format ไปตามดูได้ในอ้างอิงเด้อ ~)

# p6spy config
decorator.datasource.p6spy.log-format=%(category): %(sql)
Enter fullscreen mode Exit fullscreen mode

เราก็จะได้ log หน้าตาประมาณนี้

Hibernate: select memberenti0_.member_id as member_i1_0_0_, memberenti0_.member_name as member_n2_0_0_ from member memberenti0_ where memberenti0_.member_id=?
2022-02-04 09:10:56  INFO  p6spy.logSQL:60 - statement: select memberenti0_.member_id as member_i1_0_0_, memberenti0_.member_name as member_n2_0_0_ from member memberenti0_ where memberenti0_.member_id=999
2022-02-04 09:10:56  INFO  p6spy.logSQL:60 - commit: 
Enter fullscreen mode Exit fullscreen mode

เราก็จะได้ log SQL ที่มี param มา debug ได้อย่างสวยงามมมมม

where memberenti0_.member_id=999
Enter fullscreen mode Exit fullscreen mode

อ้างอิง

Latest comments (0)