SpringBoot 整合ORM

SpringBoot整合ORM:
使用JPA规范:
源码分析:

public class SpringImplicitNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl {

	@Override
	public Identifier determineJoinTableName(ImplicitJoinTableNameSource source) {
		String name = source.getOwningPhysicalTableName() + "_"
				+ source.getAssociationOwningAttributePath().getProperty();
		return toIdentifier(name, source.getBuildingContext());
	}

}

JTA 事务:

public class SpringJtaPlatform extends AbstractJtaPlatform {

	private static final long serialVersionUID = 1L;

	private final JtaTransactionManager transactionManager;

	public SpringJtaPlatform(JtaTransactionManager transactionManager) {
		Assert.notNull(transactionManager, "TransactionManager must not be null");
		this.transactionManager = transactionManager;
	}

	@Override
	protected TransactionManager locateTransactionManager() {
		return this.transactionManager.getTransactionManager();
	}

	@Override
	protected UserTransaction locateUserTransaction() {
		return this.transactionManager.getUserTransaction();
	}

}

实体工厂的Enttity:

public class EntityManagerFactoryBuilder {

	private final JpaVendorAdapter jpaVendorAdapter;

	private final PersistenceUnitManager persistenceUnitManager;

	private final Map<String, Object> jpaProperties;

	private final URL persistenceUnitRootLocation;

	private AsyncTaskExecutor bootstrapExecutor;

	private PersistenceUnitPostProcessor[] persistenceUnitPostProcessors;

