绍兴市交通建设检测中心网站,江都城乡建设局网站,建设局网站建设方案书,景点网站模板一、前言 由于项目中的 实体#xff08;entity#xff09;默认都是继承一个父类#xff08;包含一些公共的属性#xff0c;比如创建时间#xff0c;修改时间#xff0c;是否删除#xff0c;主键id#xff09;。为了实现逻辑删除#xff0c;一般会自己实现RepositoryFa… 一、前言 由于项目中的 实体entity默认都是继承一个父类包含一些公共的属性比如创建时间修改时间是否删除主键id。为了实现逻辑删除一般会自己实现RepositoryFactoryBean 和 Repository。但是由于多个团队开发的结果表的结构没有同一也就是会出现有的表没有基础父类对应的字段这样就会导致自定义的jpa repository操作这些表就会出错。 二、最开始实现 默认父类 import java.io.Serializable;
import java.sql.Timestamp;import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;import org.hibernate.annotations.GenericGenerator;MappedSuperclass
public abstract class AbsIdEntity implements Serializable {private static final long serialVersionUID 7988377299341530426L;IdGenericGenerator(nameuuid, strategyuuid)GeneratedValue(generatoruuid)Column(nameid)protected String id;Column(name creationtime)protected Timestamp creationTimestamp new Timestamp(System.currentTimeMillis());Column(name lastmodifiedtime)protected Timestamp modificationTimestamp new Timestamp(System.currentTimeMillis());Column(name dr)protected int dr;// 是否删除。0:未删除;1:已删除/*** 主键对应id字段*/public String getId() { return id; }public void setId(String id) { this.id id; }/*** 创建日期对应ts_insert字段*/public Timestamp getCreationTimestamp() { return creationTimestamp; }public void setCreationTimestamp(Timestamp creationTimestamp) { this.creationTimestamp creationTimestamp; }/*** 修改日期对应ts_update字段*/public Timestamp getModificationTimestamp() { return modificationTimestamp; }public void setModificationTimestamp(Timestamp modificationTimestamp) { this.modificationTimestamp modificationTimestamp; }/*** 是否删除对应dr字段* return*/public int getDr() {return dr;}public void setDr(int dr) {this.dr dr;}} View Code 自定义Repository接口 添加BaseDao接口BaseDao继承了JpaSpecificationExecutor、CrudRepository这样可以保证所有Repository都有基本的增删改查以及分页等方法。在BaseDao上添加NoRepositoryBean标注这样Spring Data Jpa在启动时就不会去实例化BaseDao这个接口 import java.io.Serializable;import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.NoRepositoryBean;/*** Data Access Object基类已经包含了常用的增删改查操作。br* 使用时只需要继承接口不需要实现类spring自动通过cglib生成实现类* * param T* 实体类型*/
NoRepositoryBean
public interface BaseDaoT extends AbsIdEntity extendsCrudRepositoryT, Serializable/* JpaRepositoryT, Serializable */, JpaSpecificationExecutorT {
} View Code 然后使所有Repository接口都继承BaseDao 实现BaseRepository 定义好自定义的方法后我们现在通过一个基本的Repository类来实现该方法 首先添加BaseDaoImpl类继承SimpleJpaRepository类使其拥有Jpa Repository的基本方法。 我们发现Repository有两个构造函数 SimpleJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager)SimpleJpaRepository(Class domainClass, EntityManager em) 这里我们实现第二个构造函数拿到domainClass和EntityManager两个对象。因为我们要实现的是知道某个Repository是否支持某个领域对象的类型因此在实现构造函数时我们将domainClass的信息保留下来。 import java.io.Serializable;
import java.sql.Timestamp;import javax.persistence.EntityManager;import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;import com.yyjz.icop.base.dao.BaseDao;Transactional
public class BaseDaoImplT extends AbsIdEntity extends SimpleJpaRepositoryT, Serializable implements BaseDaoT {SuppressWarnings(unused)private final EntityManager entityManager;public BaseDaoImpl(ClassT domainClass, EntityManager entityManager) {super(domainClass, entityManager);this.entityManager entityManager;}public BaseDaoImpl(JpaEntityInformationT, Serializable information, EntityManager entityManager) {super(information, entityManager);this.entityManager entityManager;}Overridepublic S extends T S save(S entity) {entity.setModificationTimestamp(new Timestamp(System.currentTimeMillis()));return super.save(entity);}/*** 只做逻辑删除*/Overridepublic void delete(T entity) {entity.setDr(1);save(entity);}Overridepublic void delete(Serializable id) {T entity findOne(id);entity.setDr(1);this.save(entity);}} View Code RepositoryFactoryBean 实现 接下来我们来创建一个自定义的BaseDaoFactoryBean来代替默认的RepositoryFactoryBean。RepositoryFactoryBean负责返回一个RepositoryFactorySpring Data Jpa 将使用RepositoryFactory来创建Repository具体实现这里我们用BaseDaoImpl代替SimpleJpaRepository作为Repository接口的实现。这样我们就能够达到为所有Repository添加或修改自定义方法的目的。 import xxx.AbsIdEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;import javax.persistence.EntityManager;
import java.io.Serializable;public class BaseDaoFactoryBeanR extends JpaRepositoryT, Serializable, T extends AbsIdEntity extends JpaRepositoryFactoryBeanR, T, Serializable {Overrideprotected RepositoryFactorySupport createRepositoryFactory(final EntityManager entityManager) {return new JpaRepositoryFactory(entityManager) {protected SimpleJpaRepositoryT, Serializable getTargetRepository(RepositoryInformation information, EntityManager entityManager) {return new BaseDaoImpl((ClassT) information.getDomainType(), entityManager);}Overrideprotected Class? getRepositoryBaseClass(RepositoryMetadata metadata) {return BaseDaoImpl.class;}};}
} View Code jpa 配置文件 !-- Spring Data Jpa配置 --
jpa:repositories base-packagecom.xxxtransaction-manager-reftransactionManagerentity-manager-factory-refentityManagerFactoryfactory-classxxx.BaseDaoFactoryBean!-- 自定义RepositoryFactoryBean --
/jpa:repositories 三、改进之后 由于有的表没有默认父类AbsIdEntity对应的字段导致生成 Repository 在操作表的时候会报错。需要修改的就是RepositoryFactoryBean的实现逻辑。对于继承了AbsIdEntity的实体类返回自定义的BaseRepository也就是BaseDaoImpl否则就返回SimpleJpaRepository。注意自定义RepositoryFactoryBean的泛型也做了修改。 import xxx.AbsIdEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;import javax.persistence.EntityManager;
import java.io.Serializable;public class BaseDaoFactoryBeanR extends JpaRepositoryT, Serializable, T extends JpaRepositoryFactoryBeanR, T, Serializable {Overrideprotected RepositoryFactorySupport createRepositoryFactory(final EntityManager entityManager) {return new JpaRepositoryFactory(entityManager) {protected SimpleJpaRepositoryT, Serializable getTargetRepository(RepositoryInformation information, EntityManager entityManager) {ClassT domainClass (ClassT) information.getDomainType();if(AbsIdEntity.class.isAssignableFrom(domainClass)) {return new BaseDaoImpl(domainClass, entityManager);} else { return new SimpleJpaRepository(domainClass, entityManager);}}Overrideprotected Class? getRepositoryBaseClass(RepositoryMetadata metadata) {return metadata.getDomainType().isAssignableFrom(AbsIdEntity.class) ? BaseDaoImpl.class : SimpleJpaRepository.class;}};}
} View Code 至此完成了适配。 生活不止眼前的bug还有诗和远方。。。 转载于:https://www.cnblogs.com/hujunzheng/p/6494671.html