写点什么

原创 | 使用 JPA 实现 DDD 持久化 - 数据库连接配置:persistence.xml

发布于: 2020 年 11 月 25 日
原创 | 使用JPA实现DDD持久化-数据库连接配置:persistence.xml



第二节 数据库连接配置:persistence.xml

为了通过JPA将领域对象的状态持久化到数据库,必须告知JPA数据库的类型、位置、账号访问等相关信息。根据JPA规范,这些信息应该定义在类路径下的META-INF/persistence.xml文件中。在maven项目中,应该在包含持久化类的tmall-domain模块的main/resources/META-INF目录下创建persistence.xml文件。

Java SE环境下典型的persistence.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"             version="2.2">
<persistence-unit name="default" transaction-type="RESOURCE_LOCAL"> <description> Hibernate JPA Configuration Example</description> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/> <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:tmall;DB_CLOSE_DELAY=-1"/> <property name="javax.persistence.jdbc.user" value="sa"/> <property name="javax.persistence.jdbc.password" value=""/> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/> </properties> </persistence-unit></persistence>
复制代码

Java EE环境下典型的persistence.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?><persistence        version="2.2"        xmlns="http://xmlns.jcp.org/xml/ns/persistence"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence                            http://xmlns.jcp.org/xml/ns/persistence_2_2.xsd">    <persistence-unit name="default" transaction-type="JTA">        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>        <jta-data-source>jdbc/testDS</jta-data-source>        <properties>            <property name="hibernate.show_sql" value="true" />            <property name="hibernate.hbm2ddl.auto" value="update" />            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>        </properties>    </persistence-unit></persistence>
复制代码

一、根节点 persistence

persistence根节点定义所采用的JPA规范的版本。目前最新的JPA规范版本是2.2

二、持久化单元节点 persistence-unit

在根节点persistence下可以创建多个持久化单元persistence-unit。绝大多数情况下项目中都只有一个持久化单元。

每个persistence-unit节点定义一个持久化单元。一个持久化单元代表到一个数据库的连接和映射。

persistence-unit节点有两个属性:

  • name属性:持久化单元的名称。这个名称必须在整个系统内是唯一的。后续通过JPA API访问数据库时必须提供相应的持久化单元的名称。

  • transaction-type属性:指定持久化单元采用的事务类型。有两个可用选项:RESOURCE_LOCAL:适用于Java SE环境。由应用代码负责创建和管理数据库事务。JTA:适用于Java EE环境。由应用服务器(例如WebSphereJBoss等。如今已经几乎绝迹)创建和管理事务。需要在应用服务器上创建连接到数据库的数据源,并以JNDI名称的形式暴露给JPA。在Java SE环境中,如果需要跨越多个事务资源(例如数据库、JMS服务等)的事务,那么也需要使用JTA事务类型。Servlet容器(如TomcatJetty等)一般不直接支持JTA事务,这时可以采用Bitronix BTM等第三方类库帮助实现JTA事务。

persistence-unit节点下还定义了以下的子节点:

  • provider节点:指定持久化提供者实现类。本范例项目使用的是hibernateJPA持久化提供者实现类HibernatePersistenceProvider

  • description节点:可选的持久化单元描述。

  • jta-data-source节点:持久化单元使用的JTA数据源,指向容器提供的JTA数据源的JNDI路径。持久化单元transaction-type的属性值是JTA时采用。

  • non-jta-data-source属性:持久化单元使用的非JTA数据源,指向容器提供的JTA数据源的JNDI路径。持久化单元transaction-type属性值是RESOURCE_LOCAL时采用。

jta-data-sourcenon-jta-data-source都是采用容器提供的数据源进行持久化。在Java SE环境下,也可以不采用容器提供的数据源,而采用下文中的几个JPA标准属性定义数据库连接信息。

三、持久化单元属性集节点 properties

持久化单元节点persistence-unitproperties子节点下通过若干个property下级节点定义一批持久化相关属性。这些属性可分为两类:名字以javax.persistence开头的JPA标准属性,以及不以javax.persistence开头的扩展属性,包括持久化框架特定的属性、数据库连接池相关属性、缓存相关属性等等。

名字以javax.persistence开头的属性是JPA定义的标准属性:

  • javax.persistence.jdbc.driver属性:定义所使用的数据库驱动类。

  • javax.persistence.jdbc.url属性:定义所使用数据库的JDBC url

  • javax.persistence.jdbc.user属性:定义访问数据库的用户名。

  • javax.persistence.jdbc.password属性:定义访问数据库的用户口令。

以上四个属性指定数据库连接基本信息。如果已经通过jta-data-source节点指定了容器提供的JTA数据源,或通过none-jta-data-source节点指定了容器提供的非JTA数据源,则无需定义这几个数据库连接属性。

名字以hibernate开头的属性是JPA实现框架Hibernate定义的扩展属性:

  • hibernate.show_sql属性:如果设置为true,将在运行时在后台打印Hibernate生成的SQL语句。

  • hibernate.hbm2ddl.auto属性:定义每次加载hibernate时是否创建或更新数据库结构。有以下几个选项(一般建议:在开发和测试时设置为update(如果在测试之间要保留之前创建的数据)或create(如果不想保留历史数据,每次测试从 0 开始),而在生产环境中设置为none以防止每次启动时误删生产数据):create:每次加载hibernate时都会删除上一次的生成的表,然后根据映射元数据重新生成表。相当于drop-createcreate-drop:每次加载hibernate时根据映射元数据生成表,但是sessionFactory一关闭,表就自动删除。update:最常用的属性。第一次加载hibernate时根据映射元数据自动建立起表的结构(前提是先建立好数据库),以后每次加载hibernate时映射元数据的变化(例如创建了新的持久化类、修改了现有的持久化类、修改了映射元数据等)自动更新表结构,但是仍然会保留原有的数据行。validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。none:任何时候加载hibernate时,都不会自动创建或修改表结构,也不会删除表。

  • hibernate.dialect属性:定义了进行O/R映射时生成的数据库方言。因为JPA/Hibernate支持面向多种数据库的持久化,而SQL虽然有了标准,但每种数据库都可能只是部分遵从SQL标准,除此之外,它们还可能拥有一些特有的SQL语法。指定了数据库方言之后,hibernate就知道如何将面向对象的对象查询语言(JPQL)翻译转换为特定数据库的SQL方言。

还有很多其他的标准属性和扩展属性,那些属性会在本教程的第三部分详细论述。

将持久化类(实体、值对象等)和persistence.xml打包到一个jar中,这个jar就成为持久化存档文件。可以部署到应用服务器和Java Web服务器上,或者打包到企业应用存档文件中。


详细内容请戳这里↓↓↓


原创 | 使用JPA实现DDD持久化-数据库连接配置:persistence.xml


这一节就讲到这里,下一节我们讲"领域模型:对象的世界"


如果觉得有收获,点个【赞】鼓励一下呗!



发布于: 2020 年 11 月 25 日阅读数: 49
用户头像

高级架构师,技术顾问,交流公号:编程道与术 2020.04.28 加入

杨宇于2020年创立编程道与术,致力于研究领域分析与建模、测试驱动开发、架构设计、自动化构建和持续集成、敏捷开发方法论、微服务、云计算等顶尖技术领域。 了解更多公众号:编程道与术

评论

发布
暂无评论
原创 | 使用JPA实现DDD持久化-数据库连接配置:persistence.xml