JPA封装介绍

参考

flea-db使用之封装JPA操作数据库 源代码

依赖

mysql-connector-java-5.1.25.jar

<!-- 数据库JDBC连接相关 (MySQL的JDBC驱动)-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.25</version>
</dependency>

eclipselink-2.5.0.jar

<!-- 数据库持久化相关 EclipseLink-->
<dependency><groupId>org.eclipse.persistence</groupId><artifactId>eclipselink</artifactId><version>2.5.0</version>
</dependency>

内容讲解

目前支持 JPA + MySQL模式,需要各位本地自行装下MySQL数据库。

1. Flea JPA查询对象 — FleaJPAQuery

该类用于实现JPA 标准化方式的数据库查询操作,可以自行组装查询条件。下面对一些关键点进行讲解,且听我细细道来 (这一版并发环境下 可能存在问题,后面我会专门写一篇博文讲解 Flea JPA查询对象的问题,其中引入了对象池的概念 )。

  • 获取FleaJPAQuery实例,并初始化内部成员变量

        private static volatile FleaJPAQuery query;private EntityManager entityManager; // JPA中用于增删改查的持久化接口private Class sourceClazz; // 实体类类对象private Class resultClazz; // 操作结果类类对象private Root root; // 根SQL表达式对象private CriteriaBuilder criteriaBuilder; //标准化生成器private CriteriaQuery criteriaQuery; // 标准化查询对象private List<Predicate> predicates; // Where条件集合private List<Order> orders; // 排序集合private List<Expression> groups; // 分组集合private FleaJPAQuery() {}/*** <p> 获取Flea JPA查询对象 </p>* (单例模式,本身没有问题,但是由于获取之后Flea JPA查询对象还要使用,* 这在有点并发的环境下就存在问题了;后面我会单独写一篇博文讲解基于对象池* 的多例模式,既保证并发下各个线程获取的Flea JPA查询对象之间互不影响,* 同时也能保证尽可能少的新建Flea JPA查询对象) ** @return Flea JPA查询对象* @since 1.0.0*/public static FleaJPAQuery getQuery() {if (ObjectUtils.isEmpty(query)) {synchronized (FleaJPAQuery.class) {if (ObjectUtils.isEmpty(query)) {query = new FleaJPAQuery();}}}return query;}/*** <p> getQuery()之后,一定要调用该方法进行初始化 </p>** @param entityManager JPA中用于增删改查的持久化接口* @param sourceClazz   实体类类对象* @param resultClazz   操作结果类类对象* @since 1.0.0*/public void init(EntityManager entityManager, Class sourceClazz, Class resultClazz) {this.entityManager = entityManager;this.sourceClazz = sourceClazz;this.resultClazz = resultClazz;// 从持久化接口中获取标准化生成器criteriaBuilder = entityManager.getCriteriaBuilder();// 通过标准化生成器 获取 标准化查询对象if (ObjectUtils.isEmpty(resultClazz)) {// 行记录查询结果criteriaQuery = criteriaBuilder.createQuery(sourceClazz);} else {// 单个查询结果criteriaQuery = criteriaBuilder.createQuery(resultClazz);}// 通过标准化查询对象,获取根SQL表达式对象root = criteriaQuery.from(sourceClazz);predicates = new ArrayList<Predicate>();}
    
  • 拼接查询条件,添加排序和分组

        // 等于条件 (单个属性列)public void equal(String attrName, Object value) throws DaoException;// 等于条件 (多个属性列)public void equal(Map<String, Object> paramMap) throws DaoException;// 不等于条件 (单个属性列)public void notEqual(String attrName, Object value) throws DaoException;// 等于条件 (多个属性列)public void notEqual(Map<String, Object> paramMap) throws DaoException;// is null 条件,某属性值为空public void isNull(String attrName) throws DaoException;// is not null 条件,某属性值为非空public void isNotNull(String attrName) throws DaoException;// in 条件, attrName属性的值在value集合中public void in(String attrName, Collection value) throws DaoException;//  not in 条件,attrName属性的值不在value集合中public void notIn(String attrName, Collection value) throws DaoException;// like 条件, 模糊匹配public void like(String attrName, String value) throws DaoException;// 小于等于条件public void le(String attrName, Number value) throws DaoException;// 小于条件public void lt(String attrName, Number value) throws DaoException;// 大于等于条件public void ge(String attrName, Number value) throws DaoException;// 大于条件public void gt(String attrName, Number value) throws DaoException;// between and 条件, 时间区间查询public void between(String attrName, Date startTime, Date endTime) throws DaoException;// 大于某个日期值条件public void greaterThan(String attrName, Date value) throws DaoException;// 大于等于某个日期值条件public void greaterThanOrEqualTo(String attrName, Date value) throws DaoException;// 小于某个日期值条件public void lessThan(String attrName, Date value) throws DaoException;// 小于等于某个日期值条件public void lessThanOrEqualTo(String attrName, Date value) throws DaoException;// 统计数目,在getSingleResult调用之前使用public void count();// 统计数目(带distinct参数),在getSingleResult调用之前使用public void countDistinct();// 设置查询某属性的最大值,在getSingleResult调用之前使用public void max(String attrName) throws DaoException;// 设置查询某属性的最小值,在getSingleResult调用之前使用public void min(String attrName) throws DaoException;// 设置查询某属性的平均值,在getSingleResult调用之前使用public void avg(String attrName) throws DaoException;// 设置查询某属性的值的总和,在getSingleResult调用之前使用public void sum(String attrName) throws DaoException;// 设置查询某属性的值的总和(Long),在getSingleResult调用之前使用public void sumAsLong(String attrName) throws DaoException;// 设置查询某属性的值的总和(Double),在getSingleResult调用之前使用public void sumAsDouble(String attrName) throws DaoException;// 去重某一列public void distinct(String attrName) throws DaoException;// 添加order by子句public void addOrderby(String attrName, String orderBy) throws DaoException;// 添加group by子句public void addGroupBy(String attrName) throws DaoException;
    
  • 获取查询结果(记录行 或 单个结果)

     // 获取查询的记录行结果集合public List getResultList() throws DaoException;// 获取查询的记录行结果集合(设置查询范围)public List getResultList(int start, int max) throws DaoException;// 获取查询的单个属性列结果集合// 需要先调用 distinct,否则默认返回行记录结果集合public List getSingleResultList() throws DaoException;// 获取查询的单个属性列结果集合(设置查询范围,可用于分页)// 需要先调用 distinct,否则默认返回行记录结果集合public List getSingleResultList(int start, int max) throws DaoException;// 获取查询的单个结果// 需要提前调用 (count, countDistinct, max, min, avg, sum, sumAsLong, sumAsDouble)public Object getSingleResult() throws DaoException;
    