	/**
	 * Create a new instance passing in the common pieces that will be shared if multiple
	 * EntityManagerFactory instances are created.
	 * @param jpaVendorAdapter a vendor adapter
	 * @param jpaProperties the JPA properties to be passed to the persistence provider
	 * @param persistenceUnitManager optional source of persistence unit information (can
	 * be null)
	 */
	public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map<String, ?> jpaProperties,
			PersistenceUnitManager persistenceUnitManager) {
		this(jpaVendorAdapter, jpaProperties, persistenceUnitManager, null);
	}

	/**
	 * Create a new instance passing in the common pieces that will be shared if multiple
	 * EntityManagerFactory instances are created.
	 * @param jpaVendorAdapter a vendor adapter
	 * @param jpaProperties the JPA properties to be passed to the persistence provider
	 * @param persistenceUnitManager optional source of persistence unit information (can
	 * be null)
	 * @param persistenceUnitRootLocation the persistence unit root location to use as a
	 * fallback (can be null)
	 * @since 1.4.1
	 */
	public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, Map<String, ?> jpaProperties,
			PersistenceUnitManager persistenceUnitManager, URL persistenceUnitRootLocation) {
		this.jpaVendorAdapter = jpaVendorAdapter;
		this.persistenceUnitManager = persistenceUnitManager;
		this.jpaProperties = new LinkedHashMap<>(jpaProperties);
		this.persistenceUnitRootLocation = persistenceUnitRootLocation;
	}

	public Builder dataSource(DataSource dataSource) {
		return new Builder(dataSource);
	}

	/**
	 * Configure the bootstrap executor to be used by the
	 * {@link LocalContainerEntityManagerFactoryBean}.
	 * @param bootstrapExecutor the executor
	 * @since 2.1.0
	 */
	public void setBootstrapExecutor(AsyncTaskExecutor bootstrapExecutor) {
		this.bootstrapExecutor = bootstrapExecutor;
	}

	/**
	 * Set the {@linkplain PersistenceUnitPostProcessor persistence unit post processors}
	 * to be applied to the PersistenceUnitInfo used for creating the
	 * {@link LocalContainerEntityManagerFactoryBean}.
	 * @param persistenceUnitPostProcessors the persistence unit post processors to use
	 * @since 2.5.0
	 */
	public void setPersistenceUnitPostProcessors(PersistenceUnitPostProcessor... persistenceUnitPostProcessors) {
		this.persistenceUnitPostProcessors = persistenceUnitPostProcessors;
	}

	/**
	 * A fluent builder for a LocalContainerEntityManagerFactoryBean.
	 */
	public final class Builder {

		private DataSource dataSource;

		private PersistenceManagedTypes managedTypes;

		private String[] packagesToScan;

		private String persistenceUnit;

		private Map<String, Object> properties = new HashMap<>();

		private String[] mappingResources;

		private boolean jta;

		private Builder(DataSource dataSource) {
			this.dataSource = dataSource;
		}

		/**
		 * The persistence managed types, providing both the managed entities and packages
		 * the entity manager should consider.
		 * @param managedTypes managed types.
		 * @return the builder for fluent usage
		 */
		public Builder managedTypes(PersistenceManagedTypes managedTypes) {
			this.managedTypes = managedTypes;
			return this;
		}

		/**
		 * The names of packages to scan for {@code @Entity} annotations.
		 * @param packagesToScan packages to scan
		 * @return the builder for fluent usage
		 * @see #managedTypes(PersistenceManagedTypes)
		 */
		public Builder packages(String... packagesToScan) {
			this.packagesToScan = packagesToScan;
			return this;
		}

		/**
		 * The classes whose packages should be scanned for {@code @Entity} annotations.
		 * @param basePackageClasses the classes to use
		 * @return the builder for fluent usage
		 * @see #managedTypes(PersistenceManagedTypes)
		 */
		public Builder packages(Class<?>... basePackageClasses) {
			Set<String> packages = new HashSet<>();
			for (Class<?> type : basePackageClasses) {
				packages.add(ClassUtils.getPackageName(type));
			}
			this.packagesToScan = StringUtils.toStringArray(packages);
			return this;
		}

		/**
		 * The name of the persistence unit. If only building one EntityManagerFactory you
		 * can omit this, but if there are more than one in the same application you
		 * should give them distinct names.
		 * @param persistenceUnit the name of the persistence unit
		 * @return the builder for fluent usage
		 */
		public Builder persistenceUnit(String persistenceUnit) {
			this.persistenceUnit = persistenceUnit;
			return this;
		}

		/**
		 * Generic properties for standard JPA or vendor-specific configuration. These
		 * properties override any values provided in the constructor.
		 * @param properties the properties to use
		 * @return the builder for fluent usage
		 */
		public Builder properties(Map<String, ?> properties) {
			this.properties.putAll(properties);
			return this;
		}

		/**
		 * The mapping resources (equivalent to {@code <mapping-file>} entries in
		 * {@code persistence.xml}) for the persistence unit.
		 * <p>
		 * Note that mapping resources must be relative to the classpath root, e.g.
		 * "META-INF/mappings.xml" or "com/mycompany/repository/mappings.xml", so that
		 * they can be loaded through {@code ClassLoader.getResource()}.
		 * @param mappingResources the mapping resources to use
		 * @return the builder for fluent usage
		 */
		public Builder mappingResources(String... mappingResources) {
			this.mappingResources = mappingResources;
			return this;
		}

		/**
		 * Configure if using a JTA {@link DataSource}, i.e. if
		 * {@link LocalContainerEntityManagerFactoryBean#setDataSource(DataSource)
		 * setDataSource} or
		 * {@link LocalContainerEntityManagerFactoryBean#setJtaDataSource(DataSource)
		 * setJtaDataSource} should be called on the
		 * {@link LocalContainerEntityManagerFactoryBean}.
		 * @param jta if the data source is JTA
		 * @return the builder for fluent usage
		 */
		public Builder jta(boolean jta) {
			this.jta = jta;
			return this;
		}

		public LocalContainerEntityManagerFactoryBean build() {
			LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
			if (EntityManagerFactoryBuilder.this.persistenceUnitManager != null) {
				entityManagerFactoryBean
						.setPersistenceUnitManager(EntityManagerFactoryBuilder.this.persistenceUnitManager);
			}
			if (this.persistenceUnit != null) {
				entityManagerFactoryBean.setPersistenceUnitName(this.persistenceUnit);
			}
			entityManagerFactoryBean.setJpaVendorAdapter(EntityManagerFactoryBuilder.this.jpaVendorAdapter);

			if (this.jta) {
				entityManagerFactoryBean.setJtaDataSource(this.dataSource);
			}
			else {
				entityManagerFactoryBean.setDataSource(this.dataSource);
			}
			if (this.managedTypes != null) {
				entityManagerFactoryBean.setManagedTypes(this.managedTypes);
			}
			else {
				entityManagerFactoryBean.setPackagesToScan(this.packagesToScan);
			}
			entityManagerFactoryBean.getJpaPropertyMap().putAll(EntityManagerFactoryBuilder.this.jpaProperties);
			entityManagerFactoryBean.getJpaPropertyMap().putAll(this.properties);
			if (!ObjectUtils.isEmpty(this.mappingResources)) {
				entityManagerFactoryBean.setMappingResources(this.mappingResources);
			}
			URL rootLocation = EntityManagerFactoryBuilder.this.persistenceUnitRootLocation;
			if (rootLocation != null) {
				entityManagerFactoryBean.setPersistenceUnitRootLocation(rootLocation.toString());
			}
			if (EntityManagerFactoryBuilder.this.bootstrapExecutor != null) {
				entityManagerFactoryBean.setBootstrapExecutor(EntityManagerFactoryBuilder.this.bootstrapExecutor);
			}
			if (EntityManagerFactoryBuilder.this.persistenceUnitPostProcessors != null) {
				entityManagerFactoryBean.setPersistenceUnitPostProcessors(
						EntityManagerFactoryBuilder.this.persistenceUnitPostProcessors);
			}
			return entityManagerFactoryBean;
		}

	}

}

