泛型--浅谈在实际中的应用一
2014-02-26 13:05
555 查看
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") @Transactional public 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; @Service public 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) {//7 StringBuilder 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); } }
相关文章推荐
- 浅谈双绞线在视频监控系统中的实际应用
- 浅谈PHP 闭包特性在实际应用中的问题
- 解决实体类噩梦:联合实体类(Java反射+泛型实际应用)
- .NET 2.0 泛型在实际开发中的一次小应用 转载(出处:http://www.vipcn.com)
- 浅谈Vue网络请求之interceptors实际应用
- .NET2.0泛型在实际开发中的一次小应用
- POJ 3261 浅谈后缀数组HEIGHT数组的实际应用
- 浅谈iOS调试技巧的实际应用(二) UI篇
- 解决实体类噩梦:联合实体类(Java反射+泛型实际应用)
- BZOJ 1458 浅谈网络流建模及实际应用
- 解决实体类噩梦:联合实体类(Java反射+泛型实际应用)
- 泛型解决实际开发应用一例
- 从实际项目中浅谈SSH框架中MVC分层思想的应用与优缺点(一)
- 浅谈iOS调试技巧的实际应用 UI篇
- 泛型(Generic):了解泛型、泛型的应用、?通配符和泛型的限定、泛型方法和类型推断、泛型类、用反射获得实际
- 从实际项目中浅谈SSH框架中MVC分层思想的应用与优缺点(一)
- 从实际项目中浅谈SSH框架中MVC分层思想的应用与优缺点(一)
- 浅谈尼尔森可用性原则的实际应用
- .NET 2.0 泛型在实际开发中的一次小应用
- java 浅谈反射在实际场景中应用