2. 数据处理的基本接口 — IFleaJPABaseDataHandler

基本的数据操作接口,其中包含了查询,(批量)添加,(批量)更新,删除等操作。

3. 抽象Flea JPA DAO层接口 — IAbstractFleaJPADAO

/*** <p> 抽象Flea JPA DAO层接口,实现基本的查询、(批量)添加、(批量)更新、删除接口 </p>** @author huazie* @version 1.0.0* @since 1.0.0*/
public interface IAbstractFleaJPADAO<T> extends IFleaJPABaseDataHandler<T> {}

4. 抽象Flea JPA DAO层实现 — AbstractFleaJPADAOImpl

本类中实现上述3中查询、(批量)添加、(批量)更新、删除的接口的具体逻辑。

  • 该类实现上述抽象Flea JPA DAO层接口,同样有类型T,由子类指定其操作的实体类。

    public abstract class AbstractFleaJPADAOImpl<T> implements IAbstractFleaJPADAO<T>
    
  • 无参构造方法,用于获取子类指定的实体类类对象。

    /*** <p> 获取T类型的Class对象 </p>** @since 1.0.0*/
    public AbstractFleaJPADAOImpl() {// 获取泛型类的子类对象的Class对象Class<?> clz = getClass();// 获取子类对象的泛型父类类型(也就是AbstractDaoImpl<T>)ParameterizedType type = (ParameterizedType) clz.getGenericSuperclass();if (LOGGER.isDebugEnabled()) {LOGGER.debug("Type={}", type);}Type[] types = type.getActualTypeArguments();clazz = (Class<T>) types[0];if (LOGGER.isDebugEnabled()) {LOGGER.debug("ClassName={}", clazz.getName());}
    }
    
  • 实现接口方法,可参见上述类源码

  • 持久化接口获取,由子类实现(可参考下面的持久化单元DAO层实现)

    /*** 获取实体管理器** @return 实体管理器* @since 1.0.0*/
    protected abstract EntityManager getEntityManager();/*** 获取实体管理器** @param entity 实体类对象实例* @return 实体管理器类* @since 1.0.0*/
    public EntityManager getEntityManager(T entity) throws CommonException {return getEntityManager(entity, false);
    }/*** 获取实体管理器** @param entity 实体类对象实例* @param flag   获取实体管理器标识【true:getFleaNextValue获取实体管理器, false: 其他场景获取实体管理器】* @return 实体管理器类* @throws CommonException 通用异常* @since 1.2.0*/
    private EntityManager getEntityManager(T entity, boolean flag) throws CommonException {EntityManager entityManager = getEntityManager();// 实体类设置默认库名setDefaultLibName(entity);// 处理并添加分表信息,如果不存在分表则不处理entityManager = LibTableSplitHelper.findTableSplitHandle().handle(entityManager, entity, flag);return entityManager;
    }
    
  • Flea JPA查询对象获取

    /*** <p> 获取指定的查询对象 </p>** @return 自定义Flea JPA查询对象* @since 1.0.0*/
    protected FleaJPAQuery getQuery(Class result) {// 获取当前的持久化单元名String unitName = FleaEntityManager.getPersistenceUnitName(this.getClass().getSuperclass());FleaJPAQueryPool pool;if (StringUtils.isBlank(unitName)) {// 获取Flea JPA查询对象池 (使用默认对象池名"default"即可)pool = FleaObjectPoolFactory.getFleaObjectPool(FleaJPAQuery.class, FleaJPAQueryPool.class);} else {// 获取Flea JPA查询对象池 (使用持久化单元名unitName作为对象池名)pool = FleaObjectPoolFactory.getFleaObjectPool(unitName, FleaJPAQuery.class, FleaJPAQueryPool.class);}if (ObjectUtils.isEmpty(pool)) {throw new RuntimeException("Can not get a object pool instance");}// 获取Flea JPA查询对象实例FleaJPAQuery query = pool.getFleaObject();if (LOGGER.isDebugEnabled()) {Object obj = new Object() {};LOGGER.debug1(obj, "FleaJPAQueryPool = {}", pool);LOGGER.debug1(obj, "FleaJPAQuery = {}", query);}// 获取实例后必须调用该方法,对Flea JPA查询对象进行初始化query.init(getEntityManager(), entityClass, result);return query;
    }
    

5. 定义抽象Flea JPA SV层接口 — IAbstractFleaJPASV

/*** <p> 抽象Flea JPA SV层接口 </p>** @author huazie* @version 1.0.0* @since 1.0.0*/
public interface IAbstractFleaJPASV<T> extends IFleaJPABaseDataHandler<T> {}

6. 抽象Flea JPA SV层实现 — AbstractFleaJPASVImpl

该类实现上述抽象Flea JPA SV层接口,相关代码也比较简单,具体接口实现内部调用抽象Flea JPA DAO层实现。

@Overridepublic T query(long entityId) throws Exception {return getDAO().query(entityId);}// ... 其他接口实现已省略/*** <p> 获取Flea JPA DAO层实现 </p>** @return 抽象Flea JPA DAO层实现* @since 1.0.0*/protected abstract IAbstractFleaJPADAO<T> getDAO();

7. 持久化单元DAO层实现 — FleaAuthDAOImpl

该类与持久化单元一一对应,如果新增一个持久化配置,即需要新增一个持久化单元DAO层实现,同时Spring配置中,需要加入对应的持久化单元事物管理者配置。

/*** <p> FleaAuth数据源DAO层父类 </p>** @author huazie* @version 1.0.0* @since 1.0.0*/
public class FleaAuthDAOImpl<T> extends AbstractFleaJPADAOImpl<T> {@PersistenceContext(unitName="fleaauth")protected EntityManager entityManager;@Override@Transactional("fleaAuthTransactionManager")public boolean remove(long entityId) throws Exception {return super.remove(entityId);}// 其余代码省略。。。@Overrideprotected EntityManager getEntityManager() {return entityManager;}}

8. 配置介绍

  • 持久化单元配置 fleaauth-persistence.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0" 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_2_0.xsd"><persistence-unit name="fleaauth" transaction-type="RESOURCE_LOCAL"><!-- provider --><provider>org.eclipse.persistence.jpa.PersistenceProvider</provider><!-- Connection JDBC --><class>具体实体类全名</class><exclude-unlisted-classes>true</exclude-unlisted-classes><properties><property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /><property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/fleaauth?useUnicode=true&amp;characterEncoding=UTF-8" /><property name="javax.persistence.jdbc.user" value="root" /><property name="javax.persistence.jdbc.password" value="root" /></properties></persistence-unit>
    </persistence>
    
  • Spring配置

     <!-- 持久化单元管理器 --><bean id="defaultPersistenceManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"><property name="persistenceXmlLocations"><!-- 可以配置多个持久单元 --><list><value>classpath:META-INF/fleaauth-persistence.xml</value></list></property></bean><!-- 持久化提供者 --><bean id="defaultPersistenceProvider" class="org.eclipse.persistence.jpa.PersistenceProvider"/><!-- 加载时织入器 --><bean id="defaultLoadTimeWeaver" class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/><!-- JPA厂商适配器,对外公开EclipseLink的持久性提供程序和EntityManager扩展接口  --><bean id="defaultVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"><!-- 是否在控制台显示sql --><property name="showSql" value="true"/></bean><!-- JpaDialect EclipseLink持久化服务的实现--><bean id="defaultJpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/><!-- 以下部分 与指定持久化单元一一对应 --><!-- ################################## --><!-- FleaAuth TransAction Manager JPA --><!-- ################################## --><bean id="fleaAuthEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="persistenceUnitManager" ref="defaultPersistenceManager"/><property name="persistenceUnitName" value="fleaauth"/><property name="persistenceProvider" ref="defaultPersistenceProvider"/><property name="jpaVendorAdapter" ref="defaultVendorAdapter"/><property name="jpaDialect" ref="defaultJpaDialect"/><property name="jpaPropertyMap"><map><entry key="eclipselink.weaving" value="false"/></map></property></bean><bean id="fleaAuthTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="fleaAuthEntityManagerFactory"/></bean><tx:annotation-driven transaction-manager="fleaAuthTransactionManager"/>
    

至此,相关JPA使用已封装完毕,下一篇博文将介绍 JPA接入 ,敬请期待。

flea-db使用之JPA封装介绍相关推荐

  1. windows7、windows 2008和windows 2008 R2 的系统封装介绍

    windows7.windows 2008和windows 2008 R2 的系统封装介绍 第一步: windows7.windows2008和windows 2008R2 中的sysprep.exe ...

  2. YugaByte DB 分布式 开源 关系型数据库介绍

    YugaByte DB 分布式 开源 关系型数据库介绍 什么是YugaByte DB? YugaByte DB是一个高性能的分布式SQL数据库,用于为全球互联网规模的应用程序提供支持.YugaByte ...

  3. Altium designer18系列教程一 建工程和封装介绍

    Altium designer18系列教程一 建工程和封装介绍 AD18介绍 AD18建工程 AD18使用 AD整体规划和封装介绍 封装介绍(借鉴燕骏工作室AD系列教程封装介绍) 一.标准零件 二. ...

  4. 《C#零基础入门之百识百例》(五十二)封装介绍 -- 二维多项式求值

    C#零基础入门 面向对象 -- 封装介绍 -- 二维多项式求值 前言 一,封装概念 二,封装属性 三,实例练习 -- 二维多项式求值 3.1 题目描述 3.2 问题分析 3.3 参考代码 前言 本文属 ...

  5. 【企业微信机器人封装介绍文档】

    企业微信机器人封装介绍文档 概述 本文档介绍了一个功能强大的企业微信机器人封装,旨在简化企业微信机器人的使用和开发过程.该封装提供了以下主要功能: 支持发送PNG图片 支持发送文件 支持定时发送文本消 ...

  6. 上门洗车APP --- Android客户端开发 之 网络框架封装介绍(一)

    上门洗车APP --- Android客户端开发 之 网络框架封装介绍(一) 上篇文章中给大家简单介绍了一些业务,上门洗车APP --- Android客户端开发 前言及业务简介,本篇文章给大家介绍下 ...

  7. c语言tinyxml使用方法,ticpp(TinyXML++)TinyXML的C++封装介绍

    ticpp(TinyXML++)正式名称为ticpp,ticpp是一个使用c++语言封装的全新的基于TinyXML的操作XML的库.它使用了模板,异常和错误处理. ticpp(TinyXML++) i ...

  8. 20221014 芯片封装介绍

    内容主要来源于:史上最全的芯片封装介绍,仅此一篇 2017-07-20 17:40 芯片封装,简单点来讲就是把Foundry生产出来的集成电路裸片(Die)放到一块起承载作用的基板上,再把管脚引出来, ...

  9. JPA——API介绍、完成JPA的CRUD操作、JPQL完成复杂查询操作

    目录 一.JPA的API介绍 二.抽取JPAUtils工具类 三.JPA完成增删改查操作 四.JPA中的复杂查询(使用JPQL) 五.总结 一.JPA的API介绍 跳转到目录 Persistence对 ...

  10. java db类_Java-jdbc-DBUtils工具类介绍

    如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils. DBUtils就是JDBC的简化开发工具包.需要项 ...

最新文章

  1. [转]cocos2d-js 3.0 屏幕适配方案 分辨率适应
  2. 零基础入门学习Python(36) 类和对象:继承
  3. CentOS7 minimal 没有netstat命令
  4. 支持向量机libsvm实战入门
  5. java个人学习笔记:javaBean
  6. SpringMVC的常用注解
  7. Python到底是什么?Python发展前景好吗?
  8. ASP.NET Core 基于JWT的认证(二)
  9. SpringCloudSpringBootmybatis分布式微服务云架构-hystrix参数详解
  10. 《白帽子讲web安全》学习笔记 (4)
  11. 【Tensorflow2.x】设置GPU(内存自增长、指定GPU)
  12. 陈丹琦-我是如何学习计算机编程的
  13. 资料:线性代数与空间解析几何知识点全汇总
  14. Fibonacci 斐波那契数列的R语言实现
  15. 印度BIS认证产品范围和注意事项
  16. 米家接入HomeKit系列四:HomeBridge搭建、配置与接入米家设备
  17. 004永磁同步电机的工作原理:大白话详细讲解从最简单的直流有刷电机到永磁同步电机是如何转动起来的
  18. Android获取QQ音乐url,QQ音乐vkey获取,更新播放url
  19. 单作用叶片泵的结构与工作原理
  20. 情以何堪的伤感QQ日志分享:一句话,了断一切

热门文章

  1. 锁机制初探(五)Moniter的实现原理
  2. html5课程总结500字,体育课心得体会500字(精选6篇)
  3. 内存取证工具Volatility学习
  4. 所谓的进步和提升,就是完成认知升级
  5. Windows故障恢复控制台使用方法
  6. 华三交换机snmp配置
  7. python 计算斜率
  8. JavaCV 制作字符画
  9. Unity开发VR项目(四)—— 创建VR场景
  10. 淘宝闲鱼京东等电商api的简单调用