вторник, 8 июля 2008 г.

Минимализм: Толстушки меня не привлекают

Здравствуйте, уважаемые.
Будучи известным минималистом, не желая работать ни с RMI, ни с SOAP, ни с Cobra, выбрав голый байтовый протокол, вооружился я средством от Apache, именуемым MINA.

Будучи известным минималистом, не желая работать ни со Spring, ни со Struts, ни с Tribune, вооружился я средством от Apache, именуемым Velocity и набросал свой мини фреймворк.

Будучи известным минималистом, не желая работать ни с FormLayout, ни с чем-нибудь еще, ни с чем-нибудь еще, вооружился я GridBagLayout и набросал свой мини класс

Будучи известным минималистом, не желая работать ни с Hibernate, ни с TopLink, ни с прочим JPA, вооружился я средством от Apache, именуемым dbcp и набросал свой мини фреймворк.

Он не настолько крут, как Hibernate, но для работы с перзистивным слоем вполне пригоден ^_^
Итак, в этот раз я хочу представить вашему вниманию свои наброски по работе с данными перзистивного слоя.

Из-за его простоты и отсутствия работы с рефлексией, необходимо четко представлять структуру таблиц баз данных, а также брать всю работу ORM на себя + отсутствие HQL запросов, который при всей моей нелюбви к большим вещам, вызывает у меня большую симпатию.

Если желание еще не пропало, начинаем.
Классический пример. Пользователь и его заказы.

package ru.vingrad.platon.perst.test;

import ru.vingrad.platon.perst.DAORequestException;

import java.util.List;

public class User {
private long id;
private String login;
private String password;
private int rating;

private static final UserOrderManager ORDER_MANAGER = new UserOrderManager();

public User(long id, String login, String password, int rating) {
this.id = id;
this.login = login;
this.password = password;
this.rating = rating;
}

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getRating() {
return rating;
}

public void setRating(int rating) {
this.rating = rating;
}

// Разбираемся с ORM

private List<UserOrder> orders;

public List<UserOrder> getOrders() {
if (orders == null)
try {
orders = ORDER_MANAGER.getUserOrders(this);
}
catch (DAORequestException e) {
e.printStackTrace();
}
return orders;
}

public void setOrders(List<UserOrder> orders) {
this.orders = orders;
}
}


package ru.vingrad.platon.perst.test;

import ru.vingrad.platon.perst.jdbc.DAOManagerJDBC;
import ru.vingrad.platon.perst.jdbc.SQLFactory;
import ru.vingrad.platon.perst.jdbc.SqlData;
import ru.vingrad.platon.perst.jdbc.SqlVariant;
import ru.vingrad.platon.perst.DAORequestException;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

public class UserItemManager extends DAOManagerJDBC<User> {

private static final SQLFactory<User> factory = new SQLFactory<User>() {
public User build(ResultSet rec) throws SQLException {
return new User(rec.getLong("record_id"), rec.getString("login"), rec.getString("password"), rec.getInt("rating"));
}

public List<SqlData> insertPart(User item) {
List<SqlData> m = updatePart(item);
m.add(
new SqlData("login", item.getLogin()));
return m;
}

public List<SqlData> updatePart(User item) {
return Arrays.asList(
new SqlData("password", item.getPassword()),
new SqlData("rating", item.getRating())
);
}

public List<SqlData> primaryPart(User item) {
return Arrays.asList(new SqlData("record_id", item.getId()));
}
};

public UserItemManager() {
super("users", "record_id", factory);
}

public User get(String login) throws DAORequestException {
return get("login = ?", Arrays.asList(new SqlVariant(login)));
}

public User get(String login, String password) throws DAORequestException {
return get("login = ? AND password = ?", new SqlVariant[]{new SqlVariant(login), new SqlVariant(password)});
}
}


package ru.vingrad.platon.perst.test;

public class UserOrder {
private long id;
private String description;
private long userId;

public UserOrder(long id, String description, long userId) {
this.id = id;
this.description = description;
this.userId = userId;
}

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public long getUserId() {
return userId;
}

public void setUserId(long userId) {
this.userId = userId;
}

// Разбираемся с ORM

private User user;

public User getUser() {
if (user == null)
user = new UserItemManager().get(userId);
return user;
}

public void setUser(User user) {
this.user = user;
userId = user.getId();
}
}


package ru.vingrad.platon.perst.test;

import ru.vingrad.platon.perst.jdbc.*;
import ru.vingrad.platon.perst.DAORequestException;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

public class UserOrderManager extends DAOManagerJDBC<UserOrder> {

private static final SQLFactory<UserOrder> factory = new SQLFactory<UserOrder>() {
public UserOrder build(ResultSet rec) throws SQLException {
return new UserOrder(rec.getLong("order_id"), rec.getString("description"), rec.getLong("user_id"));
}

public List<SqlData> insertPart(UserOrder item) {
return updatePart(item);
}

public List<SqlData> updatePart(UserOrder item) {
return Arrays.asList(
new SqlData("description", item.getDescription()),
new SqlData("user_id", item.getId())
);
}

public List<SqlData> primaryPart(UserOrder item) {
return Arrays.asList(new SqlData("order_id", item.getId()));
}
};

public UserOrderManager() {
super("user_order", "order_id", factory);
}

public List<UserOrder> getUserOrders(User user) throws DAORequestException {
return getList("user_id = ?", Arrays.asList(new SqlVariant(user.getId())));
}
}



SQLFactory представляет здесь для нас новизну. Состоит из 4-х методов
build(ResultSet) восстанавливает из записи объект Java
insertPart(T item) возвращает список полей таблицы и их значений, которые необходимо вставлять в запрос при добавлении записи в таблицу базы данных
updatePart(T item) возвращает список полей таблицы и их значений, которые необходимо вставлять в запрос при обновлении записи в таблице базы данных
primaryPart(T item) возвращает список полей таблицы и их значений, которые являются первичным ключем

Perst (0.1.1)

PS. Не смотря на нелюбовь к большим вещам, чтобы никто не смог обвинить меня в глупости и слепости, должен подчеркнуть: JPA - это мощный инструмент, попавший в руки программиста, я представляю его основные возможности и преимущества и ни в коем случае не хотел в этой статье агитировать читателей не пользоваться этим волшебным инструментом.

Комментариев нет: