1. MySql Dirver 설정

 

2. application.properties 설정

# MySQL 연결 설정
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=jeonghun90
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA 설정
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

 

 

추가 정보: spring.jpa.hibernate.ddl-auto=update 옵션

728x90
반응형

1. Entity FrameWork Core를 설치한다.

2. Model을 선언한다.
3. DbSet를 선언한다.

- AppDbContext.cs
4. Service를 선언한다.

- IService.cs, Service.cs

5. Service를 등록한다.

- Program.cs 또는 StartUp.cs

6. Service 호출

- Controller 생성자 주입을 통해 사용한다.


 키지 설:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools 
// visual studio -> 도구 -> NetGet 패키지 관리자 -> 패키지 관리자 콘솔

Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools

 

// Terminal

dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

 


1단계: Model (엔티티) 정의

데이터베이스 테이블에 매핑될 객체입니다.

  • 파일: Models/TodoItem.cs
// Models/TodoItem.cs
using System;
using System.ComponentModel.DataAnnotations; // 데이터 어노테이션 사용

namespace CoreMVC.Models
{
    public class TodoItem
    {
        // 기본 키 (EF Core가 Id로 인식)
        public int Id { get; set; }

        // 제목 (필수, 최대 길이 100)
        [Required(ErrorMessage = "제목은 필수입니다.")]
        [StringLength(100, ErrorMessage = "제목은 최대 100자까지 가능합니다.")]
        public string Title { get; set; } = string.Empty; // C# 8.0+ Nullable Reference Types 대응

        // 완료 여부
        public bool IsDone { get; set; }

        // 생성 일자
        public DateTime CreatedDate { get; set; } = DateTime.Now; // 기본값으로 현재 시간 설정
    }
}

 

2단계: Entity Framework Core DbContext 설정

데이터베이스와 통신하는 핵심 클래스입니다.

  • 파일: Data/AppDbContext.cs (또는 Models/AppDbContext.cs)
// Data/AppDbContext.cs
using Microsoft.EntityFrameworkCore;
using CoreMVC.Models; // TodoItem 모델 참조

namespace CoreMVC.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options)
            : base(options)
        {
        }	

        // TodoItem 엔티티를 위한 DbSet
        public DbSet<TodoItem> TodoItems { get; set; }
        public DbSet<TodoItemSummary> TodoItemSummaries { get; set; } = null!;
    }
}

 

3단계: Service Interface 정의

서비스의 계약을 정의합니다. 구현체와 느슨하게 결합될 수 있도록 합니다.

  • 파일: Interfaces/ITodoService.cs (필요하다면 Interfaces 폴더 생성)
// Interfaces/ITodoService.cs
using CoreMVC.Models; // TodoItem 모델 참조
using System.Collections.Generic;
using System.Threading.Tasks; // 비동기 메서드를 위해 필요

namespace CoreMVC.Interfaces
{
    public interface ITodoService
    {
        Task<List<TodoItem>> GetAllTodoItemsAsync();
        Task<TodoItem?> GetTodoItemByIdAsync(int id);
        Task AddTodoItemAsync(TodoItem todo);
        Task UpdateTodoItemAsync(TodoItem todo);
        Task DeleteTodoItemAsync(int id);
        Task ToggleTodoItemStatusAsync(int id);
        
        Task<IEnumerable<TodoItem>> GetAllTodoItemsAsync();
        Task<TodoItemSummary?> GetTodoItemSummaryAsync();
        Task<IEnumerable<TodoItem>> SearchTodoItemsByTitleAsync(string searchTerm);
    }
}

 

4단계: Service Implementation (ServiceImpl) 구현

ITodoService 인터페이스를 구현하며, AppDbContext를 사용하여 실제 데이터베이스 작업을 수행합니다.

  • 파일: Services/TodoService.cs (필요하다면 Services 폴더 생성)
