jpa+spring对实体的crud和实现分页功能的简单实用的封装

这篇博客介绍了如何利用JPA和Spring进行实体的CRUD操作,并封装了一个分页类QueryResult,实现了DAO接口,包括查询、删除、更新等方法,同时提供了分页查询的多种实现。示例中还包括了具体实体类ProductType的业务接口及其实现类,以及相关的配置文件和实体类设计。
摘要由CSDN通过智能技术生成

 

分页类的封装:

==============================================================================================

package com.itcast.bean;

import java.util.List;

/**
 * 对分页做一个单独的类来处理
 * 显而易见是结果集与总数的封装
 * @author Administrator
 *
 * @param <T>
 */
public class QueryResult<T> {

    private List<T> resultlist;
   
    private long totalrecord;

    public List<T> getResultlist() {
        return resultlist;
    }

    public void setResultlist(List<T> resultlist) {
        this.resultlist = resultlist;
    }

    public long getTotalrecord() {
        return totalrecord;
    }

    public void setTotalrecord(long totalrecord) {
        this.totalrecord = totalrecord;
    }
   
}

 

DAO的设计

==============================================================================================

package com.itcast.service.base;

import java.util.LinkedHashMap;

import com.itcast.bean.QueryResult;

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);
   
    //获取分页数据
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult
            ,String wherejpql,Object[] queryParams,LinkedHashMap<String, String> orderby);
   
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult
            ,String wherejpql,Object[] queryParams);
   
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult
            ,LinkedHashMap<String, String> orderby);
   
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult);
   
    public <T> QueryResult<T> getScrollData(Class<T> entityClass);
   
}

 

 

抽象类的实现

==============================================================================================

package com.itcast.service.base;

import java.util.LinkedHashMap;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.itcast.bean.QueryResult;

@Transactional
public abstract class DaoSupport implements DAO {

    @PersistenceContext protected EntityManager em;
   
    public <T> void delete(Class<T> entityClass,Object entityid) {
        //em.remove(em.getReference(entityClass, entityid));
        delete(entityClass,new Object[]{entityid});
    }

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

    @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
    public <T> T find(Class<T> entityClass, Object entityId) {
        return em.find(entityClass, entityId);
    }

    public void save(Object entity) {
        em.persist(entity);
    }

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

    @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,
            int firstindex, int maxresult, LinkedHashMap<String, String> orderby) {
        return getScrollData(entityClass, firstindex, maxresult,null,null, orderby);
    }

    @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,
            int firstindex, int maxresult, String wherejpql,Object[] queryParams) {
        return getScrollData(entityClass, firstindex, maxresult, wherejpql, queryParams,null);
    }

    @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult) {
        return getScrollData(entityClass, firstindex, maxresult,null,null,null);
    }

    @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
    public <T> QueryResult<T> getScrollData(Class<T> entityClass) {
        return getScrollData(entityClass,-1,-1);
    }

   
    @SuppressWarnings("unchecked")
    @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
    public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult
            ,String wherejpql,Object[] queryParams,LinkedHashMap<String, String> orderby) {
        QueryResult qr = new QueryResult<T>();
        String entityname = getEntityName(entityClass);
        Query query = em.createQuery("select o from "+ entityname+ " o " +(wherejpql==null?" ":" where "+wherejpql) + buildOrderby(orderby));
        setQueryParams(query, queryParams);
        //实现分页设置开始索引和最大数据量
        if(firstindex != -1 && maxresult != -1){
            query.setFirstResult(firstindex).setMaxResults(maxresult);
        }
        qr.setResultlist(query.getResultList());
        query = em.createQuery("select count(o) from "+ entityname+ " o "+(wherejpql==null?" ":" where "+wherejpql));
        setQueryParams(query, queryParams);
        qr.setTotalrecord((Long)query.getSingleResult());
        System.out.println(qr);
        return qr;
    }
   
   
    protected void setQueryParams(Query query,Object[] queryParams){
        if(queryParams != null && queryParams.length>0){
            for(int i = 0; i<queryParams.length; ++i){
                query.setParameter(i+1, queryParams[i]);
            }
        }
    }

    //组装order by语句
   
    protected String buildOrderby(LinkedHashMap<String,String> orderby){
        StringBuffer orderbyql = new StringBuffer("");
        if(orderby != null && orderby.size()>0){
            orderbyql.append(" order by ");
            for(String key : orderby.keySet()){
                orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
            }
            orderbyql.deleteCharAt(orderbyql.length()-1);
        }
        return orderbyql.toString();
    }
   
    //获取实体的名称
    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;
    }
}

 

 

具体实体类的业务接口

==============================================================================================

package com.itcast.service.product;

import com.itcast.bean.product.ProductType;
import com.itcast.service.base.DAO;

public interface ProductTypeService extends DAO{

}

 

 

具体实体类接口的实现类

==============================================================================================

package com.itcast.service.product.impl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.itcast.bean.product.ProductType;
import com.itcast.service.base.DaoSupport;
import com.itcast.service.product.ProductTypeService;

@Service
@Transactional
public class ProductTypeServiceBeen extends DaoSupport implements ProductTypeService {

    /**
     * 重载DaoSupport的public <T> void delete(Class<T> entityClass, Object[] entityids)方法
     * 使其对ProductType实体类只是将他的visible设置为false而不像其他的实体呗删除掉
     */
    @Override
    public <T> void delete(Class<T> entityClass, Object[] entityids) {
        if(entityids!=null && entityids.length>0){
            StringBuffer jpql = new StringBuffer();
            for(int i=0;i<entityids.length;++i){
                jpql.append("?").append(i+2).append(",");
            }
            jpql.deleteCharAt(jpql.length()-1);
            Query query = em.createQuery("update ProductType o set o.visible=?1 where o.typeid in("+jpql.toString()+")")
                             .setParameter(1, false);
            for(int i=0;i<entityids.length;++i){
                query.setParameter(i+2, entityids[i]);
            }
            query.executeUpdate();
        }
    }

   
}

 

 

