如果使用maven管理,则需要在pom.xml中配置hibernate,代码如下
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifacted> <version>5.2.10.Final</version> </dependency>
如果要使用c3p0数据库连接池,则需要在pom.xml中添加代码:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.2.10.Final</version> </dependency>
若将hibernate.cfg.cml和*.hbm.xml文件放在sec/main/resources文件夹中,则需要在pom.xml中配置代码:
<build> <testResources> <testResource> <filtering>false</filtering> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </testResource> <testResource> <directory>src/main/resources</directory> </testResource> </testResources> </build>
比如这里有三个类,学校类(School),班级类(Classes)和学生类(School),他们的关系是学校包含多个班级,班级有学校的引用,班级包含多个学生,学生有班级的引用,每个类的信息如下Getter和Setter方法省略
学校类:public class School implements Serializable { /** * */ private static final long serialVersionUID = -2535601535222481695L; private String id; private String name; private Set<Classes> stClass; public School() { stClass = new HashSet<Classes>(); } public School(String name) { this.name = name; stClass = new HashSet<Classes>(); } public School(String id, String name, Set<Classes> stClass) { this.id = id; this.name = name; this.stClass = stClass; } }
班级类:
public class Classes implements Serializable{ private Static final long serialVersionUID = ??; private String id; private School school; private String name; private Set<Student> students; public Classes(String id, School school, String name, Set<Student> students){ this.id = id; this.school = school; this.name = name; this.students = students; } }
学生类(Student):
public class Student implements Serializable{ private static final long serialVersionUID=??; private String id; private Classes classes; private String name; public Student(String id, Classes classes, String name){ this.id = id; this.classes = classes; this.name = name; } }
hibernate.cfg.xml文件的配置信息
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/testmy?useSSL=true&serverTimezone=UTC</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="c3p0.min_size">5</property> <!--在连接池中可用数据库连接的最小数目--> <property name="c3p0.max_size">30</property> <!--在连接池中所有数据库连接的最大数目--> <property name="c3p0.time_out">1800</property> <!--设定数据库连接的超时时间--> <property name="c3p0.max_statement">50</property> <!--可以被缓存的PreparedStatement的最大数目--> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> <mapping resource="com/bairock/test/main/School.hbm.xml" /> <mapping resource="com/bairock/test/main/Classes.hbm.xml" /> <mapping resource="com/bairock/test/main/Student.hbm.xml" /> </session-factory> </hibernate-configuration>
几个重要配置说明:
1).connection.driver_class
为连接数据库的驱动程序,老版的mysql为com.mysql.jdbc.Driver
,新版本改为com.mysql.cj.jdbc.Driver
2).connection.url
为数据库的路径,localhost:3306
为数据库的ip地址和端口号,testmy
为数据库的名称,
useSSL
为是否启用SSL检查,不配置此项会报异常:Establishing SSL connection without server's identity verification is not recommended...
serverTimezone=UTC
为配置时区,不配置的话会报错:The server time zone value '??' is unrecognized or represents more than one time zone...
,需要注意的是此项配置与其前面的配置要用&分割。学校类的映射文件School.hbm.xml代码
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.bairock.test.main"> <class name="School" table="school"> <id name="id" column="school_id" type="string"> <generator class="uuid2"/> </id> <property name="name" /> <set name="stClass" table="classes" inverse="true" cascade="all" lazy="true"> <key column="school_id"></key> <one-to-many class="Classes" /> </set> </class> </hibernate-mapping>
说明:
1). id为主键,name为School类中的id属性,column为表中的列名,generator为主键生成策略,这里使用uuid2策略,使用这种方式的原因是服务器端和客户端都可能生成主键,客户端可能离线使用,那么当客户端生成主键后,上传到服务器端可能会导致主键重复,使用uuid可以避免这种情况。hibernate之前的版本有uuid.hex和uuid.string两种策略,新版本中去掉了uuid.string,并且uuid.hex可以用uuid2替代。
2). set标签为School中的Set<Classes>
集合,inverse属性表示将控制权交给Classes对象,防止更新School数据表信息时也更新所有的Classes数据表,如果设置为false可能会出现异常;key标识classes表的外键,它对应到了school表的主键school_id
;one-to-many
说明了School和Classes为一对多的关系,响应的在Classes.hbm.xml
中要配置many-to-one
标签班级类的映射文件Classes.hbm.xml代码
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.bairock.test.main"> <class name="Classes" table="classes"> <id name="id" column="classes_id"> <generator class="uuid2" /> </id> <property name="name" /> <many-to-one name="school" column="school_id" class="School" cascade="none" outer-join="true" insert="true" access="property" not-null="true"> </many-to-one> <set name="students" table="student" inverse="true" cascade="all" lazy="true"> <key column="classes_id"></key> <one-to-many class="Student" /> </set> </class> </hibernate-mapping>
说明,前面一介绍过的省略:
many-to-one
对应了School.hbm.xml中的set
标签的one-to-many
,name为Classes类中的school属性。学生类的映射文件Student.hbm.xml代码
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.bairock.test.main"> <class name="Student" table="student"> <id name="id" column="student_id"> <generator class="uuid2" /> </id> <many-to-one name="classes" column="classes_id" class="Classes" cascade="none" outer-join="true" insert="true" access="property" not-null="true"> </many-to-one> <property name="name" /> </class> </hibernate-mapping>
需要注意的是三个类的id类型是String,而不是UUID,否则将出现转换错误
测试代码
public class ClassesTest { private SessionFactory sessionFactory; @Before public void setUp() throws Exception { // A SessionFactory is set up once for an application! final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build(); try { sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory(); } catch (Exception e) { // The registry would be destroyed by the SessionFactory, but we had // trouble building the SessionFactory // so destroy it manually. e.printStackTrace(); StandardServiceRegistryBuilder.destroy(registry); } } @After public void tearDown() throws Exception { if (sessionFactory != null) { sessionFactory.close(); } } @SuppressWarnings("unchecked") @Test public void test() { // create a couple of events... Session session = sessionFactory.openSession(); session.beginTransaction(); School school = new School("huaihai"); // school.setId(UUID.randomUUID().toString()); Classes classes = new Classes("class1"); // classes.setId(UUID.randomUUID().toString()); Student s = new Student("jack"); // s.setId(UUID.randomUUID().toString()); s.setClasses(classes); classes.getStudents().add(s); classes.setSchool(school); school.getStClass().add(classes); session.save(school); session.getTransaction().commit(); session.close(); // now lets pull events from the database and list them session = sessionFactory.openSession(); session.beginTransaction(); List<?> result = session.createQuery("from School").list(); for (School sch : (List<School>) result) { System.out.println("School (" + sch.getName() + ") : "); //List<?> listClasses = session.createQuery("from Classes where school").list(); for (Classes c : sch.getStClass()) { System.out.println("clazz (" + c.getName() + ") : "); for (Student ss : c.getStudents()) { System.out.println("student (" + ss.getName() + ") : "); } } } session.getTransaction().commit(); session.close(); } }
运行结果
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect Hibernate: drop table if exists classes 六月 21, 2017 8:39:01 下午 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@1abf088] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. Hibernate: drop table if exists school Hibernate: drop table if exists student Hibernate: create table classes (classes_id varchar(255) not null, name varchar(255), school_id varchar(255) not null, primary key (classes_id)) engine=MyISAM 六月 21, 2017 8:39:01 下午 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@74a051] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. Hibernate: create table school (school_id varchar(255) not null, name varchar(255), primary key (school_id)) engine=MyISAM Hibernate: create table student (student_id varchar(255) not null, classes_id varchar(255) not null, name varchar(255), primary key (student_id)) engine=MyISAM Hibernate: alter table classes add constraint FKpmbjltak5i0knqcgyydru2f18 foreign key (school_id) references school (school_id) Hibernate: alter table student add constraint FK4l5dnicegnvpmu0pv6vdvrmb6 foreign key (classes_id) references classes (classes_id) 六月 21, 2017 8:39:01 下午 org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources INFO: HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@dce7ed' Hibernate: insert into school (name, school_id) values (?, ?) Hibernate: insert into classes (name, school_id, classes_id) values (?, ?, ?) Hibernate: insert into student (classes_id, name, student_id) values (?, ?, ?) 六月 21, 2017 8:39:01 下午 org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService INFO: HHH000397: Using ASTQueryTranslatorFactory Hibernate: select school0_.school_id as school_i1_1_, school0_.name as name2_1_ from school school0_ School (huaihai) : Hibernate: select stclass0_.school_id as school_i3_0_0_, stclass0_.classes_id as classes_1_0_0_, stclass0_.classes_id as classes_1_0_1_, stclass0_.name as name2_0_1_, stclass0_.school_id as school_i3_0_1_ from classes stclass0_ where stclass0_.school_id=? clazz (class1) : Hibernate: select students0_.classes_id as classes_2_2_0_, students0_.student_id as student_1_2_0_, students0_.student_id as student_1_2_1_, students0_.classes_id as classes_2_2_1_, students0_.name as name3_2_1_ from student students0_ where students0_.classes_id=? student (jack) :
Hibernate的配置
最新推荐文章于 2024-05-14 20:46:13 发布