// Services/TodoService.cs
using CoreMVC.Data; // AppDbContext 참조
using CoreMVC.Interfaces; // ITodoService 참조
using CoreMVC.Models; // TodoItem 모델 참조
using Microsoft.EntityFrameworkCore; // 비동기 메서드 (ToListAsync, FirstOrDefaultAsync 등)를 위해 필요
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CoreMVC.Services
{
    public class TodoService : ITodoService // 인터페이스 구현
    {
        private readonly AppDbContext _context; // DbContext 주입 필드

        // 생성자 주입을 통해 AppDbContext 인스턴스를 받습니다.
        public TodoService(AppDbContext context)
        {
            _context = context;
        }

        public async Task<List<TodoItem>> GetAllTodoItemsAsync()
        {
            return await _context.TodoItems.OrderByDescending(t => t.Id).ToListAsync();
        }

        public async Task<TodoItem?> GetTodoItemByIdAsync(int id)
        {
            return await _context.TodoItems.FirstOrDefaultAsync(t => t.Id == id);
        }

        public async Task AddTodoItemAsync(TodoItem todo)
        {
            // Id는 데이터베이스에서 자동 증가 컬럼으로 설정되므로, 따로 할당할 필요 없음.
            // todo.CreatedDate는 모델에서 기본값이 설정되어 있습니다.
            _context.TodoItems.Add(todo);
            await _context.SaveChangesAsync(); // 데이터베이스에 저장
        }

        public async Task UpdateTodoItemAsync(TodoItem todo)
        {
            _context.TodoItems.Update(todo); // EF Core의 변경 추적 기능 활용
            await _context.SaveChangesAsync(); // 데이터베이스에 저장
        }

        public async Task DeleteTodoItemAsync(int id)
        {
            var todo = await _context.TodoItems.FirstOrDefaultAsync(t => t.Id == id);
            if (todo != null)
            {
                _context.TodoItems.Remove(todo);
                await _context.SaveChangesAsync(); // 데이터베이스에 저장
            }
        }

        public async Task ToggleTodoItemStatusAsync(int id)
        {
            var todo = await _context.TodoItems.FirstOrDefaultAsync(t => t.Id == id);
            if (todo != null)
            {
                todo.IsDone = !todo.IsDone; // 상태 토글
                _context.TodoItems.Update(todo); // 변경 감지
                await _context.SaveChangesAsync(); // 데이터베이스에 저장
            }
        }
        
        
        
        /// <summary>
        /// 저장 프로시저 사용
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<TodoItem>> GetAllTodoItemsAsync()
        {
            // 여기에서 저장 프로시저 호출 로직을 캡슐화
            return await _context.TodoItems.FromSqlRaw("EXEC sp_GetAllTodoItems").ToListAsync();
        }

        /// <summary>
        /// 저장 프로시저 사용
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<TodoItem>> SearchTodoItemsByTitleAsync(string searchTerm)
        {
            return await _context.TodoItems.FromSqlInterpolated($"EXEC sp_GetTodoItemsByTitle {searchTerm}").ToListAsync();
        }

        /// <summary>
        /// 저장 프로시저 사용
        /// </summary>
        /// <returns></returns>
        public async Task<TodoItemSummary?> GetTodoItemSummaryAsync()
        {
            var result = await _context.TodoItemSummaries.FromSqlRaw("EXEC sp_GetTodoItemSummary").ToListAsync();
            return result.FirstOrDefault();
        }
    
    
    }
}

 

5단계: 애플리케이션 시작 및 서비스 등록 (Program.cs)

서비스(DI) 및 HTTP 요청 파이프라인을 설정합니다.

  • 파일: Program.cs
// Program.cs
using Microsoft.EntityFrameworkCore;
using CoreMVC.Data; // AppDbContext 참조
using CoreMVC.Interfaces; // ITodoService 참조
using CoreMVC.Services; // TodoService 구현체 참조

var builder = WebApplication.CreateBuilder(args);

// appsettings.json에서 데이터베이스 연결 문자열 설정
// "ConnectionStrings": {
//   "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=CoreMVCTodoDb;Trusted_Connection=True;MultipleActiveResultSets=true"
// }
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// 서비스 등록
builder.Services.AddControllersWithViews(); // MVC 컨트롤러 및 뷰 서비스

// ITodoService 인터페이스에 TodoService 구현체를 Scoped 서비스로 등록
// DbContext가 Scoped이므로, 이를 사용하는 TodoService도 Scoped로 등록하는 것이 일반적입니다.
builder.Services.AddScoped<ITodoService, TodoService>();

var app = builder.Build();

// HTTP 요청 파이프라인 설정
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

 

6단계: 컨트롤러 구현 (Controllers/TodoController.cs)

HTTP 요청을 받아 서비스를 통해 비즈니스 로직을 수행하고 뷰를 반환합니다.

  • 파일: Controllers/TodoController.cs (기존 HomeController.cs를 수정하거나 새 파일 생성)
// Controllers/TodoController.cs
using Microsoft.AspNetCore.Mvc;
using CoreMVC.Models; // TodoItem 모델 참조
using CoreMVC.Interfaces; // ITodoService 참조
using System.Threading.Tasks;
using System.Collections.Generic;

namespace CoreMVC.Controllers
{
    public class TodoController : Controller
    {
        private readonly ITodoService _todoService; // 인터페이스를 통해 서비스 주입

        // 생성자 주입
        public TodoController(ITodoService todoService)
        {
            _todoService = todoService;
        }

        // 모든 TodoItem 목록 표시 (GET: /Todo)
        public async Task<IActionResult> Index()
        {
            //var todos = await _todoService.SearchTodoItemsByTitleAsync("t");
            //var todos = await _todoService.GetAllTodoItemsAsync();
            //var todoSummary = await _todoService.GetTodoItemSummaryAsync();
        
            var todoItems = await _todoService.GetAllTodoItemsAsync();
            return View(todoItems);
        }

        // 특정 TodoItem 상세 정보 표시 (GET: /Todo/Details/5)
        public async Task<IActionResult> Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var todoItem = await _todoService.GetTodoItemByIdAsync(id.Value);
            if (todoItem == null)
            {
                return NotFound();
            }
            return View(todoItem);
        }

        // 새로운 TodoItem 생성 폼 (GET: /Todo/Create)
        public IActionResult Create()
        {
            return View();
        }

        // 새로운 TodoItem 생성 처리 (POST: /Todo/Create)
        [HttpPost]
        [ValidateAntiForgeryToken] // CSRF 방어
        public async Task<IActionResult> Create([Bind("Title,IsDone")] TodoItem todoItem)
        {
            if (ModelState.IsValid) // 모델 유효성 검사 (데이터 어노테이션 기반)
            {
                todoItem.CreatedDate = DateTime.Now; // 생성일자는 서버에서 설정
                await _todoService.AddTodoItemAsync(todoItem);
                TempData["SuccessMessage"] = "TodoItem이 성공적으로 추가되었습니다!"; // 성공 메시지
                return RedirectToAction(nameof(Index)); // 목록 페이지로 리다이렉트
            }
            return View(todoItem); // 유효성 검사 실패 시 폼 다시 보여주기
        }

        // TodoItem 수정 폼 (GET: /Todo/Edit/5)
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var todoItem = await _todoService.GetTodoItemByIdAsync(id.Value);
            if (todoItem == null)
            {
                return NotFound();
            }
            return View(todoItem);
        }

        // TodoItem 수정 처리 (POST: /Todo/Edit/5)
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("Id,Title,IsDone,CreatedDate")] TodoItem todoItem)
        {
            if (id != todoItem.Id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    await _todoService.UpdateTodoItemAsync(todoItem);
                    TempData["SuccessMessage"] = "TodoItem이 성공적으로 수정되었습니다!";
                }
                catch (DbUpdateConcurrencyException) // 동시성 문제 처리 (필요시)
                {
                    if (await _todoService.GetTodoItemByIdAsync(todoItem.Id) == null)
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(todoItem);
        }

        // TodoItem 삭제 확인 폼 (GET: /Todo/Delete/5)
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var todoItem = await _todoService.GetTodoItemByIdAsync(id.Value);
            if (todoItem == null)
            {
                return NotFound();
            }
            return View(todoItem);
        }

        // TodoItem 삭제 처리 (POST: /Todo/Delete/5)
        [HttpPost, ActionName("Delete")] // 액션 이름을 DeleteConfirmed로 변경하여 오버로딩 회피
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            await _todoService.DeleteTodoItemAsync(id);
            TempData["SuccessMessage"] = "TodoItem이 성공적으로 삭제되었습니다!";
            return RedirectToAction(nameof(Index));
        }

        // TodoItem 상태 토글 (GET 또는 POST, 간단히 GET으로 예시)
        public async Task<IActionResult> ToggleStatus(int id)
        {
            await _todoService.ToggleTodoItemStatusAsync(id);
            TempData["SuccessMessage"] = "TodoItem 상태가 변경되었습니다!";
            return RedirectToAction(nameof(Index));
        }
    }
}

 

7단계: 뷰(Views) 생성

TodoItem 데이터를 표시하고 상호작용하기 위한 Razor View 파일들을 생성합니다.

  • 폴더: Views/Todo/ (새 폴더 생성)

7.1. Views/Todo/Index.cshtml (목록)

@model IEnumerable<CoreMVC.Models.TodoItem>

@{
    ViewData["Title"] = "할 일 목록";
}

<h1>@ViewData["Title"]</h1>

<p>
    <a asp-action="Create" class="btn btn-primary">새 할 일 추가</a>
</p>

@if (TempData["SuccessMessage"] != null)
{
    <div class="alert alert-success" role="alert">
        @TempData["SuccessMessage"]
    </div>
}

<table class="table table-striped">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.IsDone)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.CreatedDate)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Title)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.IsDone)
                    <a asp-action="ToggleStatus" asp-route-id="@item.Id" class="btn btn-sm @(item.IsDone ? "btn-warning" : "btn-success") ms-2">
                        @(item.IsDone ? "미완료" : "완료")
                    </a>
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.CreatedDate)
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-sm btn-info">수정</a> |
                    <a asp-action="Details" asp-route-id="@item.Id" class="btn btn-sm btn-secondary">상세</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-sm btn-danger">삭제</a>
                </td>
            </tr>
        }
    </tbody>
</table>

 

7.2. Views/Todo/Create.cshtml (생성)

@model CoreMVC.Models.TodoItem

@{
    ViewData["Title"] = "새 할 일 추가";
}

<h1>@ViewData["Title"]</h1>

<h4>TodoItem</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group form-check mt-2">
                <label class="form-check-label">
                    <input class="form-check-input" asp-for="IsDone" /> @Html.DisplayNameFor(model => model.IsDone)
                </label>
            </div>
            <div class="form-group mt-3">
                <input type="submit" value="생성" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div class="mt-3">
    <a asp-action="Index">목록으로 돌아가기</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

 

7.3. Views/Todo/Edit.cshtml (수정)

@model CoreMVC.Models.TodoItem

@{
    ViewData["Title"] = "할 일 수정";
}

<h1>@ViewData["Title"]</h1>

<h4>TodoItem</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Id" />
            <input type="hidden" asp-for="CreatedDate" /> @* CreatedDate는 수정하지 않으므로 hidden으로 유지 *@
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group form-check mt-2">
                <label class="form-check-label">
                    <input class="form-check-input" asp-for="IsDone" /> @Html.DisplayNameFor(model => model.IsDone)
                </label>
            </div>
            <div class="form-group mt-3">
                <input type="submit" value="저장" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div class="mt-3">
    <a asp-action="Index">목록으로 돌아가기</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

 

7.4. Views/Todo/Details.cshtml (상세)

