1. 程式人生 > >BaseDao基於JPA的實現

BaseDao基於JPA的實現

一,說明

二,DAO層的功能

      這裡要簡單提一下MVC模式了,MVC本身不是一種設計模式,只是在程式開發過程中逐漸形成的一種模式,也可以說是一種結構,它的目的就是為了分層解耦。

      spring框架也有自己的MVC開發模式,spring是面向介面程式設計(切面),View層呼叫Controller,Controller呼叫Service,而Service又呼叫資料訪問層,Model即實體類

      DAO介面程式碼:

public interface DAO {

	public void save(Object entity);
	
	public void update(Object entity);
	
	public <T> void delete(Class<T> entityClass,Object entityid);
	
	public <T> void delete(Class<T> entityClass,Object[] entityids);
	
	public <T> T find(Class<T> entityClass,Object entityid);
	
	/**
	 * 獲取分頁資料的封裝
	 * @param <T>
	 * @param entityClass 實體類
	 * @param firstindex 開始索引
	 * @param maxresult 需要獲取的記錄數
	 * @return
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex,int maxresult);
	
	/**
	 * 帶排序功能的分頁實現
	 * @param <T>
	 * @param entityClass
	 * @param firstindex
	 * @param maxresult
	 * @param orderby 按照新增的key的順序排序
	 * @return
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex,int maxresult,LinkedHashMap<String, String> orderby);
	
	/**
	 * 帶排序功能的分頁實現
	 * @param <T>
	 * @param entityClass
	 * @param firstindex
	 * @param maxresult
	 * @param wheresql 新增限制條件
	 * @param orderby
	 * @return
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex,int maxresult,String wheresql,Object[] queryParams,LinkedHashMap<String, String> orderby);
	
}

DAO實現層程式碼:

@Transactional
public abstract class DaoSupport implements DAO {

	@PersistenceContext
	protected EntityManager em;
	
	@Override
	public void save(Object entity) {
		em.persist(entity);
	}

	@Override
	public void update(Object entity) {
		em.merge(entity);
	}

	@Override
	public <T> void delete(Class<T> entityClass, Object entityid) {
		delete(entityClass, new Object[]{entityid});
	}

	@Override
	public <T> void delete(Class<T> entityClass, Object[] entityids) {
		for(Object id : entityids) {
			em.remove(em.getReference(entityClass, id));
		}
	}

	@Override
	public <T> T find(Class<T> entityClass, Object entityid) {
		return em.find(entityClass, entityid);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,
			int firstindex, int maxresult) {
		QueryResult qr = new QueryResult<T>();
		String entityname = getEntityName(entityClass);
		Query query = em.createQuery("select o from "+entityname+" o ");
		query.setFirstResult(firstindex).setMaxResults(maxresult);
		qr.setResultlist(query.getResultList());
		query = em.createQuery("select count(o) from " + entityname + " o ");
		qr.setTotalrecord((Long)query.getSingleResult());
		return qr;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,
			int firstindex, int maxresult,String wheresql,Object[] queryParams, LinkedHashMap<String, String> orderby) {
		QueryResult qr = new QueryResult<T>();
		String entityname = getEntityName(entityClass);
		Query query = em.createQuery("select o from "+entityname+" o " + (wheresql == null ? "" : " where " + wheresql) + buildOrderby(orderby));
		setQueryParams(query,queryParams);
		query.setFirstResult(firstindex).setMaxResults(maxresult);
		List<T> list = query.getResultList();
		qr.setResultlist(list);
		qr.setTotalrecord(list.size());
		return qr;
	}
	
	protected void setQueryParams(Query query,Object[] queryParams) {
		if(null != queryParams && 0 < queryParams.length) {
			for (int i = 0; i < queryParams.length; i++) {
				query.setParameter(i+1, queryParams[i]);
			}
		}
	}
	
	@Override
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,
			int firstindex, int maxresult, LinkedHashMap<String, String> orderby) {
		return getScrollData(entityClass, firstindex, maxresult, null,null, orderby);
	}
	
	protected String buildOrderby(LinkedHashMap<String, String> orderby) {
		StringBuffer sb = new StringBuffer();
		if(null != orderby && 0 != orderby.size()) {
			sb.append(" order by ");
			for (String key : orderby.keySet()) {
				sb.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
			}
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}
	
	/**
	 * 獲取實體的名稱
	 * @param <T>
	 * @param entityClass 實體類
	 * @return
	 */
	protected <T> String getEntityName(Class<T> entityClass) {
		String entityname = entityClass.getSimpleName();
		Entity entity = entityClass.getAnnotation(Entity.class);
		if(entity.name() != null && !"".equals(entity.name())) {
			entityname = entity.name();
		}
		return entityname;
	}

}


三,新增Service層

public interface JMusicService extends DAO {

}

Service實現

@Service(value="jMusicServiceBean")
@Transactional
public class JMusicServiceBean extends DaoSupport implements JMusicService {

	
	
}

可以看到,dao層利用泛型的方式來實現,使Service層程式碼非常簡單,但是,這裡沒有利用依賴注入的方式將dao層和Service層分離,後續中有待處理

四,測試dao層的實現

public class SpringJpaTest {

	private static ApplicationContext cxt;
	private static JMusicService jmService;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		//WebRoot/WEB-INF/
		cxt=  new ClassPathXmlApplicationContext("spring-mvc.xml");
		jmService = (JMusicService) cxt.getBean("jMusicServiceBean");
	}
	
	@Test
	public void testsave() {
		
		for(int i = 0;i < 15;i++) {
			JMusic jm = new JMusic();
			jm.setAlbum("BigBun");
			jm.setDistributeDate(Timestamp.valueOf(DateUtil.getNowDate()));
			String uuid = UUID.randomUUID().toString().replaceAll("-", "");
			jm.setMusicname(uuid.substring(3, 10));
			jm.setMusicurl("http://www.baidu.com/music/20150308/"+uuid.substring(3, 10)+".mp3");
			jm.setSinger("Johns Brooks");
			jmService.save(jm);
		}
	}
	
	@Test
	public void testfind() throws UnsupportedEncodingException {
		JMusic jm = jmService.find(JMusic.class, 1000);
		if(null != jm)
			System.out.println(jm.getSinger());
	}
	
	
	@Test
	public void testdelete () {
		jmService.delete(JMusic.class, 1);
		jmService.delete(JMusic.class, 2);
	}
	/***
	 * 測試分頁
	 */
	@Test
	public void testPages() {
		QueryResult<JMusic> qr = jmService.getScrollData(JMusic.class, 11, 10);
		for(JMusic jm : qr.getResultlist()) {
			System.out.println(jm.getId());
		}
	}
	
	/***
	 * 測試帶有排序的分頁
	 */
	@Test
	public void testOrderPages() {
		LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>();
		orderby.put("musicname", "desc");
		orderby.put("id", "asc");
		//JPA佔位符
		QueryResult<JMusic> qr = jmService.getScrollData(JMusic.class, 0, 100," singer=?1",new Object[]{"Jay"},orderby);
		for(JMusic jm : qr.getResultlist()) {
			System.out.println(jm.getMusicname() + "-" + jm.getId());
		}
	}

}

這裡可以測試一下,增刪改查的各個功能,還有各種分頁的效果的測試