Статьи

Реализация проектирования на основе домена с шаблонами Spring JDBC

Дизайн, управляемый доменом (DDD), позволяет разрабатывать приложения более объектно-ориентированным образом. Современные подходы к разработке JEE способствуют использованию объектов JPA / Hibernate в качестве элементов хранения данных и дополняют дополнительный уровень обслуживания поверх этих объектов JPA. Это заставляет вас структурировать ваше приложение более процедурным образом. DDD позволяет вам кодировать бизнес-логику в основном в объектах вашего домена. Использование методов DDD сводит к минимуму использование и сложность дополнительного уровня обслуживания, поэтому вы можете получить более простой дизайн и ускорить разработку.

Я расскажу о способе реализации DDD с помощью Spring JDBC. Позвольте мне объяснить основные структуры в моей реализации;

 Приложение-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">


<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:book"/>
<property name="username" value="SA" />
<property name="password" value=""/>
<property name="initialSize" value="1"/>
<property name="maxActive" value="10"/>
</bean>


<bean id="dateUtil" class="dddWithSpringJdbc.DateUtil">
</bean>

<bean id="book" class="dddWithSpringJdbc.Book" scope="prototype">
<property name="dateUtil" ref="dateUtil"></property>
</bean>

<bean id="bookRepository" class="dddWithSpringJdbc.repository.impl.BookRepository">
<property name="dataSource" ref="dataSource"></property>
</bean>

</beans>

Этот файл настраивает среду Spring.

Конфигурация транзакции;

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:book"/>
<property name="username" value="SA" />
<property name="password" value=""/>
<property name="initialSize" value="1"/>
<property name="maxActive" value="10"/>
</bean>

Бины «txManager» и «dataSource» устанавливают конфигурацию транзакции. Требуется использовать аннотации @Transactional для ваших методов и классов. Компонент «dateUtil» — это простой служебный класс для форматирования дат.
«Книга» представляет собой объект домена. «bookRepository» — это объект для извлечения и сохранения объектов «Book».

Модельный объект, Book.java

public class Book {

private String name;
private int id;
private DateUtil dateUtil;
private Date dateAdded;

public Book() {
dateAdded = new Date();
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}

public void setDateUtil(DateUtil dateUtil) {
this.dateUtil = dateUtil;
}

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

public int getId() {
return id;
}


public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public String formatDateAdded() {
return dateUtil.formatDate(dateAdded);
}

}

 

 Объекты хранилища;

IBookRepository.java;

public interface IBookRepository {

public List<Book> findBooks();
public void insert(Book book);
public void init();
}

«IBookRepository» используется для получения объектов «Книга» из базы данных и записи их в базу данных. Это разновидность DAO, используемая на платформах JEE.

BaseRepository.java

public abstract class BaseRepository extends NamedParameterJdbcDaoSupport implements BeanFactoryAware{

private BeanFactory bf;

public void setBeanFactory(BeanFactory bf) throws BeansException {
this.bf = bf;
}

protected <T> T createBean(String name) {
return (T)bf.getBean(name);
}

protected NamedParameterJdbcTemplate getTemplate() {
return super.getNamedParameterJdbcTemplate();
}
}

Это используется для извлечения bean-компонентов из Spring и для помощи в выполнении операций с базой данных. Вы можете получить бин из контекста Spring, вызвав метод «getBean ()».

BookRepository.java

@Transactional(propagation=Propagation.REQUIRED)
public class BookRepository extends BaseRepository implements IBookRepository {

@Transactional(readOnly=true)
@Override
public List<Book> findBooks() {
return getTemplate().query("select * from BOOK order by name asc", (Map) null, new ParameterizedRowMapper<Book>() {

@Override
public Book mapRow(ResultSet rs, int index) throws SQLException {
Book book = createBean("book");

book.setId(rs.getInt("id"));
book.setName(rs.getString("name"));

return book;
}

});

}

public void insert(Book book) {
String sql = "insert into BOOK(id, name) values(:id, :name);";


Map<String, Object> params = new HashMap<String, Object>();
params.put("id", book.getId());
params.put("name", book.getName());

getTemplate().update(sql, params);

}

@Override
public void init() {
getTemplate().update("CREATE TABLE BOOK (id int not null primary key, name varchar(256));", (Map) null);
getTemplate().update("insert into BOOK(id, name) values(1, 'Book1');", (Map) null);

}
}

 «BookRepository» — это объект репозитория, выполняющий операции с базой данных. «findBooks ()» извлекает всю информацию о книге из базы данных. Обратите внимание, что для этого он извлекает объект «Книга» из контекста Spring, вызывая метод «createBean ()». Spring создает, инициирует и возвращает управляемый компонент «Book».
«insert ()» просто добавляет еще один объект «Book» в базу данных. «init ()» подготавливает базу данных для приложения.
    
Пример приложения начинается с вызова метода main класса «Start».

Start.java

public class Start {

public static void main(String [] args) {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("/application-context.xml");
IBookRepository repository = (IBookRepository)appContext.getBean("bookRepository");

repository.init();

List<Book> bookList = repository.findBooks();

Book firstBook = bookList.get(0);
String formattedString = firstBook.formatDateAdded();

System.out.println("result=" + formattedString);

}
}

Цель этого фрагмента кода — отформатировать свойство dateAdded объекта Book. Для этого
объект «Книга» использует объект «DateUtil», который вводится в него для форматирования даты. Вы можете получить отформатированную строку
, вызвав метод formatDateAdded () объекта «Книга», не касаясь объекта «DateUtil».

Вы можете найти соответствующий исходный код в виде прикрепленного zip- файла в разделе Ресурсы.