泛型--浅谈在实际中的应用一

来源:互联网 发布:鲍尔夏季联赛数据 编辑:程序博客网 时间:2024/06/10 09:01
package cn.itcast.service.base;import java.io.Serializable;import java.util.LinkedHashMap;import cn.itcast.bean.QueryResult;public interface DAO<T> {/** * 获取记录总数 * @param entityClass 实体类 * @return */public long getCount();/** * 清除一级缓存的数据 */public void clear();/** * 保存实体 * @param entity 实体id */public void save(T entity);/** * 更新实体 * @param entity 实体id */public void update(T entity);/** * 删除实体 * @param entityClass 实体类 * @param entityids 实体id数组 */public void delete(Serializable ... entityids);/** * 获取实体 * @param <T> * @param entityClass 实体类 * @param entityId 实体id * @return */public T find(Serializable entityId);/** * 获取分页数据 * @param <T> * @param entityClass 实体类 * @param firstindex 开始索引 * @param maxresult 需要获取的记录数 * @return */public QueryResult<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams,LinkedHashMap<String, String> orderby);public QueryResult<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams);public QueryResult<T> getScrollData(int firstindex, int maxresult, LinkedHashMap<String, String> orderby);public QueryResult<T> getScrollData(int firstindex, int maxresult);public QueryResult<T> getScrollData();}
package cn.itcast.service.base;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.io.Serializable;import java.lang.reflect.Method;import java.util.LinkedHashMap;import javax.persistence.EmbeddedId;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 cn.itcast.bean.QueryResult;import cn.itcast.utils.GenericsUtils;@SuppressWarnings("unchecked")@Transactionalpublic abstract class DaoSupport<T> implements DAO<T>{protected Class<T> entityClass = GenericsUtils.getSuperClassGenricType(this.getClass());@PersistenceContext protected EntityManager em;public void clear(){em.clear();}public void delete(Serializable ... entityids) {for(Object id : entityids){em.remove(em.getReference(this.entityClass, id));}}@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)public T find(Serializable entityId) {if(entityId==null) throw new RuntimeException(this.entityClass.getName()+ ":传入的实体id不能为空");return em.find(this.entityClass, entityId);}public void save(T entity) {em.persist(entity);}@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)public long getCount() {return (Long)em.createQuery("select count("+ getCountField(this.entityClass) +") from "+ getEntityName(this.entityClass)+ " o").getSingleResult();}public void update(T entity) {em.merge(entity);}@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)public QueryResult<T> getScrollData(int firstindex, int maxresult, LinkedHashMap<String, String> orderby) {return getScrollData(firstindex,maxresult,null,null,orderby);}@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)public QueryResult<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams) {return getScrollData(firstindex,maxresult,wherejpql,queryParams,null);}@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)public QueryResult<T> getScrollData(int firstindex, int maxresult) {return getScrollData(firstindex,maxresult,null,null,null);}@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)public QueryResult<T> getScrollData() {return getScrollData(-1, -1);}@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)public QueryResult<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams,LinkedHashMap<String, String> orderby) {QueryResult qr = new QueryResult<T>();String entityname = getEntityName(this.entityClass);Query query = em.createQuery("select o from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "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("+ getCountField(this.entityClass)+ ") from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where "+ wherejpql));setQueryParams(query, queryParams);qr.setTotalrecord((Long)query.getSingleResult());return qr;}protected static 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语句 * @param orderby * @return */protected static 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();}/** * 获取实体的名称 * @param <E> * @param clazz 实体类 * @return */protected static <E> String getEntityName(Class<E> clazz){String entityname = clazz.getSimpleName();Entity entity = clazz.getAnnotation(Entity.class);if(entity.name()!=null && !"".equals(entity.name())){entityname = entity.name();}return entityname;}/** * 获取统计属性,该方法是为了解决hibernate解析联合主键select count(o) from Xxx o语句BUG而增加,hibernate对此jpql解析后的sql为select count(field1,field2,...),显示使用count()统计多个字段是错误的 * @param <E> * @param clazz * @return */protected static <E> String getCountField(Class<E> clazz){String out = "o";try {PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();for(PropertyDescriptor propertydesc : propertyDescriptors){Method method = propertydesc.getReadMethod();if(method!=null && method.isAnnotationPresent(EmbeddedId.class)){PropertyDescriptor[] ps = Introspector.getBeanInfo(propertydesc.getPropertyType()).getPropertyDescriptors();out = "o."+ propertydesc.getName()+ "." + (!ps[1].getName().equals("class")? ps[1].getName(): ps[0].getName());break;}}} catch (Exception e) {e.printStackTrace();}        return out;}}

package cn.itcast.service.book;import cn.itcast.bean.BuyCart;import cn.itcast.bean.book.DeliverWay;import cn.itcast.bean.book.Order;import cn.itcast.bean.book.PaymentWay;import cn.itcast.service.base.DAO;public interface OrderService extends DAO<Order> {/** * 解锁订单 * @param orderids 订单号 */public void unlock(String... orderids);/** * 加锁订单 * @param orderid 订单号 * @param username 加锁用户 * @return */public Order addLock(String orderid, String username);/** * 把订单转为已收货状态 * @param orderid 订单号 */public void turnReceived(String orderid);/** * 把订单转为已发货状态 * @param orderid 订单号 */public void turnDelivered(String orderid);/** * 把订单转为等待发货状态 * @param orderid 订单号 */public void turnWaitdeliver(String orderid);/** * 财务确认已付款 * @param orderid 订单号 */public void confirmPayment(String orderid);/** * 审核通过订单 * @param orderid 订单号 */public void confirmOrder(String orderid);/** * 取消订单 * @param orderid 订单号 */public void cannelOrder(String orderid);/** * 生成订单 * @param buyCart 购物车 * @param username 用户名 * @return */public Order createOrder(BuyCart buyCart, String username);/** * 更新支付方式 * @param orderid 订单号 * @param paymentWay 支付方式 */public void updatePaymentWay(String orderid, PaymentWay paymentWay);/** * 更新配送方式 * @param orderid 订单号 * @param deliverWay 配送方式 */public void updateDeliverWay(String orderid, DeliverWay deliverWay);/** * 更新配送费 * @param orderid 订单号 * @param deliverFee 配送费 */public void updateDeliverFee(String orderid, float deliverFee);}

package cn.itcast.service.book.impl;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import javax.annotation.Resource;import javax.persistence.Query;import org.springframework.stereotype.Service;import cn.itcast.bean.BuyCart;import cn.itcast.bean.BuyItem;import cn.itcast.bean.book.DeliverWay;import cn.itcast.bean.book.Order;import cn.itcast.bean.book.OrderItem;import cn.itcast.bean.book.OrderState;import cn.itcast.bean.book.PaymentWay;import cn.itcast.bean.product.ProductStyle;import cn.itcast.bean.user.Buyer;import cn.itcast.bean.user.ContactInfo;import cn.itcast.service.base.DaoSupport;import cn.itcast.service.book.GeneratedOrderidService;import cn.itcast.service.book.OrderService;@Servicepublic class OrderServiceBean extends DaoSupport<Order> implements OrderService {@Resource GeneratedOrderidService generatedOrderidService;/*@PostConstruct public void init(){generatedOrderidService.init();}*/public void unlock(String... orderids){if(orderids!=null && orderids.length>0){StringBuilder sb = new StringBuilder();for(int i=0 ; i < orderids.length ; i++){sb.append('?').append(i+2).append(',');}sb.deleteCharAt(sb.length()-1);Query query = em.createQuery("update Order o set o.lockuser=?1 where o.orderid in("+ sb +")");query.setParameter(1, null);for(int i=0 ; i < orderids.length ; i++){query.setParameter(i+2, orderids[i]);}query.executeUpdate();}}public Order addLock(String orderid, String username){Query query = em.createQuery("update Order o set o.lockuser=?1 where o.orderid=?2 and o.lockuser is null and o.state=?3");query.setParameter(1, username);query.setParameter(2, orderid);query.setParameter(3, OrderState.WAITCONFIRM);query.executeUpdate();em.flush();return find(orderid);}public void turnReceived(String orderid){Order order = this.find(orderid);if(OrderState.DELIVERED.equals(order.getState())){order.setState(OrderState.RECEIVED);}}public void turnDelivered(String orderid){Order order = this.find(orderid);if(OrderState.WAITDELIVER.equals(order.getState())){order.setState(OrderState.DELIVERED);}}public void turnWaitdeliver(String orderid){Order order = this.find(orderid);if(OrderState.ADMEASUREPRODUCT.equals(order.getState())){order.setState(OrderState.WAITDELIVER);}}public void confirmPayment(String orderid){Order order = this.find(orderid);order.setPaymentstate(true);if(OrderState.WAITPAYMENT.equals(order.getState())){order.setState(OrderState.ADMEASUREPRODUCT);}else if(OrderState.DELIVERED.equals(order.getState()) && PaymentWay.COD.equals(order.getPaymentWay())){order.setState(OrderState.RECEIVED);}}public void confirmOrder(String orderid){Order order = this.find(orderid);if(OrderState.WAITCONFIRM.equals(order.getState())){if(!PaymentWay.COD.equals(order.getPaymentWay()) && !order.getPaymentstate()){order.setState(OrderState.WAITPAYMENT);}else{order.setState(OrderState.ADMEASUREPRODUCT);}}order.setLockuser(null);}public void cannelOrder(String orderid){Order order = this.find(orderid);if(!OrderState.RECEIVED.equals(order.getState())){order.setState(OrderState.CANCEL);}order.setLockuser(null);}public void updateDeliverFee(String orderid, float deliverFee){Order order = this.find(orderid);order.setDeliverFee(deliverFee);order.setTotalPrice(order.getProductTotalPrice()+ order.getDeliverFee());order.setPayablefee(order.getTotalPrice());}public void updatePaymentWay(String orderid, PaymentWay paymentWay){em.createQuery("update Order o set o.paymentWay=?1 where o.orderid=?2").setParameter(1, paymentWay).setParameter(2, orderid).executeUpdate();}public void updateDeliverWay(String orderid, DeliverWay deliverWay){/* * 下面语句在hibernate中执行出错,这是hibernate的bug导致的,如果用在TopLink上,下面语句能成功执行 * em.createQuery("update OrderDeliverInfo o set o.deliverWay=?1 where o.order.orderid=?2").setParameter(1, deliverWay).setParameter(2, orderid).executeUpdate();*/Order order = this.find(orderid);order.getOrderDeliverInfo().setDeliverWay(deliverWay);}public Order createOrder(BuyCart buyCart, String username){Order order = new Order();Buyer buyer = em.find(Buyer.class, username);order.setBuyer(buyer);order.setDeliverFee(buyCart.getDeliveFee());order.setNote(buyCart.getNote());order.setOrderContactInfo(buyCart.getContactInfo());order.setOrderDeliverInfo(buyCart.getDeliverInfo());order.setState(OrderState.WAITCONFIRM);order.setPaymentWay(buyCart.getPaymentWay());order.setProductTotalPrice(buyCart.getTotalSellPrice());order.setTotalPrice(buyCart.getOrderTotalPrice());order.setPayablefee(buyCart.getOrderTotalPrice());for(BuyItem item : buyCart.getItems()){ProductStyle style = item.getProduct().getStyles().iterator().next();OrderItem oitem = new OrderItem(item.getProduct().getName(), item.getProduct().getId(),item.getProduct().getSellprice(), item.getAmount(), style.getName(), style.getId());order.addOrderItem(oitem);}if(buyer.getContactInfo()==null){buyer.setContactInfo(new ContactInfo());buyer.getContactInfo().setAddress(order.getOrderContactInfo().getAddress());buyer.getContactInfo().setPostalcode(order.getOrderContactInfo().getPostalcode());buyer.getContactInfo().setPhone(order.getOrderContactInfo().getTel());buyer.getContactInfo().setMobile(order.getOrderContactInfo().getMobile());if(buyer.getRealname()==null) buyer.setRealname(order.getOrderContactInfo().getBuyerName());if(buyer.getGender()==null) buyer.setGender(order.getOrderContactInfo().getGender());}order.setOrderid(buildOrderid2(order.getCreateDate()));this.save(order);return order;}/** * 生成订单号,订单号的组成:两位年份两位月份两位日期+(流水号,不够8位前面补零),如:09120200000001 * @return */private String buildOrderid2(Date date) {SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");StringBuilder sb = new StringBuilder(dateFormat.format(date));sb.append(fillZero(8, String.valueOf(generatedOrderidService.buildOrderid())));return sb.toString();}/** * 生成订单号,订单号的组成:两位年份两位月份两位日期+(当天订单总数+1),如果订单总数的长度不够8位,前面补零,如:09120200000001 * @return */private String buildOrderid(Date date) {SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");StringBuilder sb = new StringBuilder(dateFormat.format(date));dateFormat = new SimpleDateFormat("yyyy-MM-dd");try {    Date now = dateFormat.parse(dateFormat.format(date));// 2009-12-02 00:00    Query query = em.createQuery("select count(o) from Order o where o.createDate>=?1");query.setParameter(1, now);long count = (Long)query.getSingleResult();sb.append(fillZero(8, String.valueOf(count+1)));} catch (ParseException e) {throw new RuntimeException("生成订单号失败");}return sb.toString();}/** * 补零 * @param length 补零后的长度 * @param source 需要补零的长符串 * @return */private String fillZero(int length, String source) {//7StringBuilder result = new StringBuilder(source);for(int i=result.length(); i<length ; i++){result.insert(0, '0');}return result.toString();}}

package cn.itcast.utils;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.ArrayList;import java.util.List;/** * 泛型工具类 * @author lihuoming * */public class GenericsUtils {/**       * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>       *       * @param clazz clazz 需要反射的类,该类必须继承范型父类     * @param index 泛型参数所在索引,从0开始.       * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>     */      @SuppressWarnings("unchecked")public static Class getSuperClassGenricType(Class clazz, int index) {            Type genType = clazz.getGenericSuperclass();//得到泛型父类          //如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class           if (!(genType instanceof ParameterizedType)) {            return Object.class;           }          //返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends DaoSupport<Buyer,Contact>就返回Buyer和Contact类型           Type[] params = ((ParameterizedType) genType).getActualTypeArguments();                           if (index >= params.length || index < 0) {          throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));        }              if (!(params[index] instanceof Class)) {            return Object.class;           }           return (Class) params[index];    }/**       * 通过反射,获得指定类的父类的第一个泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>       *       * @param clazz clazz 需要反射的类,该类必须继承泛型父类     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>     */      @SuppressWarnings("unchecked")public static Class getSuperClassGenricType(Class clazz) {    return getSuperClassGenricType(clazz,0);    }/**       * 通过反射,获得方法返回值泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){}     *       * @param Method method 方法     * @param int index 泛型参数所在索引,从0开始.     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>     */     @SuppressWarnings("unchecked")public static Class getMethodGenericReturnType(Method method, int index) {    Type returnType = method.getGenericReturnType();    if(returnType instanceof ParameterizedType){        ParameterizedType type = (ParameterizedType) returnType;        Type[] typeArguments = type.getActualTypeArguments();            if (index >= typeArguments.length || index < 0) {              throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));            }         return (Class)typeArguments[index];    }    return Object.class;    }/**       * 通过反射,获得方法返回值第一个泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){}     *       * @param Method method 方法     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>     */     @SuppressWarnings("unchecked")public static Class getMethodGenericReturnType(Method method) {    return getMethodGenericReturnType(method, 0);    }    /**       * 通过反射,获得方法输入参数第index个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){}     *       * @param Method method 方法     * @param int index 第几个输入参数     * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合     */     @SuppressWarnings("unchecked")public static List<Class> getMethodGenericParameterTypes(Method method, int index) {    List<Class> results = new ArrayList<Class>();    Type[] genericParameterTypes = method.getGenericParameterTypes();    if (index >= genericParameterTypes.length ||index < 0) {             throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));        }     Type genericParameterType = genericParameterTypes[index];    if(genericParameterType instanceof ParameterizedType){         ParameterizedType aType = (ParameterizedType) genericParameterType;         Type[] parameterArgTypes = aType.getActualTypeArguments();         for(Type parameterArgType : parameterArgTypes){             Class parameterArgClass = (Class) parameterArgType;             results.add(parameterArgClass);         }         return results;    }    return results;    }/**       * 通过反射,获得方法输入参数第一个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){}     *       * @param Method method 方法     * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合     */     @SuppressWarnings("unchecked")public static List<Class> getMethodGenericParameterTypes(Method method) {    return getMethodGenericParameterTypes(method, 0);    }/**       * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names;     *       * @param Field field 字段     * @param int index 泛型参数所在索引,从0开始.     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>     */     @SuppressWarnings("unchecked")public static Class getFieldGenericType(Field field, int index) {    Type genericFieldType = field.getGenericType();        if(genericFieldType instanceof ParameterizedType){        ParameterizedType aType = (ParameterizedType) genericFieldType;        Type[] fieldArgTypes = aType.getActualTypeArguments();        if (index >= fieldArgTypes.length || index < 0) {         throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));            }         return (Class)fieldArgTypes[index];    }    return Object.class;    }/**       * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names;     *       * @param Field field 字段     * @param int index 泛型参数所在索引,从0开始.     * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>     */     @SuppressWarnings("unchecked")public static Class getFieldGenericType(Field field) {    return getFieldGenericType(field, 0);    }}


0 0
原创粉丝点击