728x90

참고페이지 : Using Go with MariaDB (링크)

 

Using Go with MariaDB | MariaDB

2019 Webinar: Building Modern Applications with MariaDB Hybrid Transactional/Analytical Processing (HTAP) Watch Now _________________________ I have been using Google’s Go programming language for a…

mariadb.com

 

MariaDB 홈페이지에서도 mysql로 작업을 환경을 구축하도록 안내하기에

혼선이 없으시길 바랍니다.

 

데이터베이스를 연동하여,

user의 전체 데이터를 가져오는 내용으로 소스를 변경하겠습니다.

 

더보기

Database 세팅

데이터베이스, 테이블을 아래 이미지와 같이 미리 생성해 주세요.

테스트를 위해 2~3개정도의 데이터를 미리 입력하는 것이 좋습니다.

MariaDB - test_crud 데이터베이스 - users 테이블

Mysql 세팅

cmd에서 프로젝트 페이지로 이동 후, 라이브러리를 다운합니다.

cd workspace/go/src/api
go get github.com/go-sql-driver/mysql

 

main.go 수정

package main

import (
	...
    
	// 코드 추가
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

type User struct {
	...
}

// Database 정보를 저장할 구조체
type DBInfo struct {
	user     string
	pwd      string
	url      string
	engine   string
	database string
}

// 주석 처리 or 제거
// Database에서 정보를 받아오기에, 더 이상 쓰지 않음
/*
var users = []User{
	User{Id: 1, Name: "David", Email: "test@gmail.com", Password: "123"},
	User{Id: 2, Name: "Nata", Email: "test@email.com", Password: "qwer"},
}
*/

// 코드 추가
var users = []User{} // 별도로 데이터를 저장
var user = User{}    // 별도로 데이터를 저장

// Database 연결 정보
var dbInfo = DBInfo{"아이디", "비밀번호", "localhost:3306", "mysql", "test_crud"}

type Response struct { ... }

func NewResponse(method, message string, status int) Response { ... }

func HttpInfo(r *http.Request) { ... }

// Content-Type을 "application/json"으로 설정하여 JSON 전달
func setJsonHeader(w http.ResponseWriter) {
	w.Header().Set("Content-Type", "application/json")
}

func main() { ... }

// 코드 추가 : sql.DB 객체 생성
func connetDatabase() *sql.DB {
	dataSource := dbInfo.user + ":" + dbInfo.pwd + "@tcp(" + dbInfo.url + ")/" + dbInfo.database
	db, err := sql.Open(dbInfo.engine, dataSource)

	checkErr(err)

	return db
}

// 코드 추가 : 에러 체크
func checkErr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

// 전체 user 정보 전달
func getUsers(w http.ResponseWriter, r *http.Request) {
	setJsonHeader(w)
	HttpInfo(r)

	// sql.DB 객체 생성
	db := connetDatabase()
	
	// 지연하여 닫는다(필수)
	defer db.Close()

	// User 전체 데이터를 불러오는 SQL 쿼리
	rows, err := db.Query("SELECT * FROM users")
	checkErr(err)

	// 지연하여 닫는다(필수)
	defer rows.Close() 

	users = []User{}
	for rows.Next() {
		user = User{}
		err := rows.Scan(&user.Id, &user.Name, &user.Email, &user.Password)
		checkErr(err)
		fmt.Println(user)
		users = append(users, user)
	}

	fmt.Println(len(users))

	json.NewEncoder(w).Encode(users)
}

...
728x90
Posted by 게으른거북
:
728x90

참고영상 : Consumindo uma (GO) API REST com Angular 7 Parte 6 # 30

 

더보기

위 방법이 마음에 안들어 다른 사이트를 참고하였습니다.

참고사이트 : NPM_ngx-toastr (링크)

 


NPM 설치

npm install ngx-toastr --save
npm install @angular/animations --save

 

src/style.css 수정

@import '~ngx-toastr/toastr.css';

 

src/app/app.module.ts 수정

...

// 코드 추가
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ToastrModule } from 'ngx-toastr';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    FontAwesomeModule,

    // 코드 추가
    BrowserAnimationsModule,
    ToastrModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
  ...
}

 

src/app/app.component.ts 수정

...

// 코드 추가
import { ToastrService } from 'ngx-toastr';

@Component({
  ...
})
export class AppComponent {
  ...
 
  // 코드 수정
  //constructor(public service: UserService) {
  constructor(public service: UserService, private toastr: ToastrService) {
    ...
  }
  
