Filtrowanie danych w dao czy serwisie?

0

Hej. Powiedzmy, że piszę sobie bibliotekę z książkami i chciałabym teraz filtrować książki po autorze książki. Czy taka metoda powinna być w BookDao czy powinno to być w serwisie? Obecnie trzymam kilka książek w pliku CSV, wiec wszystko mi jedno, ale gdybym w przyszłości chciała hibernate/mysql z milionem książek może hibernate/mysql ma jakieś wydajniejsze filtry i powinno to być w dao?

obecnie mam tak i chciałabym prosić jeszcze o radę czy nie lepiej nazwać tego BooksDao (bo chodzi o książki) ?

package dao;

import model.Book;
import java.util.List;

public interface BookDao {
	List<Book> getAll() throws Exception;
	boolean add(Book book) throws Exception;
	boolean delete(int idBook) throws Exception;
}

oraz mam też tak z tym filtrowaniem po autorze ksiązki:

package service;

import dao.BookDao;
import model.Book;
import java.util.ArrayList;
import java.util.List;

public class BookService {
	private BookDao bookDao;
	
	public void setBookDao(BookDao bookDao) {
		this.bookDao = bookDao;
	}
	
	public List<Book> getAll() throws Exception{
		return bookDao.getAll();
	}
	
	public List<Book> getWrittenBy(String author) throws Exception {
		List<Book> writtenBy = new ArrayList<Book>();
		List<Book> books = bookDao.getAll();
		for(Book b : books) {
			if(b.getAuthor().equals(author))
				writtenBy.add(b);
		}
		return writtenBy;
	}
}
1

Dao.

0

a czy taki serwis zwracający listę wypożyczonych książek ma sens?

	public List<Book> getLendBooks () throws Exception {
		List<Lend> lends = lendDao.getAll();
		List<Book> books = new ArrayList<Book>();
		for(Lend l : lends) {
			books.add(bookDao.get(l.getIdBook()));
		}
		return books;
	}
1

Eh. Napisze w pseudokodzie bo nie znam javy.

interface IDao<TEntity>
{
  Either<Error, TEntity> Add(TEntity);
  Either<Error, TEntity> Edit(TEntity);
  Nullable<Error> Delete(int);

  Either<Error, TEntity> FindOne(int);
  Either<Error, List<TEntity>> FindByExpression(Expression);
}
class BookService {
  IDao<Book> _bookDao;

  public BookService(IDao<Book> bookDao)
  {
    _bookDao = bookDao;
  }

  Either<Error, PagedList<BorrowedBookViewModel>> FindAllBorrowedBooks()
  {
    return MagicTransform<List<Book>, PagedList<BorrowedBookViewModel>>(_bookDao.FindByExpression(x => x.Status == "Borrowed"));
  }
}

Inaczej nie umiem tego opisac zbytnio.

0

@n0name_l z tego co rozumiem z tego kodu to wymaga żeby książka posiadała pole string "status" określające status (mozna tez zrobic np. bool czyWypozyczona). Czyli rozumiem, że jest to lepsze niż ustalanie wypożyczonych książek na podstawie bazy wypożyczeń (klasa Wypożyczenie ma private int idKsiazki, idCzytelnika;)? Zastanawia mnie po prostu co jak będę robić w bazie mysql tabelę książek przeznaczonych do sprzedaży, tabele książek, które wymagają wymiany okładki itd... takich pól wtedy w klasie książka może mi się zrobić dużo.. :p

1

Nah, chodzilo mi o caloksztalt, zeby DAO umialo wyciagnac sobie N obiektow, w zaleznosci od wyrazenia, a jakie to wyrazenie bedzie to juz zalezy od bazy. Jako, ze nie znam Javy to tak koslawo to ciut wyglada. Calosc zalezy od schematu bazy, ale to z polem jako string to kiepski pomysl, ale malo miejsca zajmuje dlatego go wstawilem. :P

Jak zrobisz tak jak pokazal z tym forem, to jako, ze Dao na kazdym .get(..) zrobi selecta, to kompletnie odpada.

