[C++] Mysql select, insert, update, delete
https://goodbyeanma.tistory.com/172
[C++] Mac os 에서 Mysql 연결하기
Mac os 환경에서 C++를 사용해서 Mysql과 연동하여 소스코드를 작성하는 방법을 보자. 일단, 해당글에서는 mac os 에 mysql 은 이미 설치되었다고 가정하고 설명을 진행하겠다. 1. mysql-connector-c++ 설치 202
goodbyeanma.tistory.com
C++와 Mysql을 연결하는 방법은 이전 글에서 포스팅하였다.
이번 글에서는 C++를 통해서 mysql 인스턴스에 DML 작업을
어떤 식으로 수행할 수 있는지 확인해 보자.
예제
Mysql에서 예제로 사용할 스키마는 아래와 같다.
CREATE TABLE EMP_TEST (
emp_seq BIGINT AUTO_INCREMENT PRIMARY KEY,
emp_name VARCHAR(25) NOT NULL,
emp_buseo VARCHAR(10) NOT NULL,
emp_salary INT NOT NULL
);
또한 C++의 대략적인 소스코드 프레임은 아래와 같다.
Mysql 인스턴스의 EMP_TEST 테이블과 맵핑할 Employee 클래스를 선언하였다.
또한 MysqlSession 클래스를 생성하여,
MySQL 데이터베이스와 상호작용하는 역할로 사용할 것이다.
#include <iostream>
#include <mysqlx/xdevapi.h>
using namespace std;
class Employee {
private:
long long empSeq;
string empName;
string empBuseo;
int empSalary;
public:
Employee(const long long &empSeq, const string &empName, const string &empBuseo, int empSalary)
:empSeq(empSeq), empName(empName), empBuseo(empBuseo), empSalary(empSalary)
{
}
// Getter methods
long long getEmpSeq() const {
return this->empSeq;
}
string getEmpName() const {
return this->empName;
}
string getEmpBuseo() const {
return this->empBuseo;
}
int getEmpSalary() const {
return this->empSalary;
}
};
class MySqlSession {
private:
mysqlx::Session session;
mysqlx::Schema db;
mysqlx::Table table;
public:
MySqlSession(const string &ipAddr, const int &port, const string &userName, const string &userPw,
const string &schema, const string &tableName)
: session(ipAddr, port, userName, userPw), db(session.getSchema(schema)), table(db.getTable(tableName))
{
}
~MySqlSession()
{
session.close();
}
};
int main()
{
MySqlSession session("localhost", 33060, "root", "123", "admin", "EMP_TEST");
return 0;
}
1. Insert
MySqlSession 클래스 내부에 insertDataEmp 메서드를 생성하여,
EMP_TEST에 데이터를 insert 해주는 기능을 만들어보자.
#include <iostream>
#include <mysqlx/xdevapi.h>
using namespace std;
class Employee {
private:
long long empSeq;
string empName;
string empBuseo;
int empSalary;
public:
Employee(const long long &empSeq, const string &empName, const string &empBuseo, int empSalary)
:empSeq(empSeq), empName(empName), empBuseo(empBuseo), empSalary(empSalary)
{
}
// Getter methods
long long getEmpSeq() const {
return this->empSeq;
}
string getEmpName() const {
return this->empName;
}
string getEmpBuseo() const {
return this->empBuseo;
}
int getEmpSalary() const {
return this->empSalary;
}
};
class MySqlSession {
private:
mysqlx::Session session;
mysqlx::Schema db;
mysqlx::Table table;
public:
MySqlSession(const string &ipAddr, const int &port, const string &userName, const string &userPw,
const string &schema, const string &tableName)
: session(ipAddr, port, userName, userPw), db(session.getSchema(schema)), table(db.getTable(tableName))
{
}
// Insert
bool insertDataEmp(const Employee &emp)
{
try {
this->table.insert("emp_seq", "emp_name", "emp_buseo", "emp_salary")
.values(emp.getEmpSeq(), emp.getEmpName(), emp.getEmpBuseo(), emp.getEmpSalary())
.execute();
return true;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return false;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return false;
}
}
~MySqlSession()
{
session.close();
}
};
int main()
{
MySqlSession session("localhost", 33060, "root", "123", "admin", "EMP_TEST");
Employee emp(1,"seunghwan","DEV",12000000);
if (session.insertDataEmp(ref(emp))) cout << "insert 성공" << endl;
return 0;
}
main 함수를 보면 MysqlSession 객체를 만들어준 다음
생성자를 통해서 Employee 객체를 생성한 다음
해당 정보를 insertDataEmp() 함수의 호출을 통해서 데이터 베이스에 삽입한다.
2. Select
위에서 삽입된 데이터를 C++에서 select 과정을 통해서
데이터를 가져와주는 소스코드는 아래와 같이 구성할 수 있다.
#include <iostream>
#include <mysqlx/xdevapi.h>
#include <optional>
using namespace std;
class Employee {
private:
long long empSeq;
string empName;
string empBuseo;
int empSalary;
public:
Employee(const long long &empSeq, const string &empName, const string &empBuseo, int empSalary)
:empSeq(empSeq), empName(empName), empBuseo(empBuseo), empSalary(empSalary)
{
}
// Getter methods
long long getEmpSeq() const {
return this->empSeq;
}
string getEmpName() const {
return this->empName;
}
string getEmpBuseo() const {
return this->empBuseo;
}
int getEmpSalary() const {
return this->empSalary;
}
};
class MySqlSession {
private:
mysqlx::Session session;
mysqlx::Schema db;
mysqlx::Table table;
public:
MySqlSession(const string &ipAddr, const int &port, const string &userName, const string &userPw,
const string &schema, const string &tableName)
: session(ipAddr, port, userName, userPw), db(session.getSchema(schema)), table(db.getTable(tableName))
{
}
// Select
optional<Employee> selectDataEmp(const long long &empSeq)
{
try {
mysqlx::RowResult result = this->table.select("emp_seq", "emp_name", "emp_buseo", "emp_salary")
.where("emp_seq = :value")
.bind("value", empSeq)
.execute();
auto row = result.fetchOne();
if (row) return Employee(row[0].get<long long>(), row[1].get<string>(), row[2].get<string>(), row[3].get<long long>());
return nullopt;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return nullopt;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return nullopt;
}
}
~MySqlSession()
{
session.close();
}
};
int main()
{
MySqlSession session("localhost", 33060, "root", "123", "admin", "EMP_TEST");
optional<Employee> result = session.selectDataEmp(1);
if (result.has_value())
{
Employee emp = result.value();
cout << "번호 : " << emp.getEmpSeq() << endl;
cout << "이름 : " << emp.getEmpName() << endl;
cout << "부서 : " << emp.getEmpBuseo() << endl;
cout << "급여 : " << emp.getEmpSalary() << endl;
}
return 0;
}
위의 코드는 직원의 고유번호를 파라미터로 받은 다음에,
해당 고유번호를 가진 직원의 정보를 데이터베이스에서 가져오는 역할을 수행하고 있다.
주의할 점은 selectDataEmp() 함수 내의 table.select(~) 부분의 파라미터 중
가져올 칼럼값을 입력하도록 되어 있는데,
해당 칼럼값은 실제 데이터베이스 내에 존재하는 칼럼값과 같은 형식으로 적어줘야 한다는 것이다.
3. Update
이번에는 특정 직원의 고유번호를 입력해 주고, 새로운 급여를 입력해 주면
해당 직원의 급여가 새로운 급여로 수정되는 소스코드를 만들어보자.
#include <iostream>
#include <mysqlx/xdevapi.h>
#include <optional>
using namespace std;
class Employee {
private:
long long empSeq;
string empName;
string empBuseo;
int empSalary;
public:
Employee(const long long &empSeq, const string &empName, const string &empBuseo, int empSalary)
:empSeq(empSeq), empName(empName), empBuseo(empBuseo), empSalary(empSalary)
{
}
// Getter methods
long long getEmpSeq() const {
return this->empSeq;
}
string getEmpName() const {
return this->empName;
}
string getEmpBuseo() const {
return this->empBuseo;
}
int getEmpSalary() const {
return this->empSalary;
}
};
class MySqlSession {
private:
mysqlx::Session session;
mysqlx::Schema db;
mysqlx::Table table;
public:
MySqlSession(const string &ipAddr, const int &port, const string &userName, const string &userPw,
const string &schema, const string &tableName)
: session(ipAddr, port, userName, userPw), db(session.getSchema(schema)), table(db.getTable(tableName))
{
}
// Update
bool updateSalaryEmpSeq(const int &empSeq, const int &value)
{
try {
this->table.update().set("emp_salary", value).where("emp_seq = :value").bind("value", empSeq).execute();
return true;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return false;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return false;
}
}
~MySqlSession()
{
session.close();
}
};
int main()
{
MySqlSession session("localhost", 33060, "root", "123", "admin", "EMP_TEST");
if (session.updateSalaryEmpSeq(1, 40000000)) cout << "update 성공" << endl;
return 0;
}
위의 코드는 급여수정의 대상이 되는 직원의 고유번호와,
수정할 급여를 파라미터로 받아주고
해당 데이터를 바탕으로 MySqlSession 클래스를 통해서
직원의 월급정보를 수정해 준다.
4. Delete
마지막으로 데이터를 삭제할 수 있는 Delete 구문을 사용해 보자.
#include <iostream>
#include <mysqlx/xdevapi.h>
#include <optional>
using namespace std;
class Employee {
private:
long long empSeq;
string empName;
string empBuseo;
int empSalary;
public:
Employee(const long long &empSeq, const string &empName, const string &empBuseo, int empSalary)
:empSeq(empSeq), empName(empName), empBuseo(empBuseo), empSalary(empSalary)
{
}
// Getter methods
long long getEmpSeq() const {
return this->empSeq;
}
string getEmpName() const {
return this->empName;
}
string getEmpBuseo() const {
return this->empBuseo;
}
int getEmpSalary() const {
return this->empSalary;
}
};
class MySqlSession {
private:
mysqlx::Session session;
mysqlx::Schema db;
mysqlx::Table table;
public:
MySqlSession(const string &ipAddr, const int &port, const string &userName, const string &userPw,
const string &schema, const string &tableName)
: session(ipAddr, port, userName, userPw), db(session.getSchema(schema)), table(db.getTable(tableName))
{
}
// Delete
bool deleteDataEmpSeq(const string &colName, const long long &value)
{
try {
this->table.remove().where(colName + "= :value").bind("value", value).execute();
return true;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return false;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return false;
}
}
~MySqlSession()
{
session.close();
}
};
int main()
{
MySqlSession session("localhost", 33060, "root", "Sh@#156452", "admin", "EMP_TEST");
if (session.deleteDataEmpSeq("emp_seq", 1)) cout << "delete 성공" << endl;
return 0;
}
deleteDataEmpSeq() 함수는 특정 직원의 고유번호를 입력하면
해당조건을 만족하는 직원의 모든 정보가 지워지게 된다.
this->table.remove(). where(colName ~ ) 처럼 동적으로
칼럼이름값을 설정할 수 있음을 보여주기 위해서
칼럼의 이름을 파라미터로 선언해 주었다.
전체적인 코드는 아래와 같다.
#include <iostream>
#include <mysqlx/xdevapi.h>
#include <cstdint>
#include <optional>
using namespace std;
class Employee {
private:
long long empSeq;
string empName;
string empBuseo;
int empSalary;
public:
Employee(const long long &empSeq, const string &empName, const string &empBuseo, int empSalary)
:empSeq(empSeq), empName(empName), empBuseo(empBuseo), empSalary(empSalary)
{
}
// Getter methods
long long getEmpSeq() const {
return this->empSeq;
}
string getEmpName() const {
return this->empName;
}
string getEmpBuseo() const {
return this->empBuseo;
}
int getEmpSalary() const {
return this->empSalary;
}
};
class MySqlSession {
private:
mysqlx::Session session;
mysqlx::Schema db;
mysqlx::Table table;
public:
MySqlSession(const string &ipAddr, const int &port, const string &userName, const string &userPw,
const string &schema, const string &tableName)
: session(ipAddr, port, userName, userPw), db(session.getSchema(schema)), table(db.getTable(tableName))
{
}
optional<Employee> selectDataEmp(const long long empSeq)
{
try {
mysqlx::RowResult result = this->table.select("emp_seq", "emp_name", "emp_buseo", "emp_salary")
.where("emp_seq = :value")
.bind("value", empSeq)
.execute();
auto row = result.fetchOne();
if (row) return Employee(row[0].get<long long>(), row[1].get<string>(), row[2].get<string>(), row[3].get<long long>());
return nullopt;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return nullopt;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return nullopt;
}
}
bool insertDataEmp(const Employee &emp)
{
try {
this->table.insert("emp_seq", "emp_name", "emp_buseo", "emp_salary")
.values(emp.getEmpSeq(), emp.getEmpName(), emp.getEmpBuseo(), emp.getEmpSalary())
.execute();
return true;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return false;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return false;
}
}
bool deleteDataEmpSeq(const string &colName, const long long &value)
{
try {
this->table.remove().where(colName + "= :value").bind("value", value).execute();
return true;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return false;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return false;
}
}
bool updateSalaryEmpSeq(const int &empSeq, const int &value)
{
try {
this->table.update().set("emp_salary", value).where("emp_seq = :value").bind("value", empSeq).execute();
return true;
} catch (const exception &e) {
cerr << "Error: " << e.what() << endl;
return false;
} catch(...) {
cerr << "An unknown error has occurred." << endl;
return false;
}
}
~MySqlSession()
{
session.close();
}
};
/**
* @brief
* Main Function
* @return int
*/
int main()
{
MySqlSession session("localhost", 33060, "root", "Sh@#156452", "admin", "EMP_TEST");
// INSERT
Employee emp(1,"seunghwan","DEV",12000000);
if (session.insertDataEmp(ref(emp))) cout << "insert 성공" << endl;
// SELECT
optional<Employee> result = session.selectDataEmp(1);
if (result.has_value())
{
Employee emp = result.value();
cout << "번호 : " << emp.getEmpSeq() << endl;
cout << "이름 : " << emp.getEmpName() << endl;
cout << "부서 : " << emp.getEmpBuseo() << endl;
cout << "급여 : " << emp.getEmpSalary() << endl;
}
// UPDATE
if (session.updateSalaryEmpSeq(1, 35000000)) cout << "update 성공" << endl;
// DELETE
if (session.deleteDataEmpSeq("emp_seq", 1)) cout << "delete 성공" << endl;
return 0;
}