JpaDatabaseInitializerDetector:

class JpaDatabaseInitializerDetector extends AbstractBeansOfTypeDatabaseInitializerDetector {

	private final Environment environment;

	JpaDatabaseInitializerDetector(Environment environment) {
		this.environment = environment;
	}

	@Override
	protected Set<Class<?>> getDatabaseInitializerBeanTypes() {
		boolean deferred = this.environment.getProperty("spring.jpa.defer-datasource-initialization", boolean.class,
				false);
		return deferred ? Collections.singleton(EntityManagerFactory.class) : Collections.emptySet();
	}

	@Override
	public void detectionComplete(ConfigurableListableBeanFactory beanFactory, Set<String> dataSourceInitializerNames) {
		configureOtherInitializersToDependOnJpaInitializers(beanFactory, dataSourceInitializerNames);
	}

	private void configureOtherInitializersToDependOnJpaInitializers(ConfigurableListableBeanFactory beanFactory,
			Set<String> dataSourceInitializerNames) {
		Set<String> jpaInitializers = new HashSet<>();
		Set<String> otherInitializers = new HashSet<>(dataSourceInitializerNames);
		Iterator<String> iterator = otherInitializers.iterator();
		while (iterator.hasNext()) {
			String initializerName = iterator.next();
			BeanDefinition initializerDefinition = beanFactory.getBeanDefinition(initializerName);
			if (JpaDatabaseInitializerDetector.class.getName()
					.equals(initializerDefinition.getAttribute(DatabaseInitializerDetector.class.getName()))) {
				iterator.remove();
				jpaInitializers.add(initializerName);
			}
		}
		for (String otherInitializerName : otherInitializers) {
			BeanDefinition definition = beanFactory.getBeanDefinition(otherInitializerName);
			String[] dependencies = definition.getDependsOn();
			for (String dependencyName : jpaInitializers) {
				dependencies = StringUtils.addStringToArray(dependencies, dependencyName);
			}
			definition.setDependsOn(dependencies);
		}
	}

}

 */
class JpaDependsOnDatabaseInitializationDetector extends AbstractBeansOfTypeDependsOnDatabaseInitializationDetector {

	private final Environment environment;

	JpaDependsOnDatabaseInitializationDetector(Environment environment) {
		this.environment = environment;
	}

	@Override
	protected Set<Class<?>> getDependsOnDatabaseInitializationBeanTypes() {
		boolean postpone = this.environment.getProperty("spring.jpa.defer-datasource-initialization", boolean.class,
				false);
		return postpone ? Collections.emptySet()
				: new HashSet<>(Arrays.asList(EntityManagerFactory.class, AbstractEntityManagerFactoryBean.class));
	}

}

JPA–Java 持久层 API:
Spring Data 是 Spring 的一个子项目,旨在统一和简化各类型数据的持久化存储方式,而不拘泥于是关系型数据库还是NoSQL数据库。

