Below is a very easy way in Spring to create DataSources with no XML:
1. DataSource
1.1 Define DataSource Interface
1.2 Implement DataSource Interface
1.3 Test if DataSource is connected
2. Jdbc
2.1 Define Jdbc Configuration
2.2 Define Jdbc Service
2.3 Test Jdbc Service
3. Hibernate
3.1 Define Hibernate Configuration
3.2 Define Hibernate Service
3.3 Test Hibernate Service
4. Jpa
4.1 Define Jpa Configuration
4.2 Define Jpa Service
4.3 Test Jpa Service
5. Spring Data
5.1 Define Spring Data Configuration
5.2 Define Spring Data Service
5.3 Test Spring Data Service
1.1 Define DataSource Interface
package com.example.config; import javax.sql.DataSource; /** * handles configuring the datasource per environment * * @author Thys Michels */ public interface DataSourceConfiguration { DataSource dataSource() throws Exception; }
1.2 Implement DataSource interface
package com.example.config; import org.apache.commons.dbcp.BasicDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import com.mongodb.Mongo; import javax.inject.Inject; import javax.sql.DataSource; import java.sql.Driver; /** * @author Thys Michels */ @PropertySource("classpath:/services.properties") @Configuration @Profile("default") public class LocalDataSourceConfiguration implements DataSourceConfiguration { @Inject private Environment environment; @Bean public DataSource dataSource() throws Exception { BasicDataSource dataSource = new BasicDataSource(); dataSource.setPassword(environment.getProperty("dataSource.password")); dataSource.setUrl(environment.getProperty("dataSource.url")); dataSource.setUsername(environment.getProperty("dataSource.user")); dataSource.setDriverClassName(environment.getPropertyAsClass("dataSource.driverClass", Driver.class).getName()); return dataSource; } }
1.3 Test if DataSource is Connected
package com.example.config; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) throws SQLException { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("default"); applicationContext.scan(LocalDataSourceConfiguration.class.getPackage().getName()); applicationContext.refresh(); DataSource newDataSource =applicationContext.getBean(DataSource.class); System.out.println("DataSource Connected: " + newDataSource.getConnection().isClosed()); newDataSource.getConnection().close(); } }
2. JDBC
2.1 Define jdbc Configuration
package com.example.jdbc; import javax.inject.Inject; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.example.config.DataSourceConfiguration; import com.example.config.LocalDataSourceConfiguration; @Configuration @EnableTransactionManagement @PropertySource("classpath:/services.properties") @Import( { LocalDataSourceConfiguration.class }) public class JdbcConfiguration { @Inject private DataSourceConfiguration dataSourceConfiguration; @Inject private Environment environment; @Bean public JdbcTemplate setupJdbcTemplate() throws Exception { return new JdbcTemplate(dataSourceConfiguration.dataSource()); } @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception { return new DataSourceTransactionManager(dataSource); } }
2.2 Define Jdbc Service
package com.example.jdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.persistence.PersistenceContext; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.example.model.Customer; import com.example.service.CustomerService; @Repository @Transactional @Qualifier("jdbcRepository") public class JdbcCustomerService implements CustomerService{ @Inject private JdbcTemplate jdbcTemplate; @Override public Customer updateCustomer(long id, String fn, String ln) { Customer updateCustomer = new Customer(); updateCustomer.setId(id); updateCustomer.setFirstName(fn); updateCustomer.setLastName(ln); jdbcTemplate.update("", updateCustomer); return null; } @Override public List<Customer> updateCustomers(List<Customer> customersToUpdate) { // TODO Auto-generated method stub return null; } public static final class CustomerMapper implements RowMapper<Customer>{ @Override public Customer mapRow(ResultSet resultSet, int rowNum) throws SQLException { Customer customer = new Customer(); customer.setId(resultSet.getLong("id")); customer.setFirstName(resultSet.getString("first_name")); customer.setLastName(resultSet.getString("last_name")); return customer; } } @Override public Customer getCustomerById(long id) { String sql = "Select * from customer where id = ?"; return jdbcTemplate.queryForObject(sql, new Object[]{id},new CustomerMapper()); } }
2.3 Test Jdbc Service
package com.example.jdbc; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.example.service.CustomerService; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("default"); applicationContext.scan(JdbcConfiguration.class.getPackage().getName()); applicationContext.refresh(); CustomerService customerService = applicationContext.getBean(CustomerService.class); System.out.println(customerService.getCustomerById(new Long(14))); } }
3. Hibernate
3.1 Define Hibernate Configration
package com.example.hibernate; import java.util.Properties; import javax.inject.Inject; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.hibernate.ejb.HibernateEntityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.orm.hibernate3.HibernateTransactionManager; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.example.config.DataSourceConfiguration; import com.example.config.LocalDataSourceConfiguration; @Configuration @PropertySource("classpath:/services.properties") @EnableTransactionManagement @Import( { LocalDataSourceConfiguration.class }) public class HibernateConfiguration { @Inject private DataSourceConfiguration dataSourceConfiguration; @Inject private Environment environment; @Bean public LocalSessionFactoryBean setupSessionFactory() throws Exception { LocalSessionFactoryBean localSessionFactory = new LocalSessionFactoryBean(); localSessionFactory.setDataSource(dataSourceConfiguration.dataSource()); localSessionFactory.setPackagesToScan("com.example.model"); Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("dialect", environment.getProperty("dataSource.dialect")); localSessionFactory.setHibernateProperties(hibernateProperties); return localSessionFactory; } @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception { return new DataSourceTransactionManager(dataSource); } }
3.2 Define Hibernate Service
package com.example.hibernate; import java.util.Collection; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import org.springframework.stereotype.Repository; import com.example.model.Customer; import com.example.service.CustomerService; @Repository @Qualifier("hibernateRepository") public class HibernateCustomerService implements CustomerService{ @Inject SessionFactory sessionFactory; @Override public Customer updateCustomer(long id, String fn, String ln) { Query query = sessionFactory.openSession().createQuery("update Customer set firstName=:fName, lastName=:lName where id=:id").setParameter("fName", fn).setParameter("lName", ln).setParameter("id", id); query.executeUpdate(); return null; } @Override public Customer getCustomerById(long id) { return (Customer) sessionFactory.openSession().createQuery("from Customer where id=?").setLong(0, id).list().get(0); } @Override public Collection<Customer> getAllCustomers() { return (Collection<Customer>)sessionFactory.openSession().createQuery("from Customer").list(); } @Override public Customer createCustomer(String fn, String ln) { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer c = new Customer(); c.setFirstName(fn); c.setLastName(ln); session.save(c); tx.commit(); session.close(); return c; } @Override public void deleteCustomer(long id) { Query query = sessionFactory.openSession().createQuery("delete Customer where id = :id").setParameter("id", id); query.executeUpdate(); } @Override public Customer createCustomer(Customer newCustomer) { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); session.save(newCustomer); tx.commit(); session.close(); return newCustomer; } @Override public int getTotalRecords() { String hql = "Select count(*) from Customer"; Query query = sessionFactory.openSession().createQuery(hql); return ((Long)query.uniqueResult()).intValue(); } }
3.3 Test Hibernate Service
package com.example.hibernate; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.example.service.CustomerService; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("default"); applicationContext.scan(HibernateConfiguration.class.getPackage().getName()); applicationContext.refresh(); CustomerService customerService = applicationContext.getBean(CustomerService.class); System.out.println(customerService.getAllCustomers()); System.out.println(customerService.getCustomerById(new Long(14))); System.out.println(customerService.createCustomer("HibernateFName", "HibernateLName")); customerService.deleteCustomer(new Long(226)); customerService.updateCustomer(new Long(225), "PName", "PLastName"); } }
4. Jpa
4.1 Define Jpa Configuration
package com.example.jpa; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.example.config.DataSourceConfiguration; import com.example.config.LocalDataSourceConfiguration; import com.example.model.Customer; import javax.inject.Inject; import javax.persistence.EntityManagerFactory; @Configuration @PropertySource("classpath:/services.properties") @EnableTransactionManagement @Import( { LocalDataSourceConfiguration.class }) public class JpaConfiguration { @Inject private DataSourceConfiguration dataSourceConfiguration; @Inject private Environment environment; @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception { LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); localContainerEntityManagerFactoryBean.setDataSource(dataSourceConfiguration.dataSource()); localContainerEntityManagerFactoryBean.setPackagesToScan(Customer.class.getPackage().getName()); HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(true); localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter); return localContainerEntityManagerFactoryBean; } @Bean public PlatformTransactionManager transactionManager() throws Exception { EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject(); return new JpaTransactionManager(entityManagerFactory); } }
4.2 Define Jpa Service
package com.example.jpa; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.example.service.CustomerService; import com.example.model.Customer; @Repository @Qualifier("jpaRepository") @Transactional(readOnly = true) public class JpaCustomerService implements CustomerService { @PersistenceContext private EntityManager entityManager; @Transactional(readOnly = true) public Customer getCustomerById(long id) { return this.entityManager.find(Customer.class, id); } public Customer createCustomer(String fn, String ln) { Customer newCustomer = new Customer(); newCustomer.setFirstName(fn); newCustomer.setLastName(ln); this.entityManager.persist(newCustomer); return newCustomer; } @Transactional public Customer updateCustomer(long id, String fn, String ln) { Customer customer = this.getCustomerById(id); customer.setFirstName(fn); customer.setLastName(ln); this.entityManager.merge(customer); return getCustomerById(id); } public Collection<Customer> getAllCustomers() { CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder(); CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class); CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select( criteriaBuilderQuery.from(Customer.class)); return this.entityManager.createQuery(customerCriteriaQuery).getResultList(); } @Transactional public void deleteCustomer(long id) { Customer customerToDelete = this.entityManager.find(Customer.class, id); this.entityManager.remove(customerToDelete); } public Customer createCustomer(Customer newCustomer) { this.entityManager.persist(newCustomer); return newCustomer; } @Transactional public Customer updateCustomer(long id, Customer updateCustomer) { Customer customer = this.getCustomerById(id); customer.setFirstName(updateCustomer.getFirstName()); customer.setLastName(updateCustomer.getLastName()); this.entityManager.merge(customer); return getCustomerById(id); } @Override public List<Customer> bulkCreate(List<Customer> customers) { for (Customer customer : customers){ this.entityManager.persist(customer); } return customers; } @Override public List<Customer> findCustomerByQuery(String query) { return this.entityManager.createNativeQuery(query, Customer.class).getResultList(); } @Transactional public void deleteCustomers(List<Customer> customersToDelete) { for (Customer customer : customersToDelete){ entityManager.remove(customer); } } @Override public List<Customer> getPaginatedCustomer(Integer currentPage, Integer totalPerPage) { CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder(); CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class); CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select( criteriaBuilderQuery.from(Customer.class)); return this.entityManager.createQuery(customerCriteriaQuery).getResultList().subList(currentPage, totalPerPage); } @Transactional public List<Customer> updateCustomers(List<Customer> customersToUpdate) { List<Customer> listOfUpdatedCustomers = new ArrayList<Customer>(); for (Customer customerToUpdate : customersToUpdate){ this.entityManager.merge(customerToUpdate); listOfUpdatedCustomers.add(getCustomerById(customerToUpdate.getId())); } return listOfUpdatedCustomers; } @Override public int getTotalRecords() { CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder(); CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class); CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select( criteriaBuilderQuery.from(Customer.class)); return this.entityManager.createQuery(customerCriteriaQuery).getResultList().size(); } @Override public List<String> getPaginationSequence() { List<String> listOfPages = new ArrayList<String>(); for (int k = 1; k < (int)Math.round((this.getTotalRecords()/10)+0.5)+1; k++){ listOfPages.add(String.valueOf(k)); } return listOfPages; } @Override public void createCustomersFromMap(Map<String, String> mapOfCustomers) { for (Map.Entry<String, String> customer : mapOfCustomers.entrySet()){ Customer newCustomer = new Customer(); newCustomer.setFirstName(customer.getKey()); newCustomer.setLastName(customer.getValue()); createCustomer(newCustomer); } } }
4.3 Test Jpa Service
package com.example.jpa; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.example.service.CustomerService; import com.example.model.Customer; public class Main { public static void main(String args[]) throws Throwable { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("default"); applicationContext.scan(JpaConfiguration.class.getPackage().getName()); applicationContext.refresh(); Log log = LogFactory.getLog(Main.class); CustomerService customerService = applicationContext.getBean(CustomerService.class); Customer customer = customerService.createCustomer("Test", "Jpa"); Customer retrievedCustomer = customerService.getCustomerById(customer.getId()); log.info(String.format("customer.id (%s) == retreivedCustomer.id (%s)? %s", customer.getId(), retrievedCustomer.getId(), customer.getId().equals(retrievedCustomer.getId()))); Customer updatedCustomer = customerService.updateCustomer(customer.getId(), "JPA", "Lover"); log.info(String.format("updated customer's firstName: %s", updatedCustomer.getFirstName())); Collection<Customer> listOfCustomers = customerService.getAllCustomers(); for (Customer c : listOfCustomers){ System.out.println(c); } List<Customer> createDummyCustomers = new ArrayList<Customer>(); for (int k = 0; k < 10; k++){ Customer dummy = new Customer(); dummy.setFirstName("FName"+k); dummy.setLastName("LName"+k); createDummyCustomers.add(dummy); } List<Customer> insertedCustomer = customerService.bulkCreate(createDummyCustomers); for (Customer c : insertedCustomer){ System.out.println(c); } List<Customer> customQueryCustomer = customerService.findCustomerByQuery("Select * from customer"); for (Customer c : customQueryCustomer){ System.out.println(c); } List<Customer> customerPagination = customerService.getPaginatedCustomer(0, 10); for (Customer c : customerPagination){ System.out.println(c); } System.out.println((int)Math.round((customerService.getTotalRecords()/10)+0.5)); System.out.println(customerService.getPaginationSequence()); } }
5. Spring Data
5.1 Configure Spring Data
package com.example.spring_data; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.example.config.DataSourceConfiguration; import com.example.config.LocalDataSourceConfiguration; import com.example.model.Customer; import javax.inject.Inject; import javax.persistence.EntityManagerFactory; @Configuration @EnableJpaRepositories @PropertySource("classpath:/services.properties") @EnableTransactionManagement @Import( { LocalDataSourceConfiguration.class }) public class JpaCustomerConfiguration { @Inject private DataSourceConfiguration dataSourceConfiguration; @Inject private Environment environment; @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception { LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); localContainerEntityManagerFactoryBean.setDataSource(dataSourceConfiguration.dataSource()); localContainerEntityManagerFactoryBean.setPackagesToScan(Customer.class.getPackage().getName()); HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(true); localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter); return localContainerEntityManagerFactoryBean; } @Bean public PlatformTransactionManager transactionManager() throws Exception { EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject(); return new JpaTransactionManager(entityManagerFactory); } }
5.2 Define Spring Data Service
package com.example.spring_data; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.repository.CrudRepository; import com.example.model.Customer; @EnableJpaRepositories public interface CustomerCRUDRepository extends CrudRepository<Customer, Long>, QueryDslPredicateExecutor<Customer>{ }
5.3 Test Spring Data Service
package com.example.spring_data; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.example.model.Customer; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("default"); applicationContext.scan(JpaCustomerConfiguration.class.getPackage().getName()); applicationContext.refresh(); CustomerCRUDRepository cr = applicationContext.getBean(CustomerCRUDRepository.class); System.out.println(cr.count()); //cr.delete(new Long(224)); Customer newCustomer = new Customer("DataJpaFName", "DataJpaLName"); cr.save(newCustomer); System.out.println(cr.findAll()); System.out.println(cr.exists(new Long(224))); System.out.println(cr.findOne(new Long(14))); } }
All code can be found here:
https://github.com/thysmichels/cloudsole-database
Thys, great write-up. Very clear and organized.
Thanks Stephen, appreciate it!:)
Wow, this is really amazing… I added a link to this page to https://springframework.zeef.com/
Nice post. But you should not use main methods to test your stuff. Why not use Junit?