sessionFactory
配置项:
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://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);
实际操作的也就是下面的几个类: