비지니스 로직과 DB를 분리하기 위해서 사용하는 패턴이다. DAO는 Data Access Object의 약자로 DB의 접근을 전담하게 된다.
DB를 사용하는 방법이 변경되더라도 클라이언트 로직이 변경되지 않도록 DB 로직을 캡슐화 하여 분리하는 방법.
설계
DAO : 기본적인 CRUD 인터페이스를 제공한다.
DaoImpl : DAO 인터페이스를 구현한 구체 클래스이다.
Value Object : DAO를 사용하여 데이터를 저장하는 POJO (plain old java obj)
JDBC (Java Database Connectivity)
데이터베이스 비종속적 표준 자바 API이다. 다양한 DB를 동일한 인터페이스로 사용할 수 있도록 추상화 해준다. 각종 DB는 JDBC Driver를 통해서 연결하고 사용하게 된다.
ODBC
예전 다양한 DB (oracle, msSql, mySql, h2 등)이 존재했을 때 각기 다른 인터페이스를 갖고 있었다. 이를 하나의 인터페이스로 통합하여 사용하기 위해 나온 것이 ODBC이다. windows 환경에서 DB들에 대해 공통의 인터페이스를 제공하기 위해 나온 것이라면 JDBC는 java 환경에서 DB들을 하나의 API로 접근하기 위해 개발된 것이다.
JDBC 사용
DB에 연결
DriverManager.getConnection("DB URL") 을 통해서 DB에 연결한다.
Connection 인터페이스를 반환 받는다.
DB URL이 필요하다
MySql : "jdbc:mysql://localhost:3306/" + "db_name"
public class AddressBook_withoutDB {
public static void main(String[] args) {
Person person;
PersonDao personDao = new PersonDaoImpl_withoutDB();
System.out.println("--- inserting ...");
person = new Person("woonsik", "anyang-si");
personDao.insert(person);
person = new Person("boonsik", "gangnam-gu");
personDao.insert(person);
System.out.println("--- finding all ...");
for (Person p : personDao.findAll()) {
System.out.println("reading... " + p);
}
System.out.println("--- updating ...");
person = personDao.findAll().get(0);
person.setName("handsome Guy");
personDao.update(person.getId(), person);
System.out.println("--- check updated ...");
person = personDao.findById(1);
if (person != null)
System.out.println(person);
System.out.println("--- deleting by id ...");
personDao.deleteById(2);
System.out.println("--- show all after delete ...");
for (Person p : personDao.findAll()) {
System.out.println("reading... " + p);
}
}
}
Person 객체 클래스 (POJO)
public class Person {
private static int count = 0;
private int id;
private String name;
private String address;
public Person(String name, String address) {
this.name = name;
this.address = address;
this.id = ++count;
}
public Person(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "Person> " +
"id=" + id +
", name='" + name + "'" +
", address='" + address + "'";
}
/*
getter, setter 생략
*/
}
PersonDao Interface 클래스 (DAO)
import java.util.List;
public interface PersonDao {
void insert(Person person);
List<Person> findAll();
Person findById(int id);
void update(int id, Person person);
void delete(Person person);
void deleteById(int id);
}
PersonDaoImpl_withoutDB 클래스 (DAO 구체 클래스 with List)
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PersonDaoImpl_withoutDB implements PersonDao {
List<Person> personList;
public PersonDaoImpl_withoutDB() {
this.personList = new ArrayList<>();
}
@Override
public void insert(Person person) {
personList.add(person);
}
@Override
public List<Person> findAll() {
return personList;
}
@Override
public Person findById(int id) {
return personList.stream()
.filter(p -> p.getId() == id)
.collect(Collectors.toList()).get(0);
}
@Override
public void update(int id, Person person) {
personList.stream()
.filter(o -> o.getId() == id)
.findFirst().ifPresent(p -> {
p.setName(person.getName());
p.setAddress(person.getAddress());
});
}
@Override
public void delete(Person person) {
deleteById(person.getId());
}
@Override
public void deleteById(int id) {
personList.stream()
.filter(p -> p.getId() == id)
.findFirst()
.map(o -> personList.remove(o));
}
}