  // 코드 추가 : toastr을 간편하게 쓰기 위한 함수
  public onToastr(service: string, title: string, message: string) {
    switch(service) {
      case "success": {
        this.toastr.success(message, title, {timeOut: 2000});
        break;
      }
      case "info": {
        this.toastr.info(message, title, {timeOut: 2000});
        break;
      }
      case "warning": {
        this.toastr.warning(message, title, {timeOut: 2000});
        break;
      }
      case "error": {
        this.toastr.error(message, title, {timeOut: 2000});
        break;
      }
      default: {
        console.log("Toast Error");
        break;
      }
    }
  }

  public onForm() {
    ...
  }

  public onSubmit(form: FormGroup) {
 
    console.log(form.value)

    if( form.value.id == null) {

      this.service.postUser(form.value)
        .subscribe((resp) => {
          console.log(resp)

          if(resp["Status"] == 201) {
            this.clearForm();   

            this.service.getUsers()
              .subscribe((data) => {
                // 코드 추가
                this.onToastr("success", "Data Insert", "새로운 User가 등록되었습니다.");

                this.users = data
                this.onForm();
              });
          }
        });
    } else {
      
      this.service.putUser(form.value)
        .subscribe((resp) => {
          console.log(resp);

          if(resp["Status"] == 200) {
            // 코드 추가
            this.onToastr("info", "Data Edit", "User 정보가 수정되었습니다.");

            this.onForm();
            this.clearForm();
            this.updateList(form.value);
          }
        });
    }
  }

  public onEdit(id: string) {
    ...
  }

  public updateList(user: any) {
    ...
  }

  public deleteConfirm(id: string) {
    ...
  }

  public cancelDelete() {
    ...
  }

  public onDelete() { 

    if(this.userId != null) {
      this.service.deleteUser(this.userId)
        .subscribe((resp) => {
          console.log(resp);
  
          if(resp["Status"] == 200) {
            // 코드 추가
            this.onToastr("error", "Data Delete", "User 정보가 삭제되었습니다.");

            this.users = this.users.filter((user) => user.id != this.userId);
            
            this.cancelDelete();
            this.onForm();
          }
        });
    }
  }

  public clearForm() {
    ...
}

 

Web 결과화면
728x90
Posted by 게으른거북
:
728x90

참고영상 : Consumindo uma (GO) API REST com Angular 7 Parte 5 # 29

 

더보기

src/app/user.service.ts 수정

...

export class UserService {
  ...
 
  constructor(private http: HttpClient) {
 
    this.getUsers()
      .subscribe((data) => {

        // 코드 수정
        if(data.length > 0) {
          this.nextUserId = (data[ data.length -1].id +1);
          console.log("ID disponivel : " + this.nextUserId);
        }
      });
  }
 
  public getUsers() {
    ...
  }

  public getUser(id: string) {
    ...
  }

  public postUser(user: any) {
    ...
  }

  public putUser(user: any) {
    ...
  }

  public deleteUser(id: string) {
    ...
  }
}

 

src/app/app.component.ts 수정

...

export class AppComponent {
  ...

  // 코드 추가
  userId = null;  // 현재 지정된 user를 파악하기 위한 변수
  displayForm : boolean = false;  // user 데이터가 비었을때를 대비한 변수
 
  constructor(public service: UserService) {
    this.service.getUsers()
      .subscribe((data) => {
        this.users = data;
        console.log(this.users);

        // 코드 추가
        this.onForm();
      })

    this.service.selectedUser = {
      ...
    };

  }
  
  // 코드 추가 : user 데이터가 1건 이상이면, 테이블 표시
  public onForm() {
    
    if(this.users.length > 0) {
      this.displayForm = true;
      return;
    }

    this.displayForm = false;
  }

  public onSubmit(form: FormGroup) {
 
    console.log(form.value)

    if( form.value.id == null) {
      this.service.postUser(form.value)
        .subscribe((resp) => {
          console.log(resp)

          if(resp["Status"] == 201) {
            this.clearForm();   

            this.service.getUsers()
              .subscribe((data) => {
                this.users = data

                // 코드 추가
                this.onForm();
              });
          }
        });
    } else {
      this.service.putUser(form.value)
        .subscribe((resp) => {
          console.log(resp);

          if(resp["Status"] == 200) {
            // 코드 추가
            this.onForm();

            this.clearForm();
            this.updateList(form.value);
          }
        });
    }
  }

  public onEdit(id: string) {
    ...
  }

  public updateList(user: any) {
    ...
  }

  // 코드 추가 : 호출된 user의 id를 저장
  public deleteConfirm(id: string) {
    this.userId = id;
  }

