빅데이터 Java 개발자 교육 - 06일차 [while문, MongoDB]

Jun_Gyu·2023년 2월 25일
0

오늘은 MongoDB를 이용하여 회원 정보들을 보관할 수 있도록 eclips와 MongoDB를 연동하는 코드를 짜볼것이다.


public void forAge() {
		for (int i = 1; i <= this.age; i++) {
			System.out.print(i + ", ");    // 1, 2, 3,
		}
		System.out.println();
		System.out.println("--------");    // --------
		
		int m = 1;
		while(m <= this.age) {
			System.out.print(m + ", ");    // 1, 2, 3,
			m++;

들어가기 앞서서 while문의 사용법. 두개의 값이 똑같이 출력되니 참고할 것. (age 값은 3으로 설정해두었다.)


먼저 MongoDB 접속을 한다.

MongoDB의 경우

mongodb://아이디:패스워드@주소:포트번호/데이터베이스번호

가 되겠다.

final String url = " ";
		
		url = "aaa";
		// final 을 붙이면 생성 당시의 값으로 프로그램이 끝날때 까지 유지가 된다.
		// 이유는 바꿀수 없는 상수이기 때문.

url의 경우 똑같은곳에 자료들을 저장을 해야하기때문에 바뀌지 않도록 값을 고정시킨다.

들어가기 앞서 먼저 전체적으로 구성된 코드를 참고용으로 미리 올려두고 살펴보도록 하겠다.

package day6;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.InsertOneResult;
import com.mongodb.client.result.UpdateResult;

// 기능용 클래스
// 몽고DB 연동

public class MemberDB {
	MongoCollection<Document> collection = null;
	// 변수는 모든 메소드에 사용 가능하기 위해 바깥으로 뺌.
	// 변수 X
	// 생성자
	public MemberDB() {
		// 공통변수가 아니기 때문에 생성자 내부에서만 사용가능한 변수 생성.

		// final 을 붙이면 생성 당시의 값으로 프로그램이 끝날때 까지 유지가 된다. 이유는 바꿀수 없기 때문.
		// mongodb://아이디:비밀번호@주소:포트번호/디비명

		final String url = " mongodb://아이디:비밀번호@주소:포트번호/디비명";

		// static클래스를 통해서 접속이 가능함. (import도 해주어야 함.)
		MongoClient client = MongoClients.create(url);
		MongoDatabase db = client.getDatabase("db209");
		this.collection = db.getCollection("members");

	}

	// 이름이 "가나다"인 사람만 조회
	public void printMembersName(String searchName) {

		// 키 또는 필드가 name인 것중에서 searchName과 정확하게 일치하는 필터
		Bson filter = Filters.eq("name", searchName);
		MongoCursor<Document> list = this.collection.find(filter).iterator();
		while (list.hasNext()) { // 2개 있으니 2번 수행
			Document doc = list.next();
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");
		}
	}

	// 전체 회원조회 메소드
	public void printMembers() {
		MongoCursor<Document> list = this.collection.find().cursor(); // 반복자
		// ex)1000 => 500개만 부분출력(X)
		// 반복자(처음부터 끝까지 전체다 반복할거라고 가정
		/*-----------------------------반복자 반복문----------------------------*/
		// 가져올 데이터가 있나요?? (반복문)
		while (list.hasNext()) { // 그 다음 가져 올 데이터가 있는지?
			Document doc = list.next(); // 있다면 가져오기
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");

		}
	}

	// 회원가입 메소드
	public int insertMember(Member member) {
		try { // 정상동작
			Document doc = new Document();
			// 키가 반드시 _id 기본키로 봄. (id는 중복되어 DB에 올라갈 수 없다.)
			doc.append("_id", member.getId());
			doc.append("password", member.getPassword());
			doc.append("name", member.getName());
			doc.append("age", member.getAge());
			doc.append("phone", member.getPhone());
			doc.append("role", member.getRole());
			doc.append("regdate", member.getRegdate());

			InsertOneResult result = this.collection.insertOne(doc);
			System.out.println(result.toString());
			return 1;

		} catch (Exception e) {// 오류가 발생 시 이쪽의 메소드가 수행됨.

			// Exception클래스의 e변수에 오류의 정보(오류 메시지)가 전송되게 됨.
			e.printStackTrace(); // 오류 메세지를 전체적으로 출력해줌. 개발자를 위한 기능

			return -1; // 오류시 보통 -1로 반환함!
		}
		

	}
package day6;

import java.util.Date;

public class Main1 {

	public static void main(String[] args) {

	// 1. 객체 생성
	// DB에 접속하고 members collection 접속
	MemberDB mDB = new MemberDB();
		
	// 2. 회원가입하고 싶은 임시 데이터 (아이디,암호,이름,나이,연락처,권한,현재시간)
	Member member = new Member("43", "40000", "가나다", 19, "010-0020-0001", "C", new Date());
	
	// 3. DB에 추가하는 메소드 수행
	int ret = mDB.insertMember(member); //성공하면 1, 실패시 -1
	System.out.println(ret);
	}
	
}

여러 정보들을 저장해보자.


이렇게. 그렇다면 한번 저장되어 있는 정보들을 가져와보자

먼저 전체 회원들이 누가 있는지 뽑아와보자. MemberDB클래스에 아래 메소드 작성하여

	// 전체 회원조회 메소드
	public void printMembers() {
		MongoCursor<Document> list = this.collecttion.find().cursor(); // 반복자
		// 1000 => 500개만 출력(X)
		// 반복자(처음부터 끝까지 전체다 반복할거라고 가정
		
		/*-------------------------------반복자 반복문----------------------------*/
		// 가져올 데이터가 있나요??  (반복문)
		while (list.hasNext()) { // 그 다음 가져 올 데이터가 있는지?
			Document doc = list.next();
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");
		}
}

메인클래스에서 mDB.printMembers();로 값을 뽑아내게 되면 MongoDB에 저장되어있는 데이터를 바탕으로 아래와 같은 결과가 나오게 된다.

이번엔 이름이 "가나다"인 사람만 조회하여 보자. 아래처럼 이름만 분리해주는 메소드를 만들어

// 이름이 "가나다"인만 조회(searchName값을 "가나다")
	public void printMembersName( String searchName ) {
		// 키 또는 필드가 name인 것중에서 searchName과 정확하게 일치하는 필터
		Bson filter = Filters.eq("name", searchName );
		MongoCursor<Document> list = this.collecttion.find(filter).iterator();
		while(list.hasNext()) { // 2개 있으니 2번 수행
			Document doc = list.next();
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");
		}
}

이를 메인에서

MemberDB mDB = new MemberDB()

을 통해서 DB에 접속하고 mDB.printMembersName();메소드를 불러와 실행하게 되면

로 나오게 된다.


확인해보면 정확히 '가나다'라는 이름의 사람만 출력된걸 확인할 수 있다. 여기서 여러 조건의 메소드를 생성할 것 같으니 객체를 줄이고자 분류된값을 출력해주는 메소드는 따로 만들어주도록 하겠다!

public void printAction(Bson filter) {
		MongoCursor<Document> list = this.collecttion.find(filter).iterator();
		while (list.hasNext()) {
			Document doc = list.next();
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");
	}
}

이렇게.

그렇다면 이제 분류를 하기위한 조건을 만드는 메소드에서는 Bson filter = Filters.와 printAction(filter); 를 이용해서 불러오기만 하면 된다.

여기서 실습을 두가지 진행하였다. // 문제1) 고객, 판매자만 조회하는 필터링

public void printMembersRole(String searchRole) {
		// 키 또는 필드가 name인 것중에서 searchRole과 정확하게 일치하는 필터
		Bson filter = Filters.eq("role", searchRole);

		printAction(filter);
}

// 문제2) 나이가 n 이상인 것만 필터링

public void printMembersAge(Integer n) {
		// 키 또는 필드가 name인 것중에서 searchName과 정확하게 일치하는 필터
		Bson filter = Filters.gte("age", n); // 나이가 n 이상이면 .gte, 이하면 .lte이다. [맛있는MongoDB Pg.91]

printAction(filter);
}

여기서 주의할것이 있다.

문제의 조건에서 나이가 'n' 이상인 것만 필터링을 하기 위해서는 Filters. 뒤에 "gte"를 붙여주어야 한다. 초과는 gt.

(이하인 것만 출력하려면 lte, 미만은 lt이다)


그다음으로는

데이터베이스에 저장된 아이디 bbb의 회원정보를 수정해볼것이다.

// 회원정보 수정하기. 이름, 연락처, 나이정보 (암호는 변경 불가능.)
	public int updateMember(Member member) {
		try {
			//변경하고자 하는 항목의 조건
/*2번*/		Bson filter = Filters.eq("_id", member.getId());
			
			//변경할 항목들...
/*3번*/   	Bson update1 = Updates.set("name", member.getName());
			Bson update2 = Updates.set("phone", member.getPhone());
			Bson update3 = Updates.set("age", member.getAge());
			
			// updateOne (조건, 변경값) => 변경값이 하나의 Bson에만 가능.. combine
/*4번*/		Bson update = Updates.combine(update1, update2, update3);
			
/*1번*/		UpdateResult result = this.collection.updateOne(filter, update);
			System.out.println(result.toString());
			return 1;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
	}

}

데이터베이스에 다른 정보들과 구분되는 기준이 '아이디'이기때문에 아이디는 수정할 수 없다.

그리고 암호또한 암호화 키로 변경되어 저장되기에 현재 배운것들로써는 암호를 변경하기는 어렵다. 위의 코드 실행 조건은 좌측에 써있는 번호의 순번대로 이루어진다.

// 회원정보 수정하기
	Member member = new Member();
	member.setId("bbb");
	member.setName("abcd"); // 변경할 이름
	member.setPhone("010-3455-6778"); // 변경할 전화번호
	member.setAge(33); // 변경할 나이
	
	int ret = mDB.updateMember(member); //성공하면 1, 실패시 -1
	System.out.println(ret);

이렇게 메인클래스에서 기준이 되는 ID를 제외하고 나머지를 바꿔줄 값으로 대입한다. 문제없이 따라왔다면

위와 같이 1이 출력된걸 확인할 수 있고,

변경이 된것을 확인 할 수 있다.

그렇다면 다음으로는 회원탈퇴, 데이터 삭제이다.

방금 수정이 된 아이디 bbb의 회원정보를 한번 삭제시켜보자.

public int deleteMember(String id) {
		try {
			Bson filter = Filters.eq("_id", id);
			DeleteResult result = this.collection.deleteOne(filter);
			System.out.println(result.toString());
			return 1;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
    }
 }

다음과 같이 메소드를 만들어 DeleteResult 메소드를 이용하여 입력된 id 값을 삭제시킨다. try catch문을 사용해 오류가 없는지 또한 검사한다. 이후 메인에서 아래 코드로 실행하게되면

public static void main(String[] args) {

        MemberDB mDB = new MemberDB();
	    // 회원정보 삭제하기
		int ret = mDB.deleteMember("bbb");  // 정보가 삭제되어도 1이 뜨는 문제 해결필요
		System.out.println(ret);
}


(모르고 1을 출력하는 코드를 안넣고 찍었다.. 양해바란다.)

위처럼 나오게 된다. 계정이 하나 지워졌고
{deletedCount = 1}

정상적으로 잘 작동했다고 1이 출력되었다.

하지만 여기서 문제가 발생한다.


이미 지워진 아이디를 다시 한번 더 삭제했는데도

1이 출력이 되는 것이다.

그렇다면 어떻게 해결하여야 할까??

public int deleteMember(String id) {
		try {
			Bson filter = Filters.eq("_id", id);
			DeleteResult result = this.collection.deleteOne(filter);
			System.out.println(result.toString());
			if (result.getDeletedCount() == 1L) {
				return 1;
			}
			return 0;

		} catch (Exception e) {
			e.printStackTrace();
			return -1;
	}
 }

바로 try문에서 if문을 넣어

삭제가 이루어진 경우 {deletedCount = 1} 에만 1이라는 값을 반환하도록 조건문을 넣을 수 있다.

삭제가 이루어지지 않는 경우, 0이 출력되도록 try문을 살짝 수정하였다.

그렇다면 이미 지워진 아이디값에 대해서


이렇게 0이라는 값을 도출하게 되기 때문에 추후 혼동이 될 부분을 원천적으로 차단할 수 있겠다.

아래는 이후 추가된 예제문제까지 구성이 완료된 코드이다.

package day6;

import org.bson.Document;
import org.bson.conversions.Bson;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.InsertOneResult;
import com.mongodb.client.result.UpdateResult;
// 기능용 클래스
// 몽고DB 연동

public class MemberDB {
	MongoCollection<Document> collection = null;

	// 변수는 모든 메소드에 사용 가능하기 위해 바깥으로 뺌.
	// 변수 X
	// 생성자
	public MemberDB() {
		// 공통변수가 아니기 때문에 생성자 내부에서만 사용가능한 변수 생성.

		// final 을 붙이면 생성 당시의 값으로 프로그램이 끝날때 까지 유지가 된다. 이유는 바꿀수 없기 때문.
		// mongodb://아이디:비밀번호@주소:포트번호/디비명
		final String url = "mongodb://아이디:비밀번호@주소:포트번호/디비명";
		// static클래스를 통해서 접속이 가능함. (import도 해주어야 함.)
		MongoClient client = MongoClients.create(url);
		MongoDatabase db = client.getDatabase("db209");
		this.collection = db.getCollection("members");
	}

	// 특정 이름의 사람만 조회
	public void printMembersName(String searchName) { // 
		// 키 또는 필드가 name인 것중에서 searchName과 정확하게 일치하는 필터
		Bson filter = Filters.eq("name", searchName);
		MongoCursor<Document> list = this.collection.find(filter).iterator();
		while (list.hasNext()) { // 2개 있으니 2번 수행
			Document doc = list.next();
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");
		}
	}

	// 전체 회원조회 메소드
	public void printMembers() {
		MongoCursor<Document> list = this.collection.find().cursor(); // 반복자
		// 1000 => 500개만 출력(X)
		// 반복자(처음부터 끝까지 전체다 반복할거라고 가정
		/*-----------------------------반복자 반복문----------------------------*/
		// 가져올 데이터가 있나요?? (반복문)
		while (list.hasNext()) { // 그 다음 가져 올 데이터가 있는지?
			Document doc = list.next();
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");
		}
	}

	// 회원가입 메소드
	public int insertMember(Member member) {
		try { // 정상동작
			Document doc = new Document();
			// 키가 반드시 _id 기본키로 봄. (id는 중복되어 DB에 올라갈 수 없다.)
			doc.append("_id", member.getId());
			doc.append("password", member.getPassword());
			doc.append("name", member.getName());
			doc.append("age", member.getAge());
			doc.append("phone", member.getPhone());
			doc.append("role", member.getRole());
			doc.append("regdate", member.getRegdate());
			InsertOneResult result = this.collection.insertOne(doc);
			System.out.println(result.toString());
			return 1;

		} catch (Exception e) {// 오류가 발생 시 이쪽의 메소드가 수행됨.

			// Exception클래스의 e변수에 오류의 정보(오류 메시지)가 전송되게 됨.
			e.printStackTrace(); // 오류 메세지를 전체적으로 출력해줌. 개발자를 위한 기능

			return -1; // 오류시 보통 -1로 반환함!
		}
	}
    // 결과 생성용 메소드
	public void printAction(Bson filter) {
		MongoCursor<Document> list = this.collection.find(filter).iterator();
		while (list.hasNext()) {
			Document doc = list.next();
			System.out.println("아이디 =>" + doc.getString("_id"));
			System.out.println("비밀번호 =>" + doc.getString("password"));
			System.out.println("나이 =>" + doc.getInteger("age"));
			System.out.println("------------------------------------");
		}
	}
	
	/*---------------------문제-------------------------*/
	// 문제1) 고객, 판매자만 조회하는 필터링
	// 조건과 같으면 .eq
	public void printMembersRole(String searchRole) {
		// 키 또는 필드가 name인 것중에서 searchRole과 정확하게 일치하는 필터
		Bson filter = Filters.eq("role", searchRole);
		printAction(filter);

	}

	// 문제2) 나이가 n 이상인 것만 필터링
	// 이상이면 .gte, 이하면 .lte이다. 크면 gt, 작으면 lt[맛있는MongoDB Pg.91]
	public void printMembersAge(Integer n) {
		// 키 또는 필드가 name인 것중에서 searchName과 정확하게 일치하는 필터
		Bson filter = Filters.gte("age", n);
		printAction(filter);
	}

	// 회원정보 수정하기. 이름, 연락처, 나이정보 (암호는 변경 불가능.)
	public int updateMember(Member member) {
		try {
			// 변경하고자 하는 항목의 조건
			/* 2번 */ Bson filter = Filters.eq("_id", member.getId());

			// 변경할 항목들...
			/* 3번 */ Bson update1 = Updates.set("name", member.getName());
			Bson update2 = Updates.set("phone", member.getPhone());
			Bson update3 = Updates.set("age", member.getAge());

			// updateOne (조건, 변경값) => 변경값이 하나의 Bson에만 가능.. combine
			/* 4번 */ Bson update = Updates.combine(update1, update2, update3);

			/* 1번 */ UpdateResult result = this.collection.updateOne(filter, update);
			System.out.println(result.toString());
			return 1;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}

	}

	public int deleteMember(String id) {
		try {
			Bson filter = Filters.eq("_id", id);
			DeleteResult result = this.collection.deleteOne(filter);
			System.out.println(result.toString());
			if (result.getDeletedCount() == 1L) {
				return 1;
			}
			return 0;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}

추가적으로 MongoDB란

C++로 작성된 오픈소스 문서지향(Document-Oriented) 적 Cross-platform 데이터베이스이며, 뛰어난 확장성과 성능을 자랑한다. 또한, 현존하는 NoSQL 데이터베이스 중 인지도 1위를 유지하고있는 DB이다.

MongoDB 공식 홈페이지의 다운로드 페이지에서 MSI 파일로 설치하면

C:\Program Files\MongoDB\Server\3.2\bin\ 에 설치된다.

CMD 창을 열어서 디렉토리로 들어가 mongod 를 실행하면 서버가 실행되게 된다.

기본 데이터베이스 디렉토리가 C:\data\db 이므로 실행 전에 폴더를 수동으로 만들어주어야 한다.


profile
시작은 미약하지만, 그 끝은 창대하리라

0개의 댓글