数据库访问层Dao业务逻辑小记录(二)
我比较喜欢海蓝色,海蓝天蓝,心情海蓝,希望我坚持下来,以前没有即时的记录,过去这么久了,才拼命的去回忆,思路会有断痕,有褶皱。
在具体实现由Dao层定义的接口时,我采用的是JPA规范,JPA全称叫Java持久化API,百度百科说JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。理解它,需要实践它。
1.同样在base包下新建抽象类DaoSupport.class,并实现接口Dao。由于是使用了JPA规范,所以加入注解Transicational,作用是为类中的方法加入事物。
/** 默认:方法被加入事物,传播行为:Propagation.REQUIRED */ @Transactional public abstract class DaoSupport implements DAO { }
2.注入实体管理其,EntityManager对象,通过注解PersistenceContext
// 注入EntityManager @PersistenceContext protected EntityManager em;
3.实现具体的方法时,可直接使用EntityManager 提供的内置方法,也可以通过sql语句来实现,这里使用前者。
4.简要记录:保存对象-->persist(含有很好理解,使对象持久化的存储),删除数据,通过id找到具体对象,在remove。设计到,remove,和getReference方法。
更新对象(数据)--> merger,可理解为使对象状态由游离状态合并(merge)为持久化状态。由于DaoSupport是抽象类,所以子类只需要继承该类,便可以直接调用这些方法,不需要再重写。
/** * 执行过程 AOP编程,方法入口:em被注入值(实例化),打开事物,事物操作,关闭操作 */ @Override public void save(Object entity) { em.persist(entity); } @Override public void update(Object entity) { em.merge(entity); } @Override public <T> void delete(Class<T> entityclazz, Object... entityids) { for (Object id : entityids) { em.remove(em.getReference(entityclazz, id)); } }
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED) @Override public <T> T search(Class<T> entityclazz, Object entityid) { return em.find(entityclazz, entityid); }
5.往往实现分页查询都是要复杂一些,由于接口中定义的分页查询都是方法的重载,所以就好办了,不用去写每个方法,实现最复杂的一个吧。
6.通过反射获取实体名
/*** * 反射获取实体名 * * @param entityClass * @return */ protected <T> String getEntityName(Class<T> entityClass) { String entityName = entityClass.getSimpleName(); Entity entity = entityClass.getAnnotation(Entity.class); System.out.println(entity.name()); if (entity.name() != null && !"".equals(entity.name())) { entityName = entity.name(); } System.out.println("实体名 : " + entityName); return entityName; }
7.拼凑order by 语句
/** * 根据一些键值,拼凑order by 语句 * 例如:order by id(key) desc(value) * @param orderby * @return */ protected String buildOrderby(LinkedHashMap<String, String> orderby) { if (orderby != null && orderby.size() > 0) { StringBuffer sql = new StringBuffer(""); sql.append(" order by "); // 拼凑order by 语句 for (String key : orderby.keySet()) { sql.append("o.").append(key).append(" ") .append(orderby.get(key)).append(","); } sql.deleteCharAt(sql.length() - 1); return sql.toString(); } return ""; }
8.动态设置参数
/** * 为查询添加参数,?1,?2, * * @param query * @param params */ public void setParamters(Query query, Object[] params) { if (params != null && params.length > 0) { for (int i = 0; i < params.length; ++i) { query.setParameter(i + 1, params[i]); } } }
9.具体实现
@SuppressWarnings("unchecked") @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED) public <T> QueryResult<T> getScrollData(Class<T> entityclass, int startIndex, int maxCount, String whereJpql, Object[] params, LinkedHashMap<String, String> orderby) { QueryResult<T> qr = new QueryResult<T>(); String entityName = getEntityName(entityclass); String sql = "select o from " + entityName + " o " + (whereJpql == null ? "" : "where " + whereJpql) + buildOrderby(orderby); String sql2 = "select count(o) from " + entityName + " o " + (whereJpql == null ? "" : "where " + whereJpql); Query query = em.createQuery(sql); setParamters(query, params); if(startIndex != -1 && maxCount != -1) { query.setFirstResult(startIndex); query.setMaxResults(maxCount); } qr.setResults(query.getResultList()); query = em.createQuery(sql2); setParamters(query, params); qr.setCount((Long) query.getSingleResult()); return qr; }
10.重载方法调用
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED) @Override public <T> QueryResult<T> getScrollData(Class<T> entityclass, int startIndex, int maxCount) { return getScrollData(entityclass, startIndex, maxCount, null, null, null); } @Override public <T> QueryResult<T> getScrollData(Class<T> entityclass, int startIndex, int maxCount, String whereJpql, Object[] params) { return getScrollData(entityclass, startIndex, maxCount, whereJpql, params, null); } @Override public <T> QueryResult<T> getScrollData(Class<T> entityclass, int startIndex, int maxCount, LinkedHashMap<String, String> orderby) { return getScrollData(entityclass, startIndex, maxCount, null,null, orderby); } @Override public <T> QueryResult<T> getScrollData(Class<T> entityclass) { return getScrollData(entityclass, -1, -1); }
11.由于是面向AOP编程,通常是采用面向接口操作。步骤:定义接口,该接口继承Dao,定义实现类继承DaoSupport,并实现该接口。该实现类基本上可以满足常用业务了。
public interface StyleService extends DAO{ } @Service("productStyleService") @Transactional public class StyleServiceBean extends DaoSupport implements StyleService{ }
这次note暂时到这里吧,祝我顺利哈。