不知道从何提及,就从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的事物注解配置,这里还有相关的配置就不细说了。