测试类

==============================================================================================

package junit.test;


import java.util.LinkedHashMap;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.itcast.bean.QueryResult;
import com.itcast.bean.product.ProductType;
import com.itcast.service.product.ProductTypeService;


public class ProductTest {
    private static ApplicationContext cxt;
    private static ProductTypeService productService;
   
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        try {
            cxt = new ClassPathXmlApplicationContext("beans.xml");
            productService = (ProductTypeService) cxt.getBean("productTypeServiceBeen");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

   
    @Test public void testSave(){
        for(int i = 0;i<20;++i){
            ProductType type = new ProductType();
            type.setName(i+"瑜伽用品");
            type.setNote("好产品");
            productService.save(type);
        }
    }
   
    @Test public void testFind(){
        ProductType type = productService.find(ProductType.class, 1);
        System.out.println(type);
        Assert.assertNotNull("找不到id为1的记录",type);
    }
   
    @Test public void testUpdate(){
        ProductType type = productService.find(ProductType.class, 1);
        type.setName("足球");
        type.setNote("好足球");
        productService.update(type);
    }
   
    @Test public void testDelete(){
        productService.delete(ProductType.class, 2);
    }
   
    @Test public void testgetScrollData(){
        LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>();
        orderby.put("typeid", "asc");
        QueryResult<ProductType> qr = productService.getScrollData(ProductType.class);
        for(ProductType t: qr.getResultlist()){
            System.out.println(t.getName());
        }
    }
}

 

 

实体类的设计

==============================================================================================

package com.itcast.bean.product;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.apache.tools.ant.util.facade.FacadeTaskHelper;

@Entity
public class ProductType implements Serializable{

    private static final long serialVersionUID = 1L;

    //类别id
    private Integer typeid;

    //类别名称
    private String name;
   
    //备注,用于Google搜索页面描述
    private String note;
   
    //是否可见
    private Boolean visible = true;
   
    //子类别
    private Set<ProductType> childtypes = new HashSet<ProductType>();
   
    //所属父类
    private ProductType parent;
   
    @OneToMany(cascade={CascadeType.REFRESH,CascadeType.REMOVE},mappedBy="parent")
    public Set<ProductType> getChildtypes() {
        return childtypes;
    }

    public void setChildtypes(Set<ProductType> childtypes) {
        this.childtypes = childtypes;
    }

    @ManyToOne(cascade=CascadeType.REFRESH)
    @JoinColumn(name="parentid")
    public ProductType getParent() {
        return parent;
    }

    public void setParent(ProductType parent) {
        this.parent = parent;
    }

    @Column(length=36,nullable=false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(length=100,nullable=true)
    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    @Column(nullable=false)
    public Boolean getVisible() {
        return visible;
    }

    public void setVisible(Boolean visible) {
        this.visible = visible;
    }

    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    public Integer getTypeid() {
        return typeid;
    }

    public void setTypeid(Integer typeid) {
        this.typeid = typeid;
    }
   
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((typeid == null) ? 0 : typeid.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ProductType other = (ProductType) obj;
        if (typeid == null) {
            if (other.typeid != null)
                return false;
        } else if (!typeid.equals(other.typeid))
            return false;
        return true;
    }

}

 

 

配置文件:

==============================================================================================

 

jpa的配置:META-INF/persistence.xml

 

<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<!-- file:///D:/hibernate/hibernate-entitymanager-3.3.2.CR1/resources/org/hibernate/ejb/persistence_1_0.xsd -->
  <persistence-unit name="itcast" transaction-type="RESOURCE_LOCAL" >
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
         <property name="hibernate.max_fetch_depth" value="3"/>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
         <property name="hibernate.jdbc.fetch_size" value="18"/>
         <property name="hibernate.jdbc.batch_size" value="10"/>
         <property name="hibernate.show_sql" value="false"/>
         <property name="hibernate.format_sql" value="false"/>
      </properties>
  </persistence-unit>
</persistence>

 

Spring 的配置:beans.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
        <!-- 使用注解的最重要语句 -->
        <context:annotation-config/>
        <context:component-scan base-package="com.itcast"/>
        <context:property-placeholder location="classpath:jdbc.properties"/>
       
 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
     <property name="driverClassName" value="${driverClassName}"/>
     <property name="url" value="${url}"/>
     <property name="username" value="${username}"/>
     <property name="password" value="${password}"/>
      <!-- 连接池启动时的初始值 -->
   <property name="initialSize" value="${initialSize}"/>
   <!-- 连接池的最大值 -->
   <property name="maxActive" value="${maxActive}"/>
   <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
   <property name="maxIdle" value="${maxIdle}"/>
   <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请一些连接,以避免洪峰来时再申请而造成的性能开销 -->
   <property name="minIdle" value="${minIdle}"/>
   </bean>
 
   <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
         <property name="dataSource" ref="dataSource"/>
         <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
         <property name="loadTimeWeaver">
             <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"></bean>
         </property>
   </bean>
 
 
   <bean id = "transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory"></property>
   </bean>
  <!-- 采用@Transactional注解方式声明处理事务 -->
  <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

==============================================================================================

 

jdbc.properties的配置:

driverClassName=org.gjt.mm.mysql.Driver
url=jdbc/:mysql/://localhost/:3306/ssh?useUnicode/=true&amp;characterEncoding/=UTF-8
username=root
password=123
initialSize=1
maxActive=100
maxIdle=8
minIdle=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值