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

sessionFactory

配置项:

hibernate的核心是sessionFactory,那我们看看如何构建session Factory。

参考官网:

java 复制代码
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()
}
java 复制代码
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);

java 复制代码
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

java 复制代码
   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相关的类,可以控制台输出,脚本文件输出与数据库创建:

java 复制代码
        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);

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

相关推荐
CodeSheep18 分钟前
Stack Overflow,轰然倒下了!
前端·后端·程序员
GoGeekBaird27 分钟前
GoHumanLoopHub开源上线,开启Agent人际协作新方式
人工智能·后端·github
水痕011 小时前
gin结合minio来做文件存储
java·eureka·gin
Victor3561 小时前
Redis(8)如何安装Redis?
后端
寒士obj1 小时前
Spring事物
java·spring
Victor3561 小时前
Redis(9)如何启动和停止Redis服务?
后端
柯南二号2 小时前
【Java后端】Spring Boot 集成 MyBatis-Plus 全攻略
java·spring boot·mybatis
程序员爱钓鱼3 小时前
Go语言实战案例-创建模型并自动迁移
后端·google·go
javachen__3 小时前
SpringBoot整合P6Spy实现全链路SQL监控
spring boot·后端·sql