hibernate源码(1)--- schema创建

sessionFactory

配置项:
image.png
hibernate的核心是sessionFactory,那我们看看如何构建session Factory。
参考官网:

plugins {
    id("java")
}
group = "com.atai.hibernatespy"
version = "1.0-SNAPSHOT"
repositories {
    mavenCentral()
}
dependencies {
    // the GOAT ORM
    implementation("org.hibernate.orm:hibernate-core:6.3.0.Final")
    // Hibernate Validator)
    implementation("org.hibernate.validator:hibernate-validator:8.0.0.Final")
    implementation("org.glassfish:jakarta.el:4.0.2")
    // Agroal connection pool)
    implementation("org.hibernate.orm:hibernate-agroal:6.3.0.Final")
    implementation("io.agroal:agroal-pool:2.1")
    // logging via Log4j)
    implementation("org.apache.logging.log4j:log4j-core:2.20.0")
    //JPA Metamodel Generator)
    annotationProcessor("org.hibernate.orm:hibernate-jpamodelgen:6.3.0.Final")
    runtimeOnly("com.h2database:h2:2.1.214")
// Compile-time checking for HQL
    //implementation 'org.hibernate : query-validator: 2.O-SNAPSHOT'//annotationProcessor 'org.hibernate: query-validator: 2.O-SNAPSHOT'
// H2 database
//    runtimeonly( 'com.h2database:h2:2.1.214')
    testImplementation(platform("org.junit:junit-bom:5.9.1"))
    testImplementation("org.junit.jupiter:junit-jupiter")
}
tasks.test {
    useJUnitPlatform()
}
package org.example;

import com.atai.entity.Book;
import org.hibernate.cfg.Configuration;

import static java.lang.Boolean.TRUE;
import static java.lang.System.out;
import static org.hibernate.cfg.JdbcSettings.*;
import static org.hibernate.cfg.JdbcSettings.HIGHLIGHT_SQL;

public class Main {
    public static void main(String[] args) {
        var sessionFactory = new Configuration()
                .addAnnotatedClass(Book.class)
                .setProperty(URL, "jdbc:h2:mem:db1")
                .setProperty(USER, "sa")
                .setProperty(PASS, "")
                // use Agroal connection pool
                .setProperty("hibernate.agroal.maxSize", "20")//display sQL in console
                .setProperty(SHOW_SQL, TRUE.toString())
                .setProperty(FORMAT_SQL, TRUE.toString())
                .setProperty(HIGHLIGHT_SQL, TRUE.toString()).buildSessionFactory();
        // export the inferred database schema
        sessionFactory.getSchemaManager().exportMappedObjects(true);
        // persist an entity
        sessionFactory.inTransaction(session -> {
            session.persist(new Book("9781932394153", "Hibernate in Action"));
        });
        // query data using HQL
        sessionFactory.inSession(session -> {
            out.println(session.createSelectionQuery(" select isbn||': '||title from Book").getSingleResult());
        });
        // query data using criteria API
        sessionFactory.inSession(session -> {
            var builder = sessionFactory.getCriteriaBuilder();
            var query = builder.createQuery(String.class);
            var book = query.from(Book.class);
            query.select(builder.concat(builder.concat(book.get("isbn"), builder.literal(": ")), book.get("title")));
            out.println(session.createSelectionQuery(query).getSingleResult());
        });
    }
}

可以通过Configuration来进行创建,参数配置在property中,buildSessionFactory() 创建出sf。
有了sf,即可以连接数据库处理。

schema相关

前面的例子中,已经有了比较好的实例,通过sf的schemaManager创建:

sessionFactory.getSchemaManager().exportMappedObjects(true);

public interface SchemaManager {
	/**
	 * Export database objects mapped by Hibernate entities.
	 * <p>
	 * Programmatic way to run {@link org.hibernate.tool.schema.spi.SchemaCreator}.
	 *
	 * @param createSchemas if {@code true}, attempt to create schemas,
	 *                      otherwise, assume the schemas already exist
	 */
	void exportMappedObjects(boolean createSchemas);

	/**
	 * Drop database objects mapped by Hibernate entities, undoing the
	 * {@linkplain #exportMappedObjects(boolean) previous export}.
	 * <p>
	 * Programmatic way to run {@link org.hibernate.tool.schema.spi.SchemaDropper}.
	 *
	 * @param dropSchemas if {@code true}, drop schemas,
	 *                    otherwise, leave them be
	 */
	void dropMappedObjects(boolean dropSchemas);

	/**
	 * Validate that the database objects mapped by Hibernate entities
	 * have the expected definitions.
	 * <p>
	 * Programmatic way to run {@link org.hibernate.tool.schema.spi.SchemaValidator}.
	 */
	void validateMappedObjects();

