Hibernate的配置

8 篇文章 0 订阅
4 篇文章 0 订阅
  1. 如果使用maven管理,则需要在pom.xml中配置hibernate,代码如下

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifacted>
            <version>5.2.10.Final</version>
        </dependency>
  2. 如果要使用c3p0数据库连接池,则需要在pom.xml中添加代码:

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>5.2.10.Final</version>
        </dependency>
  3. 若将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>
  4. 比如这里有三个类,学校类(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;
        }
    }
  5. 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&amp;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...,需要注意的是此项配置与其前面的配置要用&amp分割。

  6. 学校类的映射文件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_idone-to-many说明了School和Classes为一对多的关系,响应的在Classes.hbm.xml中要配置many-to-one标签

  7. 班级类的映射文件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属性。

  8. 学生类的映射文件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>
  9. 需要注意的是三个类的id类型是String,而不是UUID,否则将出现转换错误

  10. 测试代码

    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();
        }
    }
  11. 运行结果

    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) : 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值