  // 코드 추가 : 저장된 user의 id를 초기화
  public cancelDelete() {
    this.userId = null;
    console.log("Cancel User Delete");
  }

  // 코드 수정
  public onDelete() { 

    if(this.userId != null) {
      //this.service.deleteUser(id)
      this.service.deleteUser(this.userId)
        .subscribe((resp) => {
          console.log(resp);
  
          if(resp["Status"] == 200) {
  
            //this.users = this.users.filter((user) => user.id != id);
            this.users = this.users.filter((user) => user.id != this.userId);
            
            this.cancelDelete();
            this.onForm();
          }
        });
    }
  }

  public clearForm() {
    ...
  }

}

 

src/app/app.component.html

<div class="container">
  <header>
    ...
  </header>

  <hr>

  <div class="row">
    <div class="col-md-12">
      <h3>Insert User Data</h3>
      <form method="post" #form="ngForm" (ngSubmit)="onSubmit(form)">
        ...
      </form>
    </div>
  </div>

  <br>
  <div class="row">
    <!-- 코드 추가 : user 데이터가 없을때, 안내문 표시-->
    <div clas="col-md-12" *ngIf="!displayForm">
      <p class="alert alert-warning text-center" >
        호출 가능한 User 데이터가 없습니다. <br>
        새로운 User 를 등록해주세요.
      </p>
    </div>

    <!-- 코드 수정 : user 데이터가 1건 이상일 경우 내용 표시-->
    <div clas="col-md-12" *ngIf="displayForm">

      <h3>User Data List</h3>

      <table class="table table-bordered table-hover text-center">
        <thead>
          <tr>
            ...
          </tr>
        </thead>
        <tbody>
          <tr *ngFor="let user of users">
            ...
            <td>
              <!-- 코드 수정 : Call Modal-->
              <button type="button" class="btn btn-sm btn-danger col-block col-lg-8" (click)="onDelete(user.id)" data-bs-toggle="modal" data-bs-target="#exampleModal" (click)="deleteConfirm(user.id)">
                <fa-icon icon="user-minus"></fa-icon>
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>


  <!-- 코드 추가 : Modal -->
  <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">User Data Delete</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="cancelDelete()"></button>
        </div>
        <div class="modal-body">
          회원 <strong class="text-danger"> #{{ userId }} </strong> 번의  정보를 삭제 하시겠습니까?
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" (click)="cancelDelete()">
            Cancle
          </button>

          <button type="button" class="btn btn-danger" data-bs-dismiss="modal" (click)="onDelete()">
            Delete
          </button>
        </div>
      </div>
    </div>
  </div>

  <br>
  <footer>
    ...
  </footer>
</div>

 

Web 결과화면 - No User Data

 

Web 결과화면 - Modal
728x90
Posted by 게으른거북
:
728x90

참고영상 : Consumindo uma (GO) API REST com Angular 7 Parte 5 # 29

 

더보기

src/app/app.module.ts 수정

버튼에 대한 아이콘 추가를 위해 아이콘 Module Import를 진행합니다.

...

// 코드 추가 : icon
import { faUserMinus } from '@fortawesome/free-solid-svg-icons';
import { faUserPlus } from '@fortawesome/free-solid-svg-icons';
import { faUndo } from '@fortawesome/free-solid-svg-icons';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    ...
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
  
  constructor(library: FaIconLibrary) {
    // 코드 수정
    library.addIcons(faEdit, faUserMinus, faUserPlus, faUndo);
  }
}

 

src/app/user.service.ts 수정

...
export class UserService {
   ...
 
  constructor(private http: HttpClient) {
    ...
  }
 
  public getUsers() {
    ...
  }

  public getUser(id: string) {
    ...
  }

  public postUser(user: any) {
    ...
  }

  public putUser(user: any) {
    ...
  }

  // 코드 추가
  public deleteUser(id: string) {
    return this.http.delete(`${this.Uri}/${id}`);
  }
}

 

src/app/app.component.ts 수정

...

export class AppComponent {
  ...
 
  constructor(public service: UserService) {
    ...
  }

  public onSubmit(form: FormGroup) {
    ...
  }

  public onEdit(id: string) {
    ...
  }
  
  public updateList(user: any) {
    ...
  }

  // 코드 추가 : user 정보 삭제
  public onDelete(id: string) { 

    this.service.deleteUser(id)
      .subscribe((resp) => {
        console.log(resp);

        if(resp["Status"] == 200) {

          this.users = this.users.filter((user) => user.id != id);
        }
      });
  }

