hibernate4+jpa學習日誌

不知道從何提及,就從entity說吧, hibernate集成了jpa之後,entity和數據庫表直接的配置就簡單了,就目前而言咱們使用關係數據庫都不多建表關係了,通常都是經過代碼事物去管理。entity的配置以下:java

@Entity
@Table(name="test")
@NamedStoredProcedureQueries({
@NamedStoredProcedureQuery(name = "test", procedureName = "sp_tesp_out", parameters = {
				@StoredProcedureParameter(mode = ParameterMode.IN, name = "i_test", type = Long.class),
				@StoredProcedureParameter(mode = ParameterMode.OUT, name = "o_test", type = Float.class) }) })
public class Test{
    private Integer id;
    private String name;
    private int userId;
     @Transient
   private String userName;
    ......
}

@Entity標註爲這個類是一個實體,@Table(name="test")標註爲數據庫對應的表,@Transient註解表示數據庫中沒有此字段,咱們在java代碼又要用到此字段時添加此註解,@NamedStoredProcedureQueries這是調用存儲過程的一個註解,第一個name 在到層經過此名稱調用,procedureName 存儲過程名稱,@StoredProcedureParamete定義存儲過程參數,包括輸入輸出,參數名稱,參數類型。 如今該說dao了,首先我會寫一個base接口,寫一些通用的方法,代碼以下:spring

@NoRepositoryBean
public interface BaseRepository<T,K extends Serializable> extends JpaRepository<T,K>,JpaSpecificationExecutor<T> {
	
	List<T> findAll(String fields,Specification<T> spec);
	Page<T> findAll(String fields,Specification<T> spec, Pageable pageable);
}

BaseRepository接口中能夠寫一些通用的方法,以便代碼的重用sql

public interface TestDao  extends BaseRepository<TestDao  ,Integer>,Test{
	
	@Query("from Test f where f.id=?1")
	public selectOne getById (Integer id);
}

hibernate封裝了不少方法,繼承一下就能夠了,也能夠同@Query註解寫本身想要sql,這樣寫的缺點是每一個參數都必須傳,這樣寫的sql不是用表名而是用entity的類名,若是想按條件查詢這就不行了,沒問題,強大的hibernate早想到這一點了,只要實現這個接口就能夠拼裝複雜的hql了,代碼以下:數據庫

public class TestDaoImpl extends TestDao  {
    
@PersistenceContext
	private EntityManager em;

        public List<Test> query(Test m){
            String hql =" select m from  Test  m where 1 = 1";
             if(m.getName != null && !"".equals(m.getName)){
                hql+=" and m.name like ' "+m.getName+"%'";
            }
            Query query = em.createQuery(hql);
            List<Test> list=query.getResultList();
            return list;
        }
}

調用存儲過程dom

@Procedure(name="test")
	public	void Test( @Param("i_test")String orderCodes);

@Procedure 中的name對應entiy中的存儲過程名稱,@Param存儲過程當中須要傳人的參數。ide

hql的使用ui

public class TestDaoImpl{
    @PersistenceContext
	private EntityManager em;
    public Page<Test> getList(TestVo vo){
        Page<Test> result=null;
        String hql="from Test b where  b.id is null";
        String countHql="select count(*) from Test b where b.id is null";
        String param="";
        param=createParam(vo);
        hql +=param;
        countHql += param;
        Query query = em.createQuery(hql);
	Query countQuery = em.createQuery(countHql);
        long total =Long.parseLong(countQuery.getResultList().get(0).toString());
		int start = pageInfo.getCurPage()*pageInfo.getPageSize();
		if (total>0&&start<total && pageInfo.getPageSize()>0){
			query.setFirstResult(start);
			query.setMaxResults(pageInfo.getPageSize());
		}
		
		
		if (pageInfo.getPageSize()<=0) {
			query.setFirstResult(start);
			pageInfo.setPageSize((int)total);
			query.setMaxResults((int)total);
		}
	List<Test> list=query.getResultList();
	 result = new PageImpl<Test>(list, new PageRequest(pageInfo.getCurPage(),                               pageInfo.getPageSize()), total);
		return result;
    }
}

createParam這是封裝查詢條件的一個方法,Page是spring的一個分頁類(org.springframework.data.domain.Page), EntityManager是jpa封裝的一個接口,具體沒詳細研究,經過@PersistenceContext註解調用就能夠了。hibernate

service層code

public interface SpecialAreaService extends BaseService<SpecialArea>{}

servic層咱們通常會繼承一個公共的方法,以便實現代碼的重用。繼承

@SuppressWarnings("rawtypes")
public interface BaseService<T extends BaseDomain> {
	
	/**
	 * 保存數據,自動生成id<br/>
	 * 不支持複合主鍵生成,使用複合主鍵請覆蓋此方法實現保存
	 * @param t
	 * @return
	 * @throws ServiceException
	 */
	public <E extends BaseDomain<E>> Result<E> save(E t) throws ServiceException;
	public <E extends BaseDomain<E>> Result<Integer> delete(E t) throws ServiceException;
	public <E extends BaseDomain<E>> Result<Integer> update(E t) throws ServiceException;
	public <E extends BaseDomain<E>> Result<E> get(E t) throws ServiceException;
	public Result<List<T>> findAll() throws ServiceException;
	public Result<List<T>> findAll(T t) throws ServiceException; 
	/**
	 * 查詢指定的屬性值
	 * @param fields 屬性名稱,多個以逗號分隔
	 * @param t
	 * @return
	 * @throws ServiceException
	 */
	public Result<List<T>> findAll(String fields,T t) throws ServiceException; 
	public Result<Page<T>> findAll(T t,Pageable pageable) throws ServiceException;
	/**
	 * 分頁查詢指定的屬性值
	 * @param fields 屬性名稱,多個以逗號分隔
	 * @param t
	 * @return
	 * @throws ServiceException
	 */
	public Result<Page<T>> findAll(String fields,T filter,Pageable pageable) throws ServiceException;
	public Result<T> findOne(T t) throws ServiceException;
}```
page是調用spring的一個分頁接口
在: spring-data-commons這個jar中

org.springframework.data.domain.Page

Result是本身寫的一個結果集封裝,這個能夠本身定義。

在這個接口中,可寫自定義方法。
**serviceImpl層**
具體的業務實現層
@Service
@Transactional
public class SpecialAreaServiceImpl extends DefaultService<SpecialArea> implements SpecialAreaService {
    @Resource
	private SpecialAreaDao dao;
	
	@Override
	public BaseRepository getMainDao() {
		return dao;
	}

	@Override
	protected Specification<SpecialArea> buildSpec(final SpecialArea t) {
		return new Specification<SpecialArea>(){

			@Override
			public Predicate toPredicate(Root<SpecialArea> root,
					CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate result = null;
				   if (t != null){
					   if(StringUtils.isNotBlank(t.getProvince())){
						   Path<String> nameExp = root.get("province");
							if(StringUtils.isNotBlank(t.getProvince())){
							result = cb.equal(nameExp,t.getProvince());
							}
					   }
					   if(StringUtils.isNotBlank(t.getCity())){
						   Path<String> nameExp = root.get("city");
							if(StringUtils.isNotBlank(t.getCity())){
							result = cb.equal(nameExp,t.getCity());
							}
					   }
					   if(StringUtils.isNotBlank(t.getRegion())){
						   Path<String> nameExp = root.get("region");
							if(StringUtils.isNotBlank(t.getCity())){
							result = cb.equal(nameExp,t.getRegion());
							}
					   }
                                            if(StringUtils.isNotBlank(t.getRemark())){//備註
							Path<String> nameExp = root.get("remark");
							if(StringUtils.isNotBlank(t.getRemark())){
							result = cb.like(nameExp,"%"+t.getRemark()+"%");
						}}
							
				   }
				return result;
			}
			
		};
	}
}

@Service用於spring的service的依賴注入,只有有這個註解

@Resource private SpecialAreaService service;

在調用的時候才能獲取的到實例。
buildSpec這個方法是用於hibernate的findAll方法的查詢配置。
@Transactional是spring的事物註解配置,這裏還有相關的配置就不細說了。
相關文章
相關標籤/搜索