Java tutorial
/** * Copyright © 2012-2013 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); */ package com.itrus.ca.common.persistence; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.sql.DataSource; import org.apache.log4j.Logger; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.QueryWrapperFilter; import org.apache.lucene.search.Sort; import org.apache.lucene.search.highlight.Formatter; import org.apache.lucene.search.highlight.Highlighter; import org.apache.lucene.search.highlight.InvalidTokenOffsetsException; import org.apache.lucene.search.highlight.QueryScorer; import org.apache.lucene.search.highlight.SimpleFragmenter; import org.apache.lucene.search.highlight.SimpleHTMLFormatter; import org.apache.lucene.util.Version; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.internal.CriteriaImpl; import org.hibernate.jdbc.ReturningWork; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.Search; import org.hibernate.search.filter.impl.CachingWrapperFilter; import org.hibernate.search.query.DatabaseRetrievalMethod; import org.hibernate.search.query.ObjectLookupMethod; import org.hibernate.transform.ResultTransformer; import org.hibernate.transform.Transformers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.wltea.analyzer.lucene.IKAnalyzer; import com.alibaba.druid.pool.DruidDataSource; import com.itrus.ca.common.annotation.VOAnnotation; import com.itrus.ca.common.utils.ReflectHelper; import com.itrus.ca.common.utils.Reflections; import com.itrus.ca.common.utils.StringHelper; import com.itrus.ca.common.utils.StringUtils; /** * DAO? * * @author ThinkGem * @version 2013-05-15 * @param <T> */ public class BaseDaoImpl<T> implements BaseDao<T> { /** * ?? */ @PersistenceContext private EntityManager entityManager; @Autowired private DataSource dataSource; /** * () */ private Class<?> entityClass; /** * ?? */ public BaseDaoImpl() { entityClass = Reflections.getClassGenricType(getClass()); } /** * ?? */ public EntityManager getEntityManager() { return entityManager; } /** * ? Session */ public Session getSession() { return (Session) getEntityManager().getDelegate(); } /** * ?? */ public void flush() { getSession().flush(); } /** * ? */ public void clear() { getSession().clear(); } // -------------- QL Query -------------- /** * QL * * @param page * @param qlString * @param parameter * @return */ @SuppressWarnings("unchecked") public <E> Page<E> find(Page<E> page, String qlString, Object... parameter) { // get count if (!page.isDisabled() && !page.isNotCount()) { String countQlString = "select count(*) " + removeSelect(removeOrders(qlString)); // page.setCount(Long.valueOf(createQuery(countQlString, // parameter).uniqueResult().toString())); Query query = createQuery(countQlString, parameter); List<Object> list = query.list(); if (list.size() > 0) { page.setCount(Long.valueOf(list.get(0).toString())); } else { page.setCount(list.size()); } if (page.getCount() < 1) { return page; } } // order by String ql = qlString; if (StringUtils.isNotBlank(page.getOrderBy())) { ql += " order by " + page.getOrderBy(); } Query query = createQuery(ql, parameter); // set page if (!page.isDisabled()) { query.setFirstResult(page.getFirstResult()); query.setMaxResults(page.getMaxResults()); } page.setList(query.list()); return page; } /** * QL * * @param qlString * @param parameter * @return */ @SuppressWarnings("unchecked") public <E> List<E> find(String qlString, Object... parameter) { Query query = createQuery(qlString, parameter); return query.list(); } /** * QL * * @param qlString * @param parameter * @return */ @Transactional(readOnly = false) public int update(String qlString, Object... parameter) { return createQuery(qlString, parameter).executeUpdate(); } /** * QL * * @param qlString * @param parameter * @return */ public Query createQuery(String qlString, Object... parameter) { Query query = getSession().createQuery(qlString); setParameter(query, parameter); return query; } // -------------- SQL Query -------------- /** * SQL * * @param page * @param sqlString * @param parameter * @return */ public <E> Page<E> findBySql(Page<E> page, String sqlString, Object... parameter) { return findBySql(page, sqlString, null, parameter); } public void exeSql(String sql) { Logger log = Logger.getLogger("ex"); Connection conn = null; PreparedStatement ps = null; try { conn = dataSource.getConnection(); conn.setAutoCommit(false); ps = conn.prepareStatement(sql); ps.execute(); conn.commit(); } catch (Exception e) { e.printStackTrace(); log.error(StringHelper.getStackInfo(e)); } finally { try { if (ps != null) ps.close(); if (conn != null) conn.close(); } catch (SQLException e1) { e1.printStackTrace(); log.error(StringHelper.getStackInfo(e1)); } } } // @Transactional(readOnly = false) // public void exeSql(final String sql) { // try { // getSession().doReturningWork(new ReturningWork() { // public SQLQuery execute(Connection connection) // throws SQLException { // // Session session = getSession(); // try { // org.hibernate.Transaction tx = session.getTransaction(); // tx.begin(); // // session.getTransaction(); // session.createSQLQuery(sql).executeUpdate(); // tx.commit(); // } catch (Exception e) { // e.printStackTrace(); // Logger log = Logger.getLogger("ex"); // log.error(StringHelper.getStackInfo(e)); // } // return null; // } // }); // } catch (Exception e) { // // e.printStackTrace(); // Logger log = Logger.getLogger("ex"); // log.error(StringHelper.getStackInfo(e)); // } // } /** * SQL * * @param page * @param sqlString * @param resultClass * @param parameter * @return */ @SuppressWarnings("unchecked") public <E> Page<E> findBySql(Page<E> page, String sqlString, Class<?> resultClass, Object... parameter) { // get count if (!page.isDisabled() && !page.isNotCount()) { String countSqlString = "select count(*) " + removeSelect(removeOrders(sqlString)); // page.setCount(Long.valueOf(createSqlQuery(countSqlString, // parameter).uniqueResult().toString())); Query query = createSqlQuery(countSqlString, parameter); List<Object> list = query.list(); if (list.size() > 0) { page.setCount(Long.valueOf(list.get(0).toString())); } else { page.setCount(list.size()); } if (page.getCount() < 1) { return page; } } // order by String sql = sqlString; if (StringUtils.isNotBlank(page.getOrderBy())) { sql += " order by " + page.getOrderBy(); } SQLQuery query = createSqlQuery(sql, parameter); // set page if (!page.isDisabled()) { query.setFirstResult(page.getFirstResult()); query.setMaxResults(page.getMaxResults()); } setResultTransformer(query, resultClass); page.setList(query.list()); return page; } /** * SQL * * @param sqlString * @param parameter * @return */ public <E> List<E> findBySql(String sqlString, Object... parameter) { return findBySql(sqlString, null, parameter); } /** * SQL * * @param sqlString * @param resultClass * @param parameter * @return */ @SuppressWarnings("unchecked") public <E> List<E> findBySql(String sqlString, Class<?> resultClass, Object... parameter) { SQLQuery query = createSqlQuery(sqlString, parameter); setResultTransformer(query, resultClass); return query.list(); } /** * SQL * * @param sqlString * @param parameter * @return */ @Transactional(readOnly = false) public int updateBySql(String sqlString, Object... parameter) { return createSqlQuery(sqlString, parameter).executeUpdate(); } /** * SQL * * @param sqlString * @param parameter * @return */ public SQLQuery createSqlQuery(String sqlString, Object... parameter) { SQLQuery query = getSession().createSQLQuery(sqlString); setParameter(query, parameter); return query; } // -------------- Query Tools -------------- /** * * * @param query * @param resultClass */ private void setResultTransformer(SQLQuery query, Class<?> resultClass) { if (resultClass != null) { if (resultClass == Map.class) { query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); } else if (resultClass == List.class) { query.setResultTransformer(Transformers.TO_LIST); } else { query.setResultTransformer(Transformers.aliasToBean(resultClass)); // query.addEntity(resultClass); } } } /** * ? * * @param query * @param parameter */ private void setParameter(Query query, Object... parameter) { if (parameter != null) { for (int i = 0; i < parameter.length; i++) { query.setParameter(i, parameter[i]); } } } /** * qlStringselect?? * * @param hql * @return */ private String removeSelect(String qlString) { int beginPos = qlString.toLowerCase().indexOf("from"); return qlString.substring(beginPos); } /** * hqlorderBy?? * * @param hql * @return */ private String removeOrders(String qlString) { Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(qlString); StringBuffer sb = new StringBuffer(); while (m.find()) { m.appendReplacement(sb, ""); } m.appendTail(sb); return sb.toString(); } // -------------- Criteria -------------- /** * * * @param page * @return */ public Page<T> find(Page<T> page) { return find(page, createDetachedCriteria()); } /** * * * @param page * @param detachedCriteria * @param resultTransformer * @return */ public Page<T> find(Page<T> page, DetachedCriteria detachedCriteria) { return find(page, detachedCriteria, Criteria.DISTINCT_ROOT_ENTITY); } @SuppressWarnings("unchecked") public List<T> manyFind(DetachedCriteria detachedCriteria, ResultTransformer resultTransformer, int size) { Criteria criteria = detachedCriteria.getExecutableCriteria(getSession()); criteria.setResultTransformer(resultTransformer); criteria.setFirstResult(0); criteria.setMaxResults(size); return criteria.list(); } /** * * * @param page * @param detachedCriteria * @param resultTransformer * @return */ @SuppressWarnings("unchecked") public Page<T> find(Page<T> page, DetachedCriteria detachedCriteria, ResultTransformer resultTransformer) { // get count if (!page.isDisabled() && !page.isNotCount()) { page.setCount(count(detachedCriteria)); if (page.getCount() < 1) { return page; } } Criteria criteria = detachedCriteria.getExecutableCriteria(getSession()); criteria.setResultTransformer(resultTransformer); // set page if (!page.isDisabled()) { criteria.setFirstResult(page.getFirstResult()); criteria.setMaxResults(page.getMaxResults()); } // order by if (StringUtils.isNotBlank(page.getOrderBy())) { for (String order : StringUtils.split(page.getOrderBy(), ",")) { String[] o = StringUtils.split(order, " "); if (o.length == 1) { criteria.addOrder(Order.asc(o[0])); } else if (o.length == 2) { if ("DESC".equals(o[1].toUpperCase())) { criteria.addOrder(Order.desc(o[0])); } else { criteria.addOrder(Order.asc(o[0])); } } } } page.setList(criteria.list()); return page; } /** * * * @param detachedCriteria * @return */ public List<T> find(DetachedCriteria detachedCriteria) { return find(detachedCriteria, Criteria.DISTINCT_ROOT_ENTITY); } /** * * * @param detachedCriteria * @param resultTransformer * @return */ @SuppressWarnings("unchecked") public List<T> find(DetachedCriteria detachedCriteria, ResultTransformer resultTransformer) { Criteria criteria = detachedCriteria.getExecutableCriteria(getSession()); criteria.setResultTransformer(resultTransformer); return criteria.list(); } /** * * * @param detachedCriteria * @return */ @SuppressWarnings("rawtypes") public long count(DetachedCriteria detachedCriteria) { Criteria criteria = detachedCriteria.getExecutableCriteria(getSession()); long totalCount = 0; try { // Get orders Field field = CriteriaImpl.class.getDeclaredField("orderEntries"); field.setAccessible(true); List orderEntrys = (List) field.get(criteria); // Remove orders field.set(criteria, new ArrayList()); // Get count criteria.setProjection(Projections.rowCount()); totalCount = Long.valueOf(criteria.uniqueResult().toString()); // Clean count criteria.setProjection(null); // Restore orders field.set(criteria, orderEntrys); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return totalCount; } /** * ? * * @param criterions * Restrictions.eq("name", value); * @return */ public DetachedCriteria createDetachedCriteria(Criterion... criterions) { DetachedCriteria dc = DetachedCriteria.forClass(entityClass); for (Criterion c : criterions) { dc.add(c); } return dc; } // -------------- Hibernate search -------------- /** * ?Session */ public FullTextSession getFullTextSession() { return Search.getFullTextSession(getSession()); } /** * */ public void createIndex() { try { getFullTextSession().createIndexer(entityClass).startAndWait(); } catch (InterruptedException e) { e.printStackTrace(); } } /** * * * @param page * * @param query * * @param queryFilter * * @param sort * ? * @return */ @SuppressWarnings("unchecked") public Page<T> search(Page<T> page, BooleanQuery query, BooleanQuery queryFilter, Sort sort) { // FullTextQuery fullTextQuery = getFullTextSession().createFullTextQuery(query, entityClass); // if (queryFilter != null) { fullTextQuery.setFilter(new CachingWrapperFilter(new QueryWrapperFilter(queryFilter))); } // ? if (sort != null) { fullTextQuery.setSort(sort); } // page.setCount(fullTextQuery.getResultSize()); fullTextQuery.setFirstResult(page.getFirstResult()); fullTextQuery.setMaxResults(page.getMaxResults()); // ?? fullTextQuery.initializeObjectsWith(ObjectLookupMethod.SECOND_LEVEL_CACHE, DatabaseRetrievalMethod.QUERY); // page.setList(fullTextQuery.list()); return page; } /** * ? */ public BooleanQuery getFullTextQuery(BooleanClause... booleanClauses) { BooleanQuery booleanQuery = new BooleanQuery(); for (BooleanClause booleanClause : booleanClauses) { booleanQuery.add(booleanClause); } return booleanQuery; } /** * ? * * @param q * * @param fields * * @return */ public BooleanQuery getFullTextQuery(String q, String... fields) { Analyzer analyzer = new IKAnalyzer(); BooleanQuery query = new BooleanQuery(); try { if (StringUtils.isNotBlank(q)) { for (String field : fields) { QueryParser parser = new QueryParser(Version.LUCENE_36, field, analyzer); query.add(parser.parse(q), Occur.SHOULD); } } } catch (ParseException e) { e.printStackTrace(); } return query; } /** * * * @param query * * @param list * * @param subLength * ? * @param fields * ?? */ public List<T> keywordsHighlight(BooleanQuery query, List<T> list, int subLength, String... fields) { Analyzer analyzer = new IKAnalyzer(); Formatter formatter = new SimpleHTMLFormatter("<span class=\"highlight\">", "</span>"); Highlighter highlighter = new Highlighter(formatter, new QueryScorer(query)); highlighter.setTextFragmenter(new SimpleFragmenter(subLength)); for (T entity : list) { try { for (String field : fields) { String text = StringUtils.replaceHtml((String) Reflections.invokeGetter(entity, field)); String description = highlighter.getBestFragment(analyzer, field, text); if (description != null) { Reflections.invokeSetter(entity, fields[0], description); break; } Reflections.invokeSetter(entity, fields[0], StringUtils.abbr(text, subLength * 2)); } } catch (IOException e) { e.printStackTrace(); } catch (InvalidTokenOffsetsException e) { e.printStackTrace(); } } return list; } // ------------------- add /** * * ???<br> * hibernateBUG<br> * ???,SQLsqlDB?<br> * SQL?...<br> * * @param page * @param sqlString * @param resultClass * @param returnVO * - VO?,<br> * - ?resultClass<br> * @return */ public <E> Page<E> findBySqlString(Page<E> page, String sqlString, Class[] resultClass, Class returnVO) { return findBySqlString(page, sqlString, null, resultClass, returnVO); } /** * ???<br> * hibernateBUG<br> * ???,SQLsqlDB?<br> * SQL?...<br> * * @param page * @param sqlString * @param parameter * @param resultClass * @param returnVO * - VO?,<br> * - ?resultClass<br> * @return */ public <E> Page<E> findBySqlStringParameter(Page<E> page, String sqlString, Parameter parameter, Class[] resultClass, Class returnVO) { return findBySqlString(page, sqlString, parameter, resultClass, returnVO); } /** * SQL * * @param page * @param sqlString * @param resultClass * @param parameter * @return */ public <E> Page<E> findBySql(Page<E> page, String sqlString, Parameter parameter, Class<?> resultClass) { return findBySqlString(page, sqlString, parameter, new Class[] { resultClass }, null); } public <E> Page<E> findBySqlString(Page<E> page, String sqlString, Class[] resultClass) { return findBySqlString(page, sqlString, null, resultClass, null); } private void setResultTransformer(SQLQuery query, Class[] resultClass) { if (resultClass == null || resultClass.length <= 0) return; for (Class cls : resultClass) { query.addEntity(cls); } } @SuppressWarnings("unchecked") public <E> Page<E> findBySqlString(Page<E> page, String sqlString, Parameter parameter, Class[] resultClass, Class returnVO) { // get count if (!page.isDisabled() && !page.isNotCount()) { String select = StringHelper.isNull(page.getCountDistinctColumn()) ? "select count(*) " : "select count(distinct " + page.getCountDistinctColumn() + ") "; String countSqlString = select + removeSelect(removeOrders(sqlString)); // page.setCount(Long.valueOf(createSqlQuery(countSqlString, // parameter).uniqueResult().toString())); Query query = createSqlQuery(countSqlString, parameter); List<Object> list = query.list(); if (list.size() > 0) { page.setCount(Long.valueOf(list.get(0).toString())); } else { page.setCount(list.size()); } if (page.getCount() < 1) { return page; } } String sql = sqlString; // group by if (StringUtils.isNotBlank(page.getGroupBy())) { sql += " group by " + page.getGroupBy(); } // order by if (StringUtils.isNotBlank(page.getOrderBy())) { sql += " order by " + page.getOrderBy(); } SQLQuery query = createSqlQuery(sql, parameter); // set page if (!page.isDisabled()) { query.setFirstResult(page.getFirstResult()); query.setMaxResults(page.getMaxResults()); } boolean isMutilReturn = false; if (resultClass != null && resultClass.length == 1) setResultTransformer(query, resultClass[0]); else if (resultClass != null && resultClass.length > 1) { setResultTransformer(query, resultClass); isMutilReturn = true; } List l = query.list(); page.setList(query.list()); if (isMutilReturn) setResultReturnVO(returnVO, page); return page; } @SuppressWarnings("unchecked") public <E> Page<E> find(Page<E> page, String qlString, Parameter parameter, Class[] resultClass, Class returnVO) { // get count if (!page.isDisabled() && !page.isNotCount()) { String countQlString = "select count(*) " + removeSelect(removeOrders(qlString)); // page.setCount(Long.valueOf(createQuery(countQlString, // parameter).uniqueResult().toString())); Query query = createQuery(countQlString, parameter); List<Object> list = query.list(); if (list.size() > 0) { page.setCount(Long.valueOf(list.get(0).toString())); } else { page.setCount(list.size()); } if (page.getCount() < 1) { return page; } } String ql = qlString; // group by if (StringUtils.isNotBlank(page.getGroupBy())) { ql += " group by " + page.getGroupBy(); } // order by if (StringUtils.isNotBlank(page.getOrderBy())) { ql += " order by " + page.getOrderBy(); } Query query = createQuery(ql, parameter); // set page if (!page.isDisabled()) { query.setFirstResult(page.getFirstResult()); query.setMaxResults(page.getMaxResults()); } page.setList(query.list()); boolean isMutilReturn = false; if (resultClass != null && resultClass.length > 1) isMutilReturn = true; if (isMutilReturn) setResultReturnVO(returnVO, page); return page; } private void setResultReturnVO(Class returnVO, Page result) { List<Class> lst = null; List<Object[]> o = result.getList(); List resList = new ArrayList(); if (returnVO == null) return; try { // ???? lst = ReflectHelper.getAllvarClass(returnVO); // for (Object[] e : o) { Object obj = returnVO.newInstance(); // e=Object[]{a,b} // for (Object ef : e) { // ?? for (Class cls : lst) { // ?set if (cls.equals(ef.getClass())) { try { VOAnnotation vo = ReflectHelper.getAnnotationByClass(returnVO, cls, VOAnnotation.class); ReflectHelper.setValue(obj, vo.varName(), ef); } catch (IllegalArgumentException | InvocationTargetException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } } resList.add(obj); } result.setList(resList); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } public List<T> manyFind(DetachedCriteria detachedCriteria, int size) { return manyFind(detachedCriteria, Criteria.DISTINCT_ROOT_ENTITY, size); } public List<Map> findBySQLListMap(final String sql, final int pageNo, final int numPerPage) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, InstantiationException { List<Map> l = findBySQL(sql, pageNo, numPerPage).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list(); return l; } public SQLQuery findBySQL(final String sql, final int pageNo, final int numPerPage) { return (SQLQuery) (T) getSession().doReturningWork(new ReturningWork() { public SQLQuery execute(Connection connection) throws SQLException { SQLQuery sqlQuery = getSession().createSQLQuery(sql); if (pageNo > 0) { sqlQuery.setFirstResult((pageNo - 1) * numPerPage); sqlQuery.setMaxResults(numPerPage); } return sqlQuery; } }); } }