• 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()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    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());
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

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

    schema相关

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

    sessionFactory.getSchemaManager().exportMappedObjects(true);

    public interface SchemaManager {
    	/**
    	 * Export database objects mapped by Hibernate entities.
    	 * 

    * 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}. *

    * 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. *

    * 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}. *

    * Programmatic way to run {@link org.hibernate.tool.schema.spi.SchemaTruncator}. */ void truncateMappedObjects(); }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    另一个与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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    如果做代码跟踪,就会发现是否使用默认的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://10.110.87.204: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", "liugeba?68");
            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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

  • 相关阅读:
    sql调优
    JVM的类加载过程
    lora训练之偷师
    为什么有的人把代码写的如此复杂?
    如何用golang写一个自己的后端框架
    Puppeteer实战指南:自动化抓取网页中的图片资源
    闲人闲谈PS之三十六——项目状态控制
    LeetCode 152. 乘积最大子数组
    ant design vue 实现组件类型推断 vue3,vite,ts
    Django 做migrations时出错,解决方案
  • 原文地址:https://blog.csdn.net/u013257767/article/details/134066591