토이프로젝트I을 하면서 데이터베이스를 사용할 수 있도록 기본 템플릿에 SQLite3 라이브러리를 담아서 주셨는데 쿼리문을 작성하는 것이 쉽지않아서 json파일을 가져오는걸 선택했었다. 프로젝트 기간이 끝나갈때쯤 SQLite3를 사용해보고싶어 데이터를 가져오는 방식으로만 사용해보았다.
데이터베이스 파일 이름과 데이터베이스를 나타내는 객체 선언
import sqlite3 from "sqlite3"
const databaseName = "toyprj1_team4"
const database = new sqlite3.Database(`${databaseName}.db`)
serialize함수에 테이블 생성 쿼리문 작성
database.serialize(() => {
database.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL,
pw TEXT,
userType TEXT
)`)
}
seilalize함수는 데이터베이스 작업을 동기적으로, 순차적으로 한줄씩 실행해준다.
테이블이 없을 경우에 테이블을 생성하도록 "IF NOT EXISTS"를 추가하고 테이블 내부 각 컬럼의 데이터 타입을 명시한다.
Autoincrement : Integer 타입이며 Primary key 로 지정된 컬럼에 자동으로 유니크한 id값을 증가하게 하여 테이블의 각 행을 고유하게 식별하게 도와준다.
데이터가 담긴 객체 선언
const users = [
{ name: "김수민", email: "tnalsdl2046@gmail.com", pw: "1234", userType: "student" },
{ name: "강동원", email: "ddd@gmail.com", pw: "1234", userType: "student" },
{ name: "김수현", email: "sssuuumen@gmail.com", pw: "1234", userType: "student" },
{ name: "김지원", email: "jiiiiwon@gmail.com", pw: "1234", userType: "student" },
{ name: "김수민 M", email: "tnals@gmail.com", pw: "1111", userType: "manager" },
{ name: "강동원 M", email: "dd111@gmail.com", pw: "1111", userType: "manager" },
{ name: "김수현 M", email: "sumen@gmail.com", pw: "1111", userType: "manager" },
{ name: "김지원 M", email: "jiwon@gmail.com", pw: "1111", userType: "manager" },
]
INSERT문 작성
const stmt = database.prepare("INSERT INTO users (name, email, pw, userType) VALUES(?,?,?,?)")
for (let user of users) {
stmt.run(user.name, user.email, user.pw, user.userType)
}
stmt.finalize()
prepare함수를 사용해 SQL 문을 미리 준비, prepare함수가 statement객체를 return해주는데 이 객체에 반복문을 사용하여 데이터를 삽입하고 run() 함수를 실행한다. 이후 사용한 statement 객체는 finalize()로 종료한다.
Each 함수
database.each("SELECT rowid AS id, name, email, pw, userType FROM users", (err, row) => {
console.log(`${row.id}:${row.name}, ${row.email}, ${row.pw},${row.userType}`)
})
결과로 나온 row들을 한 행씩 순회하여 콜백 호출, rowid는 SQLite에서 자동으로 관리하는 유니크한 식별자로 rowid열의 이름을 결과 세트에서 id로 변경하여 표시한다.
위 사진처럼 서버를 실행할때마다 로그가 쌓이기때문에 serialize함수 내부 상단에 DROP문 추가
database.run("DROP TABLE IF EXISTS users")
최종
import sqlite3 from "sqlite3"
const databaseName = "toyprj1_team4"
const database = new sqlite3.Database(`${databaseName}.db`)
database.serialize(() => {
database.run("DROP TABLE IF EXISTS users")
database.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL,
pw TEXT,
userType TEXT
)`)
const stmt = database.prepare("INSERT INTO users (name, email, pw, userType) VALUES(?,?,?,?)")
const users = [
{ name: "김수민", email: "tnalsdl2046@gmail.com", pw: "1234", userType: "student" },
{ name: "강동원", email: "ddd@gmail.com", pw: "1234", userType: "student" },
{ name: "김수현", email: "sssuuumen@gmail.com", pw: "1234", userType: "student" },
{ name: "김지원", email: "jiiiiwon@gmail.com", pw: "1234", userType: "student" },
{ name: "김수민 M", email: "tnals@gmail.com", pw: "1111", userType: "manager" },
{ name: "강동원 M", email: "dd111@gmail.com", pw: "1111", userType: "manager" },
{ name: "김수현 M", email: "sumen@gmail.com", pw: "1111", userType: "manager" },
{ name: "김지원 M", email: "jiwon@gmail.com", pw: "1111", userType: "manager" },
]
for (let user of users) {
stmt.run(user.name, user.email, user.pw, user.userType)
}
stmt.finalize()
database.each("SELECT rowid AS id, name, email, pw, userType FROM users", (err, row) => {
console.log(`${row.id}:${row.name}, ${row.email}, ${row.pw},${row.userType}`)
})
})
export default database
express 모듈과 database를 import 후 선언
import express from "express"
import database from "./database.js"
const app = express()
웹브라우저에서 요청이 들어오면 database로 부터 데이터 가져오기
app.get("/api/users", (req, res) => {
const sql = "SELECT * FROM users"
database.all(sql, (err, rows) => {
if (err) {
return res.status(500).json({
status: "Error",
message: err.message,
})
}
res.json({
status: "OK",
data: rows,
})
})
})
app.listen(port, () => {
console.log(`ready to ${port}`)
})
서버실행 후 로그와 "SQLite Viewer" Extention으로 데이터 확인
// 이메일 중복확인 버튼 클릭시 database에 저장된 이메일 값과 비교하는 유효성검사
const checkEmail = async (event) => {
event.preventDefault()
if (this.emailRegexValidation) {
const res = await axios.get("/api/users")
const users = res.data.data
for (let user of users) {
if (user.email === usersEmail.value) {
emailError.textContent = "중복된 이메일입니다."
this.emailValidation = false
break
} else {
emailError.textContent = "이메일이 확인 되었습니다."
this.emailValidation = true
}
}
} else {
alert("이메일 형식을 확인해주세요.")
}
}
데이터베이스에 저장된 user데이터는 회원가입 페이지에서 이메일 중복 검사 시에 저장된 데이터와 중복이 되는지 비교할 수 있다.