  public clearForm() {
    ...
}

 

src/app/app.component.html 수정

<div class="container">
  <header>
    ...
  </header>

  <hr>

  <div class="row">
    <div class="col-md-12">
      <h3>Insert User Data</h3>
      <form method="post" #form="ngForm" (ngSubmit)="onSubmit(form)">
        ...
 
        <div class="form-row">
          <div class="d-grid gap-2 d-md-flex justify-content-md-end">
            <!-- 코드 수정 : icon 추가 -->
            <button class="btn btn-sm btn-block btn-primary col-lg-2" [disabled]="!form.valid" >
              submit &nbsp; <fa-icon icon="user-plus"></fa-icon>
            </button>

            <!-- 코드 수정 : icon 추가 -->
            <button class="btn btn-sm btn-block btn-secondary col-lg-2" (click)="clearForm()">
              clear &nbsp; <fa-icon icon="undo"></fa-icon>
            </button>
          </div>
        </div>
      </form>
    </div>
  </div>

  <br>
  <div class="row">
    <div clas="col-md-12" *ngIf="users">

      <h3>User Data List</h3>
      
      <table class="table table-bordered table-hover text-center">
        <thead>
          <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Email</th>
            <th>Password</th>
            <th>Edit</th>
            <!-- 코드 수정 -->
            <th>Delete</th>
          </tr>
        </thead>
        <tbody>
          <tr *ngFor="let user of users">
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td>{{ user.email }}</td>
            <td>{{ user.password }}</td>
            <td>
              <button type="button" class="btn btn-sm btn-info col-block col-lg-8" (click)="onEdit(user.id)">
                <fa-icon icon="edit"></fa-icon>
              </button>
            </td>
            <!-- 코드 수정 : delete 추가 -->
            <td>
              <button type="button" class="btn btn-sm btn-danger col-block col-lg-8" (click)="onDelete(user.id)">
                <fa-icon icon="user-minus"></fa-icon>
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <br>
  <footer>
    <p class="alert text-center"></p>
  </footer>
</div>

 

Web 결과화면
728x90
Posted by 게으른거북
:
728x90

참고영상 : Consumindo uma (GO) API REST com Angular 7 Parte 4 # 28

 

더보기

폰트 변경

Google Font (링크)

Google Font 페이지

 

index.html 에 추가

<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Montserrat" rel="stylesheet">

 

src/app/app.component.css 에 추가

.container {
    font-family: 'Montserrat', sans-serif;
}

 

src/app/app.service.ts 수정

...

export class UserService {
  ...
 
  constructor(private http: HttpClient) {
    ...
  }
 
  public getUsers() {
    ...
  }

  public getUser(id: string) {
    ...
  }

  public postUser(user: any) {
    ...
  }

  // 코드 추가
  public putUser(user: any) {

    let data = {
      "id"        :   user.id,
      "name"      :   user.name,
      "email"     :   user.email,
      "password"  :   user.password
    };

    return this.http.put(`${this.Uri}/${user.id}`, JSON.stringify(data));
  }
}

 

src/app/app.component.ts 수정

...

export class AppComponent {
  ...
 
  constructor(public service: UserService) {
    ...
  }

  public onSubmit(form: FormGroup) {
 
    console.log(form.value)

    if( form.value.id == null) {
      this.service.postUser(form.value)
        .subscribe((resp) => {
          console.log(resp)

          if(resp["Status"] == 201) {
            this.clearForm();   // 코드 추가
            this.service.getUsers()
              .subscribe((data) => this.users = data);
          }
        });
    } else {
      // 코드 추가 : user 데이터 수정
      this.service.putUser(form.value)
        .subscribe((resp) => {
          console.log(resp);

          if(resp["Status"] == 200) {
            this.clearForm();
            this.updateList(form.value);
          }
        });

    }
  }

  // 코드 추가 : user 데이터를 Form에 전달
  public onEdit(id: string) {

    this.service.getUser(id)
      .subscribe((data) => {
        this.service.selectedUser = data;
      });
  }
  
  // 코드 추가 : 테이블 내 user 데이터 갱신
  public updateList(user: any) {
    for(var i = 0; i < this.users.length; i++) {
      if(user.id == this.users[i].id) {
        this.users[i] = user;
        return;
      }
    }
  }

  // 코드 추가 : Form 비우기
  public clearForm() {
    this.service.selectedUser = {
      "id": null,
      "name": '',
      "email": '',
      "password": ''
    };
  }
}

 

Web 결과화면
728x90
Posted by 게으른거북
: