`
hsyzijvaa
  • 浏览: 106905 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论
阅读更多



JPA 应用技巧 1:实体类和实体 DAO 模板

Posted on 2011-09-07 17:40 蜀山兆孨龘 阅读(1512) 评论(8)  编辑  收藏  所属分类: Java EE






    最近闲来无事(楼主确实太懒了),重翻旧账,捣鼓了下 JPA 2.0,通过不断地写代码和谷歌,又有了一些旧瓶装新酒的发现和吐槽。楼主将在这一系列文章中慢慢道来。本次开篇带来的是两个模板类:用作实体类基础框架的 AbstractEntity, 以及实现了对实体的基本 CRUD 操作的 BasicEntityDao。
    一个实体类必须实现 java.io.Serializable 接口,必须有一个 ID 字段作为主键,且最好覆盖 equals 和 hashCode 方法。因为实体类和数据表有对应关系,所以往往根据 ID 来实现 equals 和 hashCode。这很自然地可以引出一个模板类,所有的实体类都可以从它继承:
   
        /**
         * 该类可作为实体类的模板,其 {@link #equals(Object)} 和 {@link hashCode()} 方法基于主键实现。
         * 子类只需要实现 {@link #getId()} 方法。
         */
        public abstract class AbstractEntity implements Serializable {
            /**
             * 返回主键。
             */
            public abstract Object getId();

            @Override
            public boolean equals(Object obj) {
                if (this == obj) {
                    return true;
                }
                if (obj == null || getClass() != obj.getClass()) {
                    return false;
                }
                return getId() == null ? false
                        : getId().equals(((AbstractEntity) obj).getId());
            }

            @Override
            public int hashCode() {
                return Objects.hashCode(getId());
            }
        }
   
    针对主键的类型,AbstractEntity 可以进一步扩展。例如,可以扩展出一个 UuidEntity,它使用随机生成的 UUID 作为主键:
   
        @MappedSuperclass
        public class UuidEntity extends AbstractEntity {
            @Id
            private String id;

            @Override
            public String getId() {
                return id;
            }

            @PrePersist
            private void generateId() {
                // 仅在持久化前生成 ID,提升一点性能。
                id = UUID.randomUUID().toString();
            }
        }
   
    继续发挥想象,让它支持乐观锁:
   
        @MappedSuperclass
        public class VersionedUuidEntity extends UuidEntity {
            @Version
            private int version;
        }
   
    这儿顺便插嘴吐槽下主键的类型。用整数还是 UUID 好呢?这个问题在网上也是争论纷纷。在楼主看来,两者各有优劣:整数主键性能高,可读性也好,但会对数据迁移,例如合并两个数据库,造成不小的麻烦,因为可能出现一大堆重复的主键;UUID 性能差些,看起来晃眼,虽然据说有些数据库针对性地做了优化,想来也不大可能优于整数,不过好处就是理论上出现重复主键的概率比中彩票还小(福彩除外)。说这么一大堆,其实还是蛮纠结啊……楼主一般倾向于用 UUID,只要服务器的配置够劲,想来不会出现明显的性能问题。
    接下来说说 BasicEntityDao,它提供了基本的 CRUD 实现,可以用来为会话 Bean 做模板:
   
        /**
         * 提供了对实体进行基本 CRUD 操作的实现,可作为会话 Bean 的模板。
         */
        public abstract class BasicEntityDao<T> {
            private Class<T> entityClass;
            private String entityClassName;
            private String findAllQuery;
            private String countQuery;

            protected BasicEntityDao(Class<T> entityClass) {
                this.entityClass = Objects.requireNonNull(entityClass);
                entityClassName = entityClass.getSimpleName();
                findAllQuery = "select e from " + entityClassName + " e";
                countQuery = "select count(e) from " + entityClassName + " e";
            }

            /**
             * 返回用于数据库操作的 {&#64;link EntityManager} 实例。
             */
            protected abstract EntityManager getEntityManager();

            public void persist(T entity) {
                getEntityManager().persist(entity);
            }

            public T find(Object id) {
                return getEntityManager().find(entityClass, id);
            }

            public List<T> findAll() {
                return getEntityManager().createQuery(findAllQuery, entityClass).getResultList();
            }

            public List<T> findRange(int first, int max) {
                return getEntityManager().createQuery(findAllQuery, entityClass)
                        .setFirstResult(first).setMaxResults(max).getResultList();
            }

            public long count() {
                return (Long) getEntityManager().createQuery(countQuery).getSingleResult();
            }

            public T merge(T entity) {
                return getEntityManager().merge(entity);
            }

            public void remove(T entity) {
                getEntityManager().remove(merge(entity));
            }
        }
   
    子类只需要提供 getEntityManager() 的实现即可。假设楼主要做一个养鸡场管理系统,对鸡圈进行操作的会话 Bean 就可以简单地写成:
   
        &#64;Stateless
        public class CoopDao extends BasicEntityDao<Coop> {
            &#64;Persistence
            private EntityManager em;

            public CoopDao() {
                super(Coop.class);
            }

            &#64;Override
            protected EntityManager getEntityManager() {
                return em;
            }

            // 更多方法……
        }
   

0
1
分享到:
评论

相关推荐

    SpringBoot使用Spring-data-jpa简化数据访问层

    由于模板Dao的实现,使得这些具体实体的Dao层已经变的非常“薄”,有一些具体实体的Dao实现可能完全就是对模板Dao的简单代理,并且往往这样的实现类可能会出现在很多实体上。Spring-data-jpa的出现正可以让这样一个...

    mybatis generator

    生成实体类 生成WEB API相关接口 Controller 生成业务逻辑相关的Service/ServiceImpl 生成操作数据库的Dao接口与Mapper.xml映射文件 生成单元测试等 软件最大的特色就是操作SQL类的Assist查询帮助类(Assist是...

    本科毕业设计+基于Springboot+JPA+semantic开发的个人博客系统

    项目知识详解: 整体项目基于springboot框架开发 数据库采用了mysql 以及 JPA 实现对数据库的链接 ...依次是javabean,配置类,contrler层,dao层,实体类,异常定义,异常处理,拦截类,service层,工具类

    easyjpa:一个超级简单的jpa,分分钟解放你的配置文件,一键搞定通用的增删改查功能

    这些实体类与数据库表建立的映射关系,提供通用的CRUD操作API,能够自动生成预先SQL语句并执行,使用者可以通过针对对象的思维方式来轻松完成增删改查的操作。 它具有以下特点: 开箱即用 EasyJpa上手简单,只要有...

    【linjiashop邻家小铺v0.8】基于Spring Boot和Vue.js的web商城系统 手机h5 小程序.zip

    linjiashop-generator 代码生成模块,根据实体生成dao,service,后台管理的controller和页面,配合IDEA 代码生成插件webflash-generator使用效果更好,使用前请仔细阅读该文档 源码更新日志: linjiashop商城系统 ...

    JAVA程序开发大全---上半部分

    13.2.2 使用反向工程生成JPA实体类和DAO类 234 13.2.3 调整生成的实体类标注 237 13.2.4 使用JPA功能 238 13.3 MyEclipse中支持JPA规范的工具 238 13.3.1 JPA透视图 239 13.3.2 JPA标注配置视图 239 13.3.3 JPA代码...

    Spring-generator一键生成数据库文件

    Spring-generator 是基于 javafx8 开发的图形界面 Spring 代码生成器,使用 Apache FreeMarker 作为代码文件的模板,用户可以一键将...生成的实体类(可以自己修改模板按自己的风格生成): Dao 接口: Mapper.xml 文件:

    基于Springboot+JPA+semantic开发的个人博客系统源码+项目说明.zip

    依次是javabean,配置类,contrler层,dao层,实体类,异常定义,异常处理,拦截类,service层,工具类 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200604160124781.png?x-oss-process=image/watermark,...

    Spring-Generator

    生成实体类 生成WEB API相关接口 Controller 生成业务逻辑相关的Service/ServiceImpl 生成操作数据库的Dao接口与Mapper.xml映射文件 生成单元测试等 软件最大的特色就是操作SQL类的Assist查询帮助类(Assist是...

    Spring in Action(第二版 中文高清版).part1

    5.3.3 使用Spring对JDBC的DAO支持类 5.4 在Spring里集成Hibernate 5.4.1 选择Hibernate的版本 5.4.2 使用Hibernate模板 5.4.3 建立基于Hibernate的DAO 5.4.4 使用Hibernate 3上下文会话 5.5 Spring和Java...

    Spring in Action(第2版)中文版

    5.3.3使用spring对jdbc的dao支持类 5.4在spring里集成hibernate 5.4.1选择hibernate的版本 5.4.2使用hibernate模板 5.4.3建立基于hibernate的dao 5.4.4使用hibernate3上下文会话 5.5spring和java持久api ...

    Spring in Action(第二版 中文高清版).part2

    5.3.3 使用Spring对JDBC的DAO支持类 5.4 在Spring里集成Hibernate 5.4.1 选择Hibernate的版本 5.4.2 使用Hibernate模板 5.4.3 建立基于Hibernate的DAO 5.4.4 使用Hibernate 3上下文会话 5.5 Spring和Java...

    linjiashop商城系统 v0.6

    linjiashop是一个基于...linjiashop-generator 代码生成模块,根据实体生成dao,service,后台管理的controller和页面,配合IDEA 代码生成插件webflash-generator使用效果更好,使用前请仔细阅读该文档linjiashop截图

    generator:Java代码生成工具

    Generator 是一款基于数据库表生成Java代码的工具,代码模板使用当前主流Java框架: Spring, SpringMVC, Mybatis(Mybatis-Plus、JPA) 组织,能够减少繁琐的重复性工作,让开发人员更专注于技术和性能,提高工作...

    linjiashop商城系统-其他

    linjiashop-generator 代码生成模块,根据实体生成dao,service,后台管理的controller和页面,配合IDEA 代码生成插件webflash-generator使用效果更好,使用前请仔细阅读该文档   linjiashop商城系统 更新日志: v...

    ProjectBuild

    实体类通过“服务的两种结构模式”定义,然后遵循dao,然后使用Maven构建工具来管理项目体系结构中的类,资源和依赖项。 登录或注册您必须先登录后才能自动打开该页面,而无需登录就无法打开任何其他页面。 主页...

Global site tag (gtag.js) - Google Analytics