无论是哪种持久化存储方式,DAO(Data Access Objects,数据访问对象) 都会提供对对象的增加、删除、修饰和查询的方法,以及排序和分页方法等。
Spring Data 提供了基于这些层面的统一接口(如:CrudRepository、PageingAndSortingRepository),以实现持久化的存储。

使用:使用 JPA:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL 数据库 依赖 -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <scope>runtime</scope>
</dependency>

2.配置数据库连接信息
3.hibernate的配置属性参数值列表:
none : 启动时不做任何操作。默认值,什么都不做,每次启动项目,不会对数据库进行任何验证和操作。
create :每次加载 Hibernate 时都会删除上一次生成的表,然后根据 Model 类再重新生成新表,哪怕没有任何改变也会这样执行,这会导致数据库数据的丢失。(每次加载 Hibernate,重新创建数据库表结构)
create-drop :每次加载 Hibernate 时会根据 Model 类生成表,但是 sessionFactory 一旦关闭,表就会自动被删除。(加载 Hibernate 时创建,退出是删除表结构)
update :最常用的属性。第一次加载 Hibernate 时会根据 Model 类自动建立表的结构(前提是先建立好数据库)。以后加载 Hibernate 时,会根据 Model 类自动更新表结构,即使表结构改变了,但表中的数据仍然存在,不会被删除。要注意的是,当部署到服务器后,表结构是不会被马上建立起来的,要等应用程序第一次运行起来后才会建立。update 表示如果 Entity 实体的字段发生了变化,那么直接在数据库中进行更新。(加载 Hibernate 时自动更新数据库结构)
validate :每次加载 Hibernate 时,会验证数据库的表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。(加载 Hibernate 时,验证创建数据库表结构)

JPA 的常用注解:
@Entity :标识实体类是JPA实体,告诉JPA在程序运行时生成实体类对应表

@Table :设置实体类在数据库所对应的表名
@Id :标识类里所在变量为主键
@GeneratedValue :设置主键生成策略,此方式依赖于具体的数据库
@Column :表示属性所对应字段名进行个性化设置
@Transient :表示属性并非数据库表字段的映射,ORM框架将忽略该属性
@CreatedDate :表示字段为创建时间字段(insert自动设置)
@CreatedBy :表示字段为创建用户字段(insert自动设置),通过实现 “AuditorAware” 接口的 “getCurrentAuditor” 方法来实现赋值。

懒加载 LAZY 和 实时加载 EAGER:

懒加载 LAZY 和 实时加载 EAGER 的目的是,实现关联数据的选择性加载。
懒加载是在属性被引用时才生成查询语句,抽取相关数据。
实时加载则是执行完主查询后,不管是否被引用,都会马上执行后续的关联数据查询
使用懒加载来调用关联数据,必须要保证主查询的 session(数据库连接会话)的生命周期没有结束,否则无法抽取到数据的。

映射关系注解:

@JoinColumn :指定一个实体组织或实体集合。用在“多对一”和“一对多”的关联中。
@OneToOne :定义表之间“一对一”的关系
@OneToMany :定义表之间“一对多”的关系
@ManyToOne :定义表之间“多对一”的关系
@ManyToMany :定义表之间“多对多”的关系
————————————————
认识 JPA 的接口
JPA 提供了操作数据库的接口。在开发过程中继承和使用这些接口,可简化现有的持久化开发工作。

JPA 接口 JpaRepository

JpaRepository 继承自 PaingAndSortingRepository 。该接口提供了 JPA 的相关实用功能,以及通过 Example 进行查询的功能。 Example 对象是 JPA 提供用来构造查询条件的对象。

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>,
QueryByExampleExecutor {
}
1
2
3
4
在上述代码中, T 表示实体对象, ID 表示主键。 ID 必须实现序列化。

分页排序接口 PagingAndSortingRepository

PagingAndSortingRepository 继承自 CrudRepository 提供的分页和排序方法。

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable findAll(Sort var1);

Page<T> findAll(Pageable var1);

}
1
2
3
4
5
findAll(Sort sort) :排序功能。它按照 “sort” 制定的排序返回数据。
Page findAll(Pageable pageable) :分页查询(含排序功能)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执于代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值