lec-14-DAO-v001
.pdfИНТЕРФЕЙС BOOKSTOREDAO
(ОКОНЧАНИЕ)
public Book getBook( int bkID ) throws DAOSysException;
public void getBooks( List<Book> p_items ) throws DAOSysException;
public void getBookAuthors( int bkid, List<BookAuthor> p_items ) throws DAOSysException;
public void getBooksByName( String partBookName, List<Book> p_items ) throws DAOSysException;
//
public Customer getCustomer( String userName ) throws DAOSysException;
public void getCustomers( String lastName, List<Customer> p_items ) throws DAOSysException;
}
При получении коллекции объектов перед вызовом надо создать коллекцию. Затем ссылка на этот объект будет передаваться в вызываемый метод с тем, чтобы в классе, реализующем интерфейс BookStoreDAO, в коллекцию были
помещены все извлеченные из базы данных объекты. Мы воспользуемся двумя простыми реализациями для интерфейса BookStoreDAO для Derby и для Oracle.
В данном случае тексты реализаций одинаковы. Однако при таком подходе неизбежны разные реализации. Например, при выполнении SQL операции в Derby, когда имеется столбец с названием year, его надо заключать в кавычки.
КЛАСС DERBYDAO
package org.bookstore.dao; import java.sql.*;
import java.util.*; import javax.naming.*; import javax.sql.*;
import org.bookstore.model.*; import org.bookstore.common.Glo;
/**
*This class implements BookStoreDAO for Derby DB.
*This class encapsulates all the SQL calls.
*/
public class DerbyDAO
implements BookStoreDAO, java.io.Serializable { public static String GET_CUSTOMER_STATEMENT
="select * from customer where username = ?"; public static String GET_CUSTOMERS_STATEMENT
="select * from customer where last_name LIKE ? order by last_name"; public static String GET_BOOK_STATEMENT
="select * from book where bk_id = ?";
public static String GET_BOOKS_STATEMENT
="select * from book order by bk_id"; public static String GET_BOOKLIKE_STATEMENT
="select * from book where name LIKE ? order by name";
. . .
КЛАСС DERBYDAO (ПРОДОЛЖЕНИЕ)
public static String GET_AUTHOR_STATEMENT
="SELECT * FROM author WHERE au_id = ?"; public static String GET_AUTHORS_STATEMENT
="SELECT * FROM author";
public static String GET_BOOKAUTHORS_STATEMENT
="SELECT a.bkid, a.auid, b.last_name, b.first_name ,b.country "
+"FROM book_author a, author b "
+"WHERE a.auid=b.au_id AND a.bkid = ?";
private transient DataSource dsn; private String dsName;
//--------------------------------------
public DerbyDAO() {}
public DerbyDAO( String p_dsName )
throws DAOSysException {
dsName = p_dsName; getDataSource();
}
//--------------------------------------
public void setDsName( String p_dsName ) { dsName = p_dsName;
}
. . .
КЛАСС DERBYDAO (ПРОДОЛЖЕНИЕ)
//-------------------------------------------------
// Business methods //-------------------------------------------------
private Connection getConn() throws DAOSysException { try {
if (dsn == null) getDataSource(); if( dsn == null )
throw new DAOSysException("Could not get DataSource Reference in DerbyDAO");
return dsn.getConnection(); } catch (SQLException se) {
throw new DAOSysException("SQLException: " + se.getMessage());
}
}
. . .
КЛАСС DERBYDAO (ПРОДОЛЖЕНИЕ)
private void getDataSource() throws DAOSysException {
if( dsName == null || dsName.equals("") || dsName.length() < 2 ) throw new DAOSysException(
"First set dsName in DerbyDAO.getDataSource()"); StringBuilder sb = new StringBuilder();
sb.append( Glo.DS_CONTEXT_NAME ); sb.append( "/" ).append( dsName ); try {
Context initCtx = new InitialContext();
dsn = (DataSource) initCtx.lookup( sb.toString() );
}
catch( NamingException ne ) { throw new DAOSysException(
"Error Data Source lookup. " + ne.getMessage());
}
}
//-------------------------------------------------
public Author getAuthor( int auID ) throws DAOSysException { Connection c = null;
PreparedStatement ps = null; ResultSet rs = null;
Author ret = null;
. . .
КЛАСС DERBYDAO (ПРОДОЛЖЕНИЕ)
try {
c = getConn();
ps = c.prepareStatement( GET_AUTHOR_STATEMENT, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ps.setInt(1, auID ); rs = ps.executeQuery(); if (rs.first()) {
ret = new Author( auID, rs.getString(2), rs.getString(3), rs.getString(4));
}
return ret;
}catch (SQLException se) {
throw new DAOSysException("SQLException: " + se.getMessage());
}finally {
try {
if (rs != null) rs.close(); if (ps != null) ps.close(); if (c != null) c.close();
} catch (Exception e) {};
}
}
. . .
КЛАСС DERBYDAO (ОКОНЧАНИЕ)
public void getBooks( List<Book> p_items ) throws DAOSysException { Connection c = null;
PreparedStatement ps = null; ResultSet rs = null;
try {
c = getConn();
ps = c.prepareStatement(GET_BOOKS_STATEMENT, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = ps.executeQuery(); |
|
while( rs.next() ) { |
|
p_items.add( new Book( rs.getInt(1), |
rs.getInt(2), |
rs.getString(3), |
rs.getString(4), |
rs.getString(5), |
rs.getInt(6), |
rs.getString(7), |
rs.getInt(8), |
rs.getDouble(9), |
rs.getString(10))); |
} |
|
}catch (SQLException se) {
throw new DAOSysException("SQLException: "+se.getMessage());
}finally { try { if (rs != null) rs.close();
if (ps != null) ps.close(); if (c != null) c.close();
} catch (Exception e) {};
}
}
НЕКОТОРЫЕ ОСОБЕННОСТИ РЕАЛИЗАЦИИ
Поскольку наша реализация DAO сериализуемая,
пришлось ссылку на источник DataSource сделать transient, и поэтому при получении подключения приходится проверять ссылку на источник и искать его вновь, если ссылка имеет значение null. Сериализовать классы DerbyDAO и OracleDAO необходимо потому, что классы служб AuthorService и BookService, реализующие шаблон Session Fasade сериализованы, а они содержат ссылку на вышеуказанные объекты.
Объекты типа AuthorService и BookService создаются в классе действия при первой навигации по пути к странице, содержащей ссылку на это действие. При первой попытке выполнить первое обращение к базе данных в классах служб автоматически, вызовом метода makeDAO(), создается объект типа BookStoreDAO (объект заданной реализации) и сохраняется ссылку на него. Затем при всех обращениях к базе данных, методы служб вызывают методы объекта типа BookStoreDAO.
КЛАСС AUTHORSERVICE
package org.bookstore.services; import org.bookstore.model.*; import java.util.*;
import org.bookstore.dao.*;
public class AuthorService implements java.io.Serializable { private List<Author> authorList = new ArrayList<Author>();
private int |
auId = -1; |
// id автора |
private BookStoreDAO dao; |
|
|
private String daoDescr; |
|
|
//-------------- |
Constructors ----------------------- |
public AuthorService() {}
public AuthorService( String p_daoDescr ) { daoDescr = p_daoDescr;
}
//--------------------------------------------
public Author getAuthor() throws Exception { if (dao == null) makeDAO();
if( auId < 0 )
throw new Exception(
"До получения автора надо задать его ID как параметр запроса "); return dao.getAuthor( auId );
}
. . .
КЛАСС AUTHORSERVICE (ПРОДОЛЖЕНИЕ)
public List<Author> getAuthors() throws Exception { if (dao == null) makeDAO();
if( authorList.size() < 1 ) dao.getAuthors( authorList ); return authorList;
}
//--------------------------------------------
public int getSize() {
if( authorList == null ) {
authorList = new ArrayList<Author>(); return( 0 );
}
return authorList.size();
}
//--------------------------------------------
public int getAuId() { return auId ;
}
//--------------------------------------------
public void setAuId( int p_auId ) { auId = p_auId;
}
. . .