文档章节

hibernate4+jpa学习日志

z
 zph-alan
发布于 2016/09/22 15:02
字数 1193
阅读 20
收藏 1

不知道从何说起,就从entity说吧, hibernate集成了jpa以后,entity和数据库表直接的配置就简单了,就目前而言我们使用关系数据库都很少建表关系了,一般都是通过代码事物去管理。entity的配置如下:

@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接口,写一些通用的方法,代码如下:

@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接口中可以写一些通用的方法,以便代码的重用

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;
        }
}

调用存储过程

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

@Procedure 中的name对应entiy中的存储过程名称,@Param存储过程中需要传人的参数。

hql的使用

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注解调用就可以了。

service层

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

© 著作权归作者所有

z
粉丝 0
博文 19
码字总数 7838
作品 0
广州
程序员
私信 提问
spring boot框架学习4-spring boot核心(3)

本节主要: 1:spring boot 为我们提供的 starter pom 都有哪些 2:怎么添加xml配置文件 3:日志相关 本文是《凯哥陪你学系列-框架学习之spring boot框架学习》中第四篇 spring boot框架学习...

799879287
2017/10/30
0
0
spring boot框架学习4-spring boot核心(3)

本节主要: 1:spring boot 为我们提供的 starter pom 都有哪些 2:怎么添加xml配置文件 3:日志相关 本文是《凯哥陪你学系列-框架学习之spring boot框架学习》中第四篇 spring boot框架学习...

凯哥java
2017/10/31
0
0
spring boot框架学习4-spring boot核心(3)

本节主要: 1:spring boot 为我们提供的 starter pom 都有哪些 2:怎么添加xml配置文件 3:日志相关 本文是《凯哥陪你学系列-框架学习之spring boot框架学习》中第四篇 spring boot框架学习...

799879287
2017/10/31
0
0
Python模块-logging模块

简介 logging模块用于输出日志信息,可以按照不同日志等级划分反馈给用户,默认以追加形式添加日志信息 一般情况下分的五种等级: 优先级 等级 1 debug() 2 info() 3 warning() 4 error() 5...

ZHAO_JH
2018/04/10
0
0
安卓恶意软件检测:系统调用日志+机器学习算法

  本文内容源自Sanya Chaba等人的学术论文《Malware Detection Approach for Android systems Using System Call Logs》。   基于签名的静态检测技术广泛应用于安卓平台的恶意应用检测。...

嘶吼RoarTalk
2018/01/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

研究下这代码,用到了guava和线程池

import com.google.common.util.concurrent.FutureCallback;import com.google.common.util.concurrent.Futures;import com.google.common.util.concurrent.ListenableFuture;import c......

暗中观察
24分钟前
3
0
《css 揭秘》 之垂直居中的实现

最近看了 Lea Verou 的 《css揭秘》一书,让我对自己的 css学习产生了深深的怀疑。这本书真是太棒了,里面涉及到很多优雅又有趣的效果实现,真的是非常棒。如果你有时间,十分建议你去看看。...

IrisHuang
29分钟前
3
0
java 抽象类(2)

/*需求: 描述一个图形、圆形、 矩形三个类。不管哪种图形都会具备计算面积与周长的行为,但是每种图形计算的方式不一致而已。常量的命名规范:全部字母大写,单词与单词 之间 使用下...

hellation_
32分钟前
2
0
总结:堆和栈

堆 堆比较好理解,即存放对象的地方。这里的对象由GC管理 1、类变量(static修饰的变量):在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命...

浮躁的码农
38分钟前
1
0
JavaScript 新语法详解:Class 的私有属性与私有方法

译者按: 为什么偏要用**#**符号? 原文:JavaScript's new #private class fields 译者:Fundebug 本文采用意译,版权归原作者所有 proposal-class-fields与proposal-private-methods定义了 ...

Fundebug
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部