@model CoreMVC.Models.TodoItem

@{
    ViewData["Title"] = "할 일 상세";
}

<h1>@ViewData["Title"]</h1>

<div>
    <h4>TodoItem</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.IsDone)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.IsDone)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.CreatedDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.CreatedDate)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model?.Id" class="btn btn-info">수정</a> |
    <a asp-action="Index" class="btn btn-secondary">목록으로 돌아가기</a>
</div>

 

7.5. Views/Todo/Delete.cshtml (삭제)

@model CoreMVC.Models.TodoItem

@{
    ViewData["Title"] = "할 일 삭제";
}

<h1>@ViewData["Title"]</h1>

<h3>이 할 일을 정말 삭제하시겠습니까?</h3>
<div>
    <h4>TodoItem</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.IsDone)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.IsDone)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.CreatedDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.CreatedDate)
        </dd>
    </dl>

    <form asp-action="Delete">
        <input type="hidden" asp-for="Id" />
        <input type="submit" value="삭제" class="btn btn-danger" /> |
        <a asp-action="Index" class="btn btn-secondary">목록으로 돌아가기</a>
    </form>
</div>

 

 

추가 사항: appsettings.json에서 데이터베이스 연결 문자열 설정

{
  "ConnectionStrings": {
  "DefaultConnection": "Server=127.0.0.1;Database=aspnet;User ID=sa;Password=jeonghun90();TrustServerCertificate=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

 

// Trusted_Connection=True; 윈도우 인증
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=CoreMVCTodoDb;Trusted_Connection=True;MultipleActiveResultSets=true"

 

// 계정 인증
"DefaultConnection": "Server=127.0.0.1;Database=aspnet;User ID=sa;Password=jeonghun90();TrustServerCertificate=True;MultipleActiveResultSets=True"

 

 

추가 사항: 데이터베이스 마이그레이션 적용

프로젝트 루트에서 명령 프롬프트를 열고 다음 명령어를 실행합니다.

  1. 마이그레이션 추가:
dotnet ef migrations add InitialCreate

이 명령은 Migrations 폴더를 생성하고, AppDbContext의 모델 정의를 기반으로 데이터베이스 스키마를 생성하는 코드를 만듭니다. HasData로 정의한 초기 데이터도 여기에 포함됩니다.

 

2. 마이그레이션 적용:

dotnet ef database update

이 명령은 생성된 마이그레이션 스크립트를 데이터베이스에 적용하여 실제 테이블과 초기 데이터를 생성합니다.

 

 

도커(Docker)에 MsSql Server 설치

 

MsSql Server 설치

docker pull mcr.microsoft.com/mssql/server:2022-latest docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=YourStrong@Passw0rd" -e "MSSQL_PID=Developer" -p 1433:1433 --name mssql -d mcr.microsoft.com/mssql/server:2022-latest docker run -e "ACCEPT_EULA=Y" -

jangjeonghun.tistory.com

 

SQL Server Management Studio 설치

 

SQL Server Management Studio 설치

Visual Studio 설치 관리자를 사용하여 SSMS(SQL Server Management Studio)를 설치하는 방법을 알아봅니다.

learn.microsoft.com

 

728x90
반응형

JDK(Java Development Kit) 설치

OpenJDK와 Oracle JDK의 차이점

Oracle JDK와 OpenJDK는 각각 Java 개발 키트로 알려진 소프트웨어와 사양 세트입니다.  Java 11부터 Oracle JDK와 OpenJDK는 Flight Recorder와 Mission Control과 같은 기능을 포함하는 동일한 빌드입니다. 기본적으로 Oracle JDK와 OpenJDK 간의 코드 변경이 거의 없기 때문에 기능적으로 매우 유사합니다. 

OpenJDK와 Oracle JDK의 가장 큰 차이점은 OpenJDK는 오라클, Red Hat, 커뮤니티가 유지 관리하는 오픈소스 프로젝트인 반면, Oracle JDK는 폐쇄형 소스(Closed source)로 유료 라이센스가 필요하며 오라클이 유지 관리한다는 것입니다. 이러한 차이로 인해 OpenJDK에서 일부 기능을 사용할 수 없는데, 이는 해당 기능이 폐쇄형 소스이거나 라이센스로 제한되기 때문입니다.

 

Red Hat build of OpenJDK

https://developers.redhat.com/products/openjdk/download

 

Download the Red Hat Build of OpenJDK | Red Hat Developer

Download the Red Hat Build of OpenJDK at no-cost. The Red Hat build of OpenJDK is an open source implementation of the Java Platform, Standard Edition (Java SE)

developers.redhat.com

Oracle JDK

https://www.oracle.com/kr/java/technologies/downloads/#jdk21-windows

 

Download the Latest Java LTS Free

Subscribe to Java SE and get the most comprehensive Java support available, with 24/7 global access to the experts.

www.oracle.com

Microsoft Build of OpenJDK

https://www.microsoft.com/openjdk

 

Microsoft Build of OpenJDK

The Microsoft Build of OpenJDK is a new no-cost long-term supported distribution and Microsoft’s new way to collaborate and contribute to the Java ecosystem.

www.microsoft.com

 

Java_Home  설정

https://velog.io/@wanny328/Java-%EC%9C%88%EB%8F%84%EC%9A%B0-11-%EC%9E%90%EB%B0%94-%ED%99%88JAVAHOME-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95

 

[Java] 윈도우 11 자바 홈(JAVA_HOME) 설정 방법

윈도우 노트북에 작업 환경 초기 세팅을 진행하며 JAVA_HOME 설정했던 방법을 공유하고자 함시스템 환경 변수 편집을 검색하여 실행합니다.환경변수에 들어가고 시스템 변수에서 새로 만들기를

velog.io

 

확장 프로그램 설치

Extension Pack for Java

728x90
반응형

ASP.NET SDK(Software Development Kit) 설치

https://dotnet.microsoft.com/ko-kr/download

 

.NET 다운로드(Linux, macOS 및 Windows) | .NET

Linux, macOS 및 Windows에서 .NET 앱을 빌드하고 실행하기 위한 무료 다운로드. .NET Framework, .NET 및 ASP.NET용 런타임, SDK 및 개발자 팩.

dotnet.microsoft.com

 

확장 프로그램 설치

Cursor IDE에서는 공식적으로 C# Dev Kit 및 Microsoft C# 확장을 사용할 수 없습니다.(VS Code 에서만 설치 가능)

하여 C#, .NET Install Tool 을 설치한다. 

 

프로젝트 생성

// mvc
dotnet new mvc -o MyMVC

// web API
dotnet new webapi -n MyWebApiWithAuth

// blazor
dotnet new blazor -o MyBlazor

 

.gitignore 생성

// 프로젝트 root path에 파일 생성
.gitignore

.gitignore
0.01MB
.gitattributes
0.00MB

 

Entity Framework Core (EF Core, ORM) 설정

Entity Framework Core 연동(EF Core, ORM)

 

Entity Framework Core 연동(EF Core, ORM)

1. Entity FrameWork Core를 설치한다.2. Model을 선언한다.3. DbSet를 선언한다.- AppDbContext.cs4. Service를 선언한다.- IService.cs, Service.cs5. Service를 등록한다.- Program.cs 또는 StartUp.cs6. Service 호출- Controller 생성자

jangjeonghun.tistory.com

728x90
반응형

네, VS Code에서 Spring Boot 기반의 RESTful API 프로젝트를 실행하여 http://localhost:8080으로 접근할 수 있도록 단계별로 자세히 설명해 드릴게요. 이미 프로젝트가 준비되어 있다는 가정하에 진행하겠습니다.


1단계: 필수 확장 프로그램 확인 및 설치

VS Code에서 Spring Boot 및 Java 프로젝트를 원활하게 개발하고 실행하기 위한 필수 확장 프로그램들이 설치되어 있는지 확인해야 합니다.

  1. VS Code 실행 후 좌측 메뉴에서 '확장 (Extensions)' 아이콘 (사각형 네 개) 클릭
  2. 다음 확장 프로그램들을 검색하여 설치 (만약 설치되어 있지 않다면):
    • Extension Pack for Java (Microsoft): Java 개발에 필요한 핵심 확장 프로그램들을 한 번에 설치해 줍니다. (Language Support for Java™, Debugger for Java, Maven for Java, Gradle for Java, Test Runner for Java 등이 포함됩니다.)
    • Spring Boot Extension Pack (VMware): Spring Boot 개발에 특화된 확장 프로그램들을 모아놓은 팩입니다. (Spring Boot Tools, Spring Boot Dashboard 등이 포함됩니다.)
    특히 중요한 확장 프로그램:
    • Language Support for Java™ by Red Hat: Java 코드 자동 완성, 정의 보기, 리팩토링 등 핵심 기능을 제공합니다.
    • Debugger for Java: Java 코드 디버깅 기능을 제공합니다.
    • Maven for Java 또는 Gradle for Java: (프로젝트 빌드 도구에 따라 선택) 해당 빌드 도구를 사용하여 프로젝트를 관리하고 빌드 태스크를 실행할 수 있게 해줍니다.

2단계: 프로젝트 열기 및 구조 확인

  1. VS Code에서 프로젝트 폴더 열기:
    • File (파일) -> Open Folder... (폴더 열기...) 선택
    • 생성한 Spring Boot 프로젝트의 루트 폴더를 선택하고 Select Folder (폴더 선택) 클릭.
    • (예: my-rest-api-project 폴더)
  2. 프로젝트 구조 확인:
    • 좌측 탐색기(Explorer)에서 프로젝트 구조가 올바르게 로드되었는지 확인합니다.
    • src/main/java 아래에 메인 애플리케이션 클래스 (예: DemoApplication.java)가 있는지 확인합니다.
    • build.gradle (Gradle 사용 시) 또는 pom.xml (Maven 사용 시) 파일이 루트 디렉토리에 있는지 확인합니다.

3단계: 빌드 도구 (Gradle/Maven)를 통한 프로젝트 로드 및 종속성 다운로드

VS Code가 프로젝트를 열면 자동으로 빌드 도구(Gradle 또는 Maven)를 인식하고 필요한 라이브러리(종속성)를 다운로드하며 프로젝트를 빌드합니다.

  1. 자동 로드 확인:
    • VS Code 우측 하단에 "Loding Java projects..." 또는 "Resolving dependencies..."와 같은 메시지가 뜨는 것을 확인할 수 있습니다.
    • 이 과정에서 인터넷 연결이 필수적이며, 프로젝트에 필요한 모든 .jar 파일들이 다운로드됩니다.
    • 이 과정이 완료되면, VS Code 좌측 패널에 Java Projects 또는 Maven 또는 Gradle 뷰가 나타납니다.
  2. Gradle / Maven 뷰 확인 (선택 사항):
    • 좌측 사이드바에 Gradle 아이콘 (코끼리) 또는 Maven 아이콘 (M 로고)이 보이면 클릭하여 프로젝트 구조와 태스크를 확인해 보세요.
    • 여기서 bootRun 또는 spring-boot:run 태스크를 찾을 수 있습니다.

4단계: Spring Boot 애플리케이션 실행 (가장 일반적인 방법)

Spring Boot 프로젝트를 실행하는 가장 일반적이고 권장되는 방법은 메인 애플리케이션 클래스를 통해 실행하는 것입니다.

  1. 메인 애플리케이션 클래스 열기:
    • src/main/java 아래에 있는 [프로젝트명]Application.java 파일을 엽니다. (예: DemoApplication.java)
  2. 코드 렌즈 (Code Lens) 사용:
    • public static void main(String[] args) 메서드 위에 보면 Run | Debug 또는 Run 링크가 나타납니다. 이것을 코드 렌즈라고 부릅니다.
    • Run을 클릭합니다.
  3. 실행 결과 확인:
    • VS Code 하단에 통합 터미널(Terminal)이 열리고 애플리케이션이 빌드되고 실행되는 로그가 출력됩니다.
    • 로그의 마지막 부분에 다음과 유사한 메시지가 보이면 성공적으로 실행된 것입니다:
        Tomcat started on port(s): 8080 (http) with context path ''
        Started DemoApplication in X.XXX seconds (JVM running for Y.YYY)
    • 이 메시지는 Spring Boot 애플리케이션이 8080 포트에서 실행 중임을 의미합니다.

5단계: 웹 브라우저에서 API 접근

이제 애플리케이션이 실행되었으니, 웹 브라우저를 통해 RESTful API에 접근할 수 있습니다.

  1. 웹 브라우저 열기: Chrome, Firefox, Edge 등 어떤 웹 브라우저든 좋습니다.
  2. URL 입력:
    • 주소창에 http://localhost:8080을 입력하고 Enter 키를 누릅니다.
    • 주의: 만약 프로젝트에 컨트롤러가 없고, 루트 경로(http://localhost:8080/)에 매핑된 API가 없다면 404 Not Found 오류가 발생할 수 있습니다.
      • 제대로 테스트하려면: 프로젝트에 API 엔드포인트가 정의되어 있어야 합니다. 예를 들어, UserController@GetMapping("/users")와 같은 엔드포인트가 있다면, http://localhost:8080/users로 접근해야 합니다.

예시 컨트롤러 (Quick Start):

만약 프로젝트에 아직 컨트롤러가 없다면, src/main/java/com/example/demo/controller (패키지명은 프로젝트에 맞게 변경) 아래에 HelloController.java 파일을 생성하고 다음과 같이 작성해 보세요.

package com.example.demo.controller; // 패키지명은 본인의 프로젝트에 맞게 수정

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController // 이 클래스가 REST API를 처리하는 컨트롤러임을 명시
public class HelloController {

    @GetMapping("/") // GET 요청이 '/' 경로로 오면 이 메서드가 처리
    public String home() {
        return "Hello, Spring Boot REST API!";
    }

    @GetMapping("/api/hello") // GET 요청이 '/api/hello' 경로로 오면 이 메서드가 처리
    public String helloApi() {
        return "Hello from /api/hello!";
    }
}

위 코드를 추가한 후 다시 4단계부터 실행하면 http://localhost:8080/ 또는 http://localhost:8080/api/hello 로 접근 시 정의된 문자열이 브라우저에 출력될 것입니다.


추가 팁: Spring Boot Dashboard (VMware Spring Boot Extension Pack 설치 시)

Spring Boot Extension Pack을 설치했다면, VS Code 좌측 사이드바에 Spring Boot Dashboard 아이콘 (Spring 로고)이 생깁니다.

  1. Spring Boot Dashboard 클릭:
    • 여기서 현재 VS Code에서 열린 Spring Boot 프로젝트들이 목록으로 나타납니다.
  2. 프로젝트 실행:
    • 해당 프로젝트 이름 옆에 있는 재생(▶) 버튼을 클릭하여 애플리케이션을 실행할 수 있습니다.
    • 디버깅(🐞) 버튼을 통해 디버그 모드로 실행할 수도 있습니다.
  3. 로그 확인:
    • 실행 후 Dashboard에서 프로젝트를 클릭하면 Output 창에 실행 로그가 출력됩니다.

이 방법은 여러 Spring Boot 프로젝트를 동시에 관리하거나 실행할 때 매우 편리합니다.


이 단계들을 따라오셨다면, 성공적으로 Spring Boot RESTful API 프로젝트를 실행하고 http://localhost:8080 (또는 정의된 엔드포인트 경로)로 접근할 수 있을 것입니다.

728x90
반응형

+ Recent posts