First let me explain the design of this source code.
there are basically
1. domain classes
2. DAO classes
3. service classes
and usually there are model classes, but in this sample application model classes are same as domain classes.
finally i have the main application LibraryApp.java , which has the main method.
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "library-db.xml","library-data-hibernate.xml","library-services.xml"});
/*
Thanks to spring i define database source objects ,schema to object mappings and dependencies between classes in the above XML files and everything else is done automatically.
*/
/*
i have defined a DataSource object in "library-db.xml" , with the connection properties in "db.properties".
*/
/*
i have defined a sessionFactory that uses the previous DataSource object in "library-data-hibernate.xml" . then i have defined a HibernateTemplate bean that uses the sessionFactory bean.
finally the DAO beans are defined ,each to use the HibernateTemplate bean.
*/
/*
then there is "library-services.xml" where i have defined the service beans. there is only one service bookService.
*/
Book book = new Book();
book.setName("test");
book.setIsbn("test isbn");
// just create a Book object and set its properties.
BookRegistrationService bookService =
(BookRegistrationService) context.getBean("bookService");
/* we get a BookRegistrationService object and its DAO property is already injected by Spring automatically.
*/
bookService.registerBook(book);
/*
okay now lets try to understand the flow so far.
the front end captures some info from the user, and in this case the front end is the Main app, which captures the book name and isbn from the user(in this sample app there is no user interaction how ever) and creates a model object that can hold all that data. In this case we captured data of only a book so we do not need to define another model class to get and set book info. instead we can use the domain Book class that can set and get book properties. But if we had to collect additional information than book properties (say buying information of that book) then we have to create a separate model object that can hold all that data. so that model object (lets name it BookRegistration.java) will have setters and getter's for book properties as well as for buying properties as well.
so next step is we pass the model to the service object which contains the business logic.
in this simple case the service object simply requests its DAO object to save the book. But in practical cases there would have been more business logic other than saving to database. Note that the service object has no idea of how to interact with the database.
it does not even know whether its hibernate that is going to save it for it.thus the service object is dependent on the DAO object for all database interactions. how ever this dependency is not hard coded. instead its injected through spring. thus to change to a different DAO object i do not need to modify the service object. which is the way it should happen ,since business layer should not be affected when we change our persistent designs. only thing it should know is that it has a DAO object that case save data for it, irrespective of how.
in the case of book info+buying info, the service object would have two DAOs , one that case save book info and the other that can save buying info.
and the service object would divide the data model object provided between two domain objects. that is set book data on an instance of Book class and buy info on a similar domain class.
then the service object would pass this domain objects to the relevant DAO to save to database.
In this case the DAO that is injected is a hibernate implementation named HibernateBookDao.java.
HibernateBookDao has the addBook method which in return calls saveOrUpdate method of HibernateTemplate with the domain object as a parameter. By this time hibernate has read the hbm.xml files and there we have defined how to save a object of class "com.r4vi.libravi.domain.Book". so when the saveOrUpdate method is called , hibernate simply looks at the mappings we defined and saves to the database accordingly.
*/
List<Book> bookList=bookService.listAllBooks();
Iterator<Book> books=bookList.iterator();
while(books.hasNext()){
Book b=books.next();
System.out.println(b.getName());
System.out.println(b.getIsbn());
}
System.out.println("All books printed");
Book book2=bookService.findBook(1);
System.out.println(book2.getName());
/*
retrieving objects follow a similar flow, but be careful with lazy loading and session closed error. lazy loading is a fantastic feature where you can delay loading of object and data that are not needed immediately. how ever because of that make sure you have not closed the session that contains the data source , when those data will be needed and fetched.
*/
}
some info on hibernate properties file.
I have named it "db.properties" here.
contents are
hibernate.connection.driver_class=org.gjt.mm.mysql.Driver
hibernate.connection.url=jdbc:mysql://localhost/library
hibernate.connection.username=
hibernate.connection.password=
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
then i wrote "library_db-data.xml" which uses those properties
note that i have given the location of "db.properties"
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/db.properties" />
</bean>
and i use the properties i defined in "db.properties" here
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${hibernate.connection.driver_class}" />
<property name="url" value="${hibernate.connection.url}" />
<property name="username" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
</bean>
though you could have used "xx.yy" instead of "hibernate.connection.username" and refer to same "xx.yy"
i recommend that you stick to this naming convention if you use hbm2ddl tool to setup database tables.
then i wrote the "library-data-hibernate.xml" file
important to note stuff are
under property name="mappingResources" i have listed the hibernate mapping files that should be read , and in practical usage i will put them all in some directories and specify all the files in the directories rather than listing each file.
then i have defined the hibernate DAO beans all of them to be injected with an HibernateTemplate instance.