0

aha. dobra to mogę to chyba tak zrobić, że np. dao wypożyczeń zwraca mi id wszystkich wypożyczonych książek a je potem przekazuję do bookDao (te ids), które to zwraca mi książki o tych podanych id.

	public List<Book> getBorrowedBooks () throws Exception {
		List<Integer> borrowedIds = borrowDao.getBorrowedBooksIds();
		List<Book> borrowed = bookDao.get(borrowedIds);
		return borrowed;
	}

A w BookDao pobranie obiektów z tabeli o danych id da się już chyba załatwić w obrębie jednego selecta ala where id IN (ids) czy przez to hibernate. dobra póki co to tylko gdybanie (jestem na etapie plików CSV :p ) ,ale może chociaż nie bd musiała nic zmieniać przy migracji -> mysql.

2
karolinaa napisał(a):

aha. dobra to mogę to chyba tak zrobić, że np. dao wypożyczeń zwraca mi id wszystkich wypożyczonych książek

Jezeli mowa o tych milionach ksiazek, to pobieranie wszystkich identyfikatorow wydaje mi sie zupelnie nieuzasadnione, a przynajmniej nie w sytuacji kiedy wyswietlasz liste wypozyczonych ksiazek uzytkownikowi. Powinnas w takim miejscu uzyc jakiegos stronnicowania i wyswietlic np. 10 elementow na jednej podstronie.

karolinaa napisał(a):

A w BookDao pobranie obiektów z tabeli o danych id da się już chyba załatwić w obrębie jednego selecta ala where id IN (ids) czy przez to hibernate.

Moim zdaniem za bardzo kombinujesz. Jezeli mowa o bazie danych to wyciaganie rekordow z tabeli wypozyczen, tylko po to aby na podstawie tych danych zbudowac zapytanie do wyciagniecia ksiazek mija sie z celem.

Takie rzeczy robi sie za pomoca jednego zapytania (czasem moze to byc zapytanie zlozone z kilku selectow). Do wyciagniecia danych uzyj po prostu zlaczen (join) i tak bedzie najlepiej. Alternatywnie, mozesz takze napisac zapytanie w stylu:

SELECT [lista kolumn] FROM ksiazki k
WHERE k.id in (select id_ksiazki from wypozyczenia)

Oczywiscie warto dodac jeszcze top/limit do tego zapytania o ile jest taka okazja.

1

Filtrowanie po użytkowniku nie powinno być ani w dao, ani w serwisie, tylko w SQL w klauzuli WHERE.

1

Ogolnie to masz racje, ale zauwaz ze autor nie uzywa rdbms tylko baze ma w pliku csv.

0

@__krzysiek85 no dobrze już wiem żeby do tego filtrowania użyć mechanizmów, które oferuje mysql, ale te metody muszę jednak gdzieś umieścić; rozumiem, że przykładowo tak;

pakiet dao
interfejs BookDao
np. z metodami typu public List<Book> getBorrowedBooks ()
klasa BookDaoImpl
z implementacją tej metody i tutaj używam mechanizmów mysql a jak chce to mogę też to zrobić na plikach csv, wyżej w aplikacji nie obchodzi mnie jak to jest zrobione...

PS korzystam z springowego IoC

1

Dokladnie.
I jak uzywasz csv to widze 2 rozwiazania - albo w twojej CSVBookDaoImpl.getBorrowedBooks zamiescic logike ktora filtruje ksiazki, albo napisac sobie taka warstwe nad csv ktora to robi, i ja uzyc w dao. Zdecydowanie latwiej moim zdaniem po prostu zaimplementowac to w warstwie dao bezposrednio, chyba ze to wielki system ktory bedzie mial dostep do csv w wielu modulach...

0

aha ok Dziękuję. Nie to po prostu mała nauka IoC i tego Springowego podziału, chcę to robić prawidłowo :]

1 użytkowników online, w tym zalogowanych: 0, gości: 1