<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://hyun7en.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://hyun7en.github.io/" rel="alternate" type="text/html" /><updated>2026-03-29T08:59:25+00:00</updated><id>https://hyun7en.github.io/feed.xml</id><title type="html">Hyun Dev Blog</title><subtitle>Backend Study Log — Spring · DevOps · Algorithm · CS</subtitle><author><name>Hyun</name></author><entry><title type="html">Spring Boot + JPA 시작하기</title><link href="https://hyun7en.github.io/spring/2026/02/16/first-post.html" rel="alternate" type="text/html" title="Spring Boot + JPA 시작하기" /><published>2026-02-16T00:00:00+00:00</published><updated>2026-02-16T00:00:00+00:00</updated><id>https://hyun7en.github.io/spring/2026/02/16/first-post</id><content type="html" xml:base="https://hyun7en.github.io/spring/2026/02/16/first-post.html"><![CDATA[<p>Spring Boot와 JPA를 활용하면 데이터베이스 연동을 매우 간결하게 처리할 수 있습니다.
이번 글에서는 기본 설정부터 간단한 CRUD API 구현까지 정리해보겠습니다.</p>

<h2 id="환경-설정">환경 설정</h2>

<p><code class="language-plaintext highlighter-rouge">build.gradle</code>에 의존성을 추가합니다.</p>

<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="n">dependencies</span> <span class="o">{</span>
    <span class="n">implementation</span> <span class="s1">'org.springframework.boot:spring-boot-starter-data-jpa'</span>
    <span class="n">implementation</span> <span class="s1">'org.springframework.boot:spring-boot-starter-web'</span>
    <span class="n">runtimeOnly</span> <span class="s1">'com.h2database:h2'</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">application.yml</code> 설정:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="na">spring</span><span class="pi">:</span>
  <span class="na">datasource</span><span class="pi">:</span>
    <span class="na">url</span><span class="pi">:</span> <span class="s">jdbc:h2:mem:testdb</span>
    <span class="na">driver-class-name</span><span class="pi">:</span> <span class="s">org.h2.Driver</span>
  <span class="na">jpa</span><span class="pi">:</span>
    <span class="na">hibernate</span><span class="pi">:</span>
      <span class="na">ddl-auto</span><span class="pi">:</span> <span class="s">create-drop</span>
    <span class="na">show-sql</span><span class="pi">:</span> <span class="no">true</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="entity-작성">Entity 작성</h2>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="rouge-code"><pre><span class="nd">@Entity</span>
<span class="nd">@Getter</span>
<span class="nd">@NoArgsConstructor</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Post</span> <span class="o">{</span>

    <span class="nd">@Id</span>
    <span class="nd">@GeneratedValue</span><span class="o">(</span><span class="n">strategy</span> <span class="o">=</span> <span class="nc">GenerationType</span><span class="o">.</span><span class="na">IDENTITY</span><span class="o">)</span>
    <span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span>

    <span class="kd">private</span> <span class="nc">String</span> <span class="n">title</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">content</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">Post</span><span class="o">(</span><span class="nc">String</span> <span class="n">title</span><span class="o">,</span> <span class="nc">String</span> <span class="n">content</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">title</span> <span class="o">=</span> <span class="n">title</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">content</span> <span class="o">=</span> <span class="n">content</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="repository">Repository</h2>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">PostRepository</span> <span class="kd">extends</span> <span class="nc">JpaRepository</span><span class="o">&lt;</span><span class="nc">Post</span><span class="o">,</span> <span class="nc">Long</span><span class="o">&gt;</span> <span class="o">{</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">JpaRepository</code>를 상속하는 것만으로 <code class="language-plaintext highlighter-rouge">save()</code>, <code class="language-plaintext highlighter-rouge">findById()</code>, <code class="language-plaintext highlighter-rouge">findAll()</code>, <code class="language-plaintext highlighter-rouge">deleteById()</code> 등의 기본 CRUD 메서드를 사용할 수 있습니다.</p>

<h2 id="service">Service</h2>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="rouge-code"><pre><span class="nd">@Service</span>
<span class="nd">@RequiredArgsConstructor</span>
<span class="nd">@Transactional</span><span class="o">(</span><span class="n">readOnly</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">PostService</span> <span class="o">{</span>

    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">PostRepository</span> <span class="n">postRepository</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Post</span><span class="o">&gt;</span> <span class="nf">findAll</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">postRepository</span><span class="o">.</span><span class="na">findAll</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="nd">@Transactional</span>
    <span class="kd">public</span> <span class="nc">Post</span> <span class="nf">save</span><span class="o">(</span><span class="nc">String</span> <span class="n">title</span><span class="o">,</span> <span class="nc">String</span> <span class="n">content</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">postRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="k">new</span> <span class="nc">Post</span><span class="o">(</span><span class="n">title</span><span class="o">,</span> <span class="n">content</span><span class="o">));</span>
    <span class="o">}</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="핵심-포인트">핵심 포인트</h2>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">@Transactional(readOnly = true)</code>를 클래스 레벨에 붙이고,
쓰기 작업에만 <code class="language-plaintext highlighter-rouge">@Transactional</code>을 추가하는 패턴이 일반적입니다.</p>
</blockquote>

<table>
  <thead>
    <tr>
      <th>어노테이션</th>
      <th>역할</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">@Entity</code></td>
      <td>JPA 관리 객체로 등록</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">@Id</code></td>
      <td>Primary Key 지정</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">@GeneratedValue</code></td>
      <td>ID 자동 생성 전략</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">@Transactional</code></td>
      <td>트랜잭션 범위 설정</td>
    </tr>
  </tbody>
</table>

<h2 id="정리">정리</h2>

<ul>
  <li>JPA는 SQL 대신 객체 중심으로 DB를 다룰 수 있게 해준다</li>
  <li><code class="language-plaintext highlighter-rouge">JpaRepository</code> 상속만으로 기본 CRUD를 사용할 수 있다</li>
  <li><code class="language-plaintext highlighter-rouge">@Transactional</code> 관리는 서비스 레이어에서 담당하는 것이 원칙이다</li>
</ul>]]></content><author><name>Hyun</name></author><category term="Spring" /><category term="Java" /><category term="Spring Boot" /><category term="JPA" /><category term="ORM" /><summary type="html"><![CDATA[Spring Boot와 JPA를 이용해 간단한 CRUD API를 만드는 과정을 정리합니다.]]></summary></entry></feed>