	/**
	 * Truncate the database tables mapped by Hibernate entities, and
	 * then re-import initial data from any configured
	 * {@linkplain org.hibernate.cfg.AvailableSettings#JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE
	 * load script}.
	 * <p>
	 * Programmatic way to run {@link org.hibernate.tool.schema.spi.SchemaTruncator}.
	 */
	void truncateMappedObjects();
}

另一个与schema关系较大的类就是:SchemaManagementToolCoordinator

   List<Class> classes = Arrays.asList(AccessconfigEntity.class);
                Properties p = new Properties();
                // 数据库方言,最终输出的方言
                p.put(AvailableSettings.DIALECT, MySQL5InnoDBDialect.class.getName());
                // 自动执行的动作
                p.put(AvailableSettings.HBM2DDL_AUTO, ddlAuto);
                // 分隔符,默认为空
                p.put(AvailableSettings.HBM2DDL_DELIMITER, ";");
                // 是否展示SQL
                p.put(AvailableSettings.SHOW_SQL, true);
                p.put("hibernate.connection.driver_class", dataSource.getDriverClassName());
                p.put("hibernate.connection.url", urlTena);
                p.put("hibernate.connection.username", dataSource.getUsername());
                p.put("hibernate.connection.password", dataSource.getPassword());
                // 是否使用默认的jdbc元数据,默认为true,读取项目自身的元数据
                p.put("hibernate.temp.use_jdbc_metadata_defaults", true);
//                p.put("hibernate.temp.use_jdbc_metadata_defaults", false);
                ConfigurationHelper.resolvePlaceHolders(p);
                ServiceRegistry registry = new StandardServiceRegistryBuilder()
                        .applySettings(p)
                        .build();
//                registry.get
                Map settings = registry.getService(ConfigurationService.class).getSettings();
                MetadataSources metadataSources = new MetadataSources(registry);
                entities.forEach(new Consumer<EntityType<?>>() {
                    @Override
                    public void accept(EntityType<?> entityType) {
                        metadataSources.addAnnotatedClass(entityType.getJavaType());
                    }
                });
                classes.forEach(metadataSources::addAnnotatedClass);
                Metadata metadata = metadataSources.buildMetadata();
                HashMap properties = new HashMap<>();
                properties.putAll(registry.getService(ConfigurationService.class).getSettings());
                SchemaManagementToolCoordinator.process(metadata, registry, settings, null);

如果做代码跟踪,就会发现是否使用默认的use_jdbc_metadata_defaults 配置项将会建立连接,获取数据库的表信息。

SchemaExport

schemaexport是另一个与schema相关的类,可以控制台输出,脚本文件输出与数据库创建:

        Configuration cfn = new Configuration();
        cfn.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
        cfn.setProperty("hibernate.connection.url", "jdbc:mysql://ip:3306/corps?useOldAliasMetadataBehavior=true&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false&nullCatalogMeansCurrent=true");
        cfn.setProperty("hibernate.connection.username", "root");
        cfn.setProperty("hibernate.connection.password", "pwd");
        cfn.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        cfn.configure();
        ServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(cfn.getProperties()).build();
//        System.out.println(cfn.toString());
//
//        ServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
//        registry.
        Metadata metadata = new MetadataSources(registry).buildMetadata();
        SchemaExport export = new SchemaExport();
        export.create(EnumSet.of(TargetType.DATABASE), metadata);

实际操作的也就是下面的几个类:
image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XML Schema实例文档中的元素是基于XML Schema定义的。XML Schema定义了文档中哪些元素是有效的,以及它们可以包含哪些属性和子元素。在XML实例文档中,可以使用XML命名空间来引用XML Schema定义,以确保文档符合所定义的模式。 要创建一个符合XML Schema定义的XML实例文档,可以按照以下步骤进行操作: 1. 创建一个包含根元素的XML文档。根元素的名称和命名空间必须与XML Schema定义中的定义匹配。 2. 在根元素的开头添加一个包含xmlns:xsi属性的命名空间声明。xsi是XML Schema实例命名空间的缩写。 3. 在根元素的开头添加一个包含xsi:schemaLocation属性的命名空间声明。xsi:schemaLocation属性的值是一个空格分隔的XML Schema命名空间和模式文件URI的列表。 4. 在文档中使用符合模式的元素、属性和值创建其他元素。 例如,以下是一个符合XML Schema定义的XML实例文档的示例: ``` <?xml version="1.0" encoding="UTF-8"?> <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.com/myschema myschema.xsd"> <element1>value1</element1> <element2 attribute1="value2">value3</element2> </root> ``` 在这个例子中,root元素使用了xsi和xsi:schemaLocation命名空间声明,指定了XML Schema定义的命名空间和模式文件URI。element1和element2元素符合XML Schema定义中定义的元素,而attribute1和它们的值符合XML Schema定义中定义的属性和值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值