4 Hibernate:使用注解(Annotation)

2 Hibernate:入门简介 中介绍了 Hibernate 开发步骤:

(1) 导入 Hibernate 库文件及开发所用数据库的驱动文件
(2) 创建 Hibernate 配置文件:hibernate.cfg.xml
(3) 创建持久化类
(4) 创建对象-关系映射文件:*.hbm.xml
(5) 将对象-关系映射文件加入 Hibernate 配置文件
(6) 通过 Hibernate API 编写访问数据库的代码

如果在步骤(3)创建持久化类中使用注解,则步骤(4)和(5)可以省略。以下展示使用注解的Hibernate完整开发步骤:

(1) 使用 Maven 管理 Hibernate 依赖,POM文件内容如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>lesson</groupId>
  <artifactId>hibernate</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.10.Final</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.40</version>
    </dependency>
  </dependencies>
</project>

(2) 创建 Hibernate 配置文件:hibernate.cfg.xml

具体步骤可以参看 2 Hibernate:入门简介,以下是配置文件内容:

<?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>

    <!-- 数据库连接设置 -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.password">123456</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
    <property name="connection.username">root</property>

    <!-- Hibernate内置的JDBC连接池,因为缺少某些关键特性,只用于学习和演示,不建议商用 -->
    <property name="connection.pool_size">1</property>

    <!-- SQL方言 -->
    <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

    <!-- 禁用二级缓存 -->
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

    <!-- 将已执行SQL打印到输出 -->
    <property name="show_sql">true</property>

    <!-- 格式化打印的SQL,否则全部显示在一行中 -->
    <property name="format_sql">true</property>

    <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">create</property>

  </session-factory>
</hibernate-configuration>

(3) 创建持久化类时使用注解(Annotation)

package hibernate;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "person")
public class Person {

    private int id;

    private String account;

    private String name;

    private Date birth;

    public Person() {}

    public Person(String account, String name, Date birth) {
        this.account = account;
        this.name = name;
        this.birth = birth;
    }

    @Id // 实体唯一标识
    @GeneratedValue(generator = "increment") // 使用名为“increment”的生成器
    @GenericGenerator(name = "increment", strategy = "increment") // 定义名为“increment”的生成器,使用Hibernate的"increment"生成策略,即自增
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "birth_date")
    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", account=" + account + ", name=" + name + ", birth=" + birth + "]";
    }

}

注解说明:

@Entity
标识当前类为实体类,使用默认 ORM 规则,即类名映射数据库中对应的表名,属性名映射数据表中列名。

@Table
如果类名和数据表名不一致,使用 @Table(name = "数据表名") 标识当前类对应的数据表名。

@Id
当前实体类的唯一性标识,通常映射到数据表主键。

@GeneratedValue
实体类唯一标识生成规则(后续会专门撰文进行详细说明)

@GenericGenerator
唯一标识生成器(后续会专门撰文进行详细说明)

@Temporal
限制时间格式。
TemporalType.DATE – 只记录日期,不记录时间
TemporalType.TIME – 只记录时间,不记录日期
TemporalType.TIMESTAMP – 日期时间都记录(默认)

@Column
如果当前类中属性名与对应数据表中的列名不一致,使用 @Column(name = "数据表列名") 标识此属性对应的数据表列名,此外可以使用 @Column(length = 30) 限制字符串长度。

@Transient
标识当前属性不映射任何数据表列。

这里只使用了部分注解,更多注解及详细说明后续补充。

(4) 将注解的实体类映射加入Hibernate 配置文件

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>

    <!-- 数据库连接设置 -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.password">123456</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
    <property name="connection.username">root</property>

    <!-- Hibernate内置的JDBC连接池,因为缺少某些关键特性,只用于学习和演示,不建议商用 -->
    <property name="connection.pool_size">1</property>

    <!-- SQL方言 -->
    <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

    <!-- 禁用二级缓存 -->
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

    <!-- 将已执行SQL打印到输出 -->
    <property name="show_sql">true</property>

    <!-- 格式化打印的SQL,否则全部显示在一行中 -->
    <property name="format_sql">true</property>

    <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">create</property>

    <!-- 使用注解的实体类映射 -->
    <mapping class="hibernate.Person"/>

  </session-factory>
</hibernate-configuration>

(5) 通过 Hibernate API 编写访问数据库的代码

沿用 3 Hibernate:本地 API 单元测试优化 中代码进行测试演示

package hibernate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class NativeApiIllustrationTest {

    private SessionFactory sessionFactory;

    @Before
    public void setUp() throws Exception {
        final StandardServiceRegistry registry = 
            new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
        try {
            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        } catch (Exception e) {
            // 如果构建SessionFactory出现异常,需要手动销毁StandardServiceRegistry
            StandardServiceRegistryBuilder.destroy(registry);
        }
    }

    @After
    public void tearDown() throws Exception {
        if (null != sessionFactory) {
            sessionFactory.close();
        }
    }

    @Test
    public void test() throws ParseException {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(new Person("tom", "Tommy", new SimpleDateFormat("yyyy-MM-dd").parse("1985-01-01")));
        session.save(new Person("mix", "Mercy", new SimpleDateFormat("yyyy-MM-dd").parse("1990-10-01")));
        session.getTransaction().commit();
        session.close();

        session = sessionFactory.openSession();
        session.beginTransaction();
        @SuppressWarnings("unchecked")
        List<Person> result = session.createQuery(" FROM Person").list();
        for (Person person : result) {
            System.out.println(person);
        }
        session.getTransaction().commit();
        session.close();
    }

}

单元测试日志:

六月 25, 2017 9:18:09 上午 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.2.10.Final}
六月 25, 2017 9:18:09 上午 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
六月 25, 2017 9:18:09 上午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/test]
六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=root, password=****}
六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 1 (min=1)
Sun Jun 25 09:18:10 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
六月 25, 2017 9:18:10 上午 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Hibernate: 

    drop table if exists person
六月 25, 2017 9:18:12 上午 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@42463763] 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 person (
       id integer not null,
        account varchar(255),
        birth_date datetime,
        name varchar(255),
        primary key (id)
    ) engine=MyISAM
六月 25, 2017 9:18:12 上午 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@fc258b1] 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.
六月 25, 2017 9:18:12 上午 org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources
INFO: HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@acdb094'
Hibernate: 
    select
        max(id) 
    from
        person
Hibernate: 
    insert 
    into
        person
        (account, birth_date, name, id) 
    values
        (?, ?, ?, ?)
Hibernate: 
    insert 
    into
        person
        (account, birth_date, name, id) 
    values
        (?, ?, ?, ?)
六月 25, 2017 9:18:12 上午 org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: 
    select
        person0_.id as id1_0_,
        person0_.account as account2_0_,
        person0_.birth_date as birth_da3_0_,
        person0_.name as name4_0_ 
    from
        person person0_
Person [id=1, account=tom, name=Tommy, birth=1985-01-01 00:00:00.0]
Person [id=2, account=mix, name=Mercy, birth=1990-10-01 00:00:00.0]
六月 25, 2017 9:18:13 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/test]

Hibernate 生成的数据表 person 结构:

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又言又语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值