Jumat, 21 September 2012

DAO dan Service Pattern

Akses terhadap database merupakan bagian yang sangat penting dari aplikasi database. Penggunaan pattern yang sesuai dapat memberikan manfaat sangat besar. Pattern yang sering digunakan dalam akses database adalah DAO (Data Access Object) dan Service/Facade pattern.

Kedua pattern ini digunakan untuk menerapkan “separation of concern” atau pemisahan kode proram berdasarkan fungsi kode program. Semua kode untuk akses data harus dipisahkan dengan kode untuk pengaturan user inteface. Hal ini memungkinkan kode akses data yang dibuat untuk aplikasi desktop, dengan mudahdigunakan untuk aplikasi web.

Penerapan konsep separation of concern secara disiplin, dapat menghasilkan kode program yang dapat dites secara otomatis menggunakan JUnit atau DBUnit. Unit testing merupakan paramater utama dalam menentukan apakah kode program yang kita hasilkan mempunyai mutu yang tinggi atau tidak. Coverage unit testing yang tinggi mencerminkan kode program yang berkualitas tinggi pula.

Dao pattern berisi semua kode untuk mengakses data, seperti query. Semua kode yang sepesifik terhadap implementasi akses data berhenti di sini, lapisan lebih atas tidak boleh tahu bagaimana akses data diterapkan, apakah menggunakan JDBC murni atau Hibernate atau JPA. Lapisan lainya hanya perlu tahu fungsionalitas dari suatu method di dalam DAO class, tidak perlu tahu bagimana method tersebut diimplementasikan. Class DAO akan mempunyai method seperti save, delete, getById atau getAll. Praktek yang lazim digunakan adalah satu buah Entity/Table akan mempunyai satu buah class DAO.

Di bawah ini adalah contoh Class DAO menggunakan JDBC untuk table T_CATEGORY :

public class CategoryDaoJdbc {
private Connection connection;
private PreparedStatement insertStatement;
private PreparedStatement updateStatement;
private PreparedStatement deleteStatement;
private PreparedStatement getByIdStatement;
private PreparedStatement getAllStatement;
private final String insertQuery =
"insert into T_CATEGORY(name,description)" +
" values(?,?)";
private final String updateQuery =
"update T_CATEGORY set name=?, description=? " +
" where id=?";
private final String deleteQuery =
"delete from T_CATEGORY where id=?";
private final String getByIdQuery =
"select * from T_CATEGORY where id =?";
private final String getAllQuery =
"select * from T_CATEGORY";
public void setConnection(Connection connection) {
try {
this.connection = connection;
insertStatement =
this.connection.prepareStatement(
insertQuery,Statement.RETURN_GENERATED_KEYS);
updateStatement =
this.connection.prepareStatement(
updateQuery);
deleteStatement =
this.connection.prepareStatement(
deleteQuery);
getByIdStatement =
this.connection.prepareStatement(
getByIdQuery);
getAllStatement =
this.connection.prepareStatement(
getAllQuery);
} catch (SQLException ex) {
}
}
public void save(Category category) {
try {
if (category.getId() == null) {
insertStatement.setString(1,
category.getName());
insertStatement.setString(2,
category.getDescription());
int id = insertStatement.executeUpdate();
category.setId(id);
} else {
updateStatement.setString(1,
category.getName());
updateStatement.setString(2,
category.getDescription());
updateStatement.setInt(3, category.getId());
updateStatement.executeUpdate();
}}
catch (SQLException ex) {
}
}
public void delete(Category category) {
try {
deleteStatement.setInt(1, category.getId());
deleteStatement.executeUpdate();
} catch (SQLException ex) {
}
}
public Category getById(Long id) {
try {
getByIdStatement.setLong(1, id);
ResultSet rs = getByIdStatement.executeQuery();
//proses mapping dari relational ke object
if (rs.next()) {
Category category = new Category();
category.setId(rs.getInt("id"));
category.setName(rs.getString("name"));
category.setDescription(
rs.getString("description"));
return category;
}
} catch (SQLException ex) {
}
return null;
}
public List<Category> getAll() {
try {
List<Category> categories =
new ArrayList<Category>();
ResultSet rs = getAllStatement.executeQuery();
while(rs.next()){
Category category = new Category();
category.setId(rs.getInt("id"));
category.setName(rs.getString("name"));
category.setDescription(
rs.getString("description"));
categories.add(category);
} return categories;
} catch (SQLException ex) {
}
return null;
}
}

Service pattern digunakan utamanya untuk menyederhanakan class-class DAO yang ada, misalnya kita mempunyai 50 buah table maka lazimnya akan ada 50 buah class DAO. Class DAO tersebut perlu disederhanakan, caranya adalah dengan mengelompokkan class-class DAO dalam satu modul aplikasi ke class Service. Misalnya DAO yang berhubungan dengan user management ke dalam class UserService.

Transaction diatur dalam class Service, praktek yang lazim digunakan adalah satu method dalam class service adalah satu scoop transaction. Jadi ketika method dalam service mulai dieksekusi transaction akan dimulai (begin), ketika method akan berakhir, transaction akan dicommit.

Berikut ini adalah contoh class Service :

public class ServiceJdbc {
private CategoryDaoJdbc categoryDao;
private Connection connection;
public void setDataSource(DataSource dataSource){
try {
connection = dataSource.getConnection();
categoryDao = new CategoryDaoJdbc();
categoryDao.setConnection(connection);
} catch (SQLException ex) {
}
}
public void save(Category category){
try {
connection.setAutoCommit(false);
categoryDao.save(category);
connection.commit();
connection.setAutoCommit(true);
} catch (SQLException ex) {
try{
connection.rollback();
}catch(SQLException e){
}
}
}
public void delete(Category category){
try {
connection.setAutoCommit(false);
categoryDao.save(category);
connection.commit();
connection.setAutoCommit(true);
} catch (SQLException ex) {
try{
connection.rollback();
}catch(SQLException e){
}
}
}
public Category getGroup(Long id){
return categoryDao.getById(id);
}
public List<Category> getGroups(){
return categoryDao.getAll();
}
}

Setelah class DAO dan service berhasil dibuat, mari kita lihat bagaimana cara menggunakannya :

public class MainJdbc {
public static void main(String[] args) {
MysqlDataSource dataSource =
new MysqlDataSource();
dataSource.setUser("root");
dataSource.setPassword("admin");
dataSource.setDatabaseName("latihan");
dataSource.setServerName("localhost");
dataSource.setPortNumber(1527);
ServiceJdbc service = new ServiceJdbc();
service.setDataSource(dataSource);
Category category = new Category();
category.setName("administrator");
service.save(category);
System.out.println("id : " + category.getId());
System.out.println("name : " +
category.getName());
try {
dataSource.getConnection().close();
} catch (SQLException ex) {
}
}
}

Setelah mengenal JDBC, kita akan membahas cara mengakses database yang lebih baik dengan manggunakan JPA. Dengan menggunakan JPA kode program yang akan dibuat akan lebih ringkas dan terlihat konsep OOP dibanding dengan JDBC murni. JPA adalah framework ORM untuk memetakan tabel dalam database dan class dalam konsep OOP. Dengan menggunakan JPA kode program kita akan lebih rapi dan terlihat OOP.

1 komentar:

  1. Mau nanya nih..pada method save di class CategoryDaoJdbc.
    int id = insertStatement.executeUpdate();
    value dari variable id apa ya?
    Terima kasih

    BalasHapus