Hibernate注解开发(未完待续)

1.注解的目的

  简化繁琐的ORM映射文件(*.hbm)的配置

2.JPA和hibernate的关系

  JPA:java persistence API,JPA注解是JavaEE的标准和规范。

  两者的关系可以简单理解为JPA是接口,Hibernate是实现,但是其功能是JPA的超集。

Hibernate如何实现与JPA的关系?

  通过hibernate-core,hibernate-entitymanager,hibernate-annotation三个组件实现。

程序开发中一般使用JPA注解,便于程序的扩展和移植。

3.Hibernate注解分类:

  类级别注解

    @Entity  表示实体类,对应DB中一张表

    @Table    表示DB中的表

    @Embeddable    嵌入类

  属性级别注解

  映射关系注解

4.Hibernate注解的使用

1.导包与准备工具类:

pom包依赖:

    <dependencies>
        <!-- slf4j 依赖包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.0-rc1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.0-rc1</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.0.7.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>
    </dependencies>

工具类:

package cn.qlq.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    // 创建一个对象,一个web项目只有一个SessionFactory
    static {
        // 3.3以及之前的版本构建会话工厂对象
        // SessionFactory sessionFactory = new
        // Configuration().configure().buildSessionFactory();

        // 5.0之后获取SessionFactory
        // 创建服务注册对象
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
        // 创建会话工厂对象
        sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
    }

    // 获得session => 获得全新session
    public static Session openSession() {
        return sessionFactory.openSession();
    }

    // 获得session => 获得与线程绑定的session
    public static Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

}

5.类注解的使用

[email protected]注解的使用---属于javax包

  @Entity:映射实体类、

  @Entity(name = "tableName")

  name是可选属性,指定数据库的表名,如果不写的话默认与实体类名相同。

注意:使用@Entity必须指定实体的主键属性(可以在get方法上设置,也可以直接在属性设置)

package cn.qlq.domain;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity(name = "t_student") // 注意包名是javax
public class Student {
//    @Id
    private Integer id;
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private String address;

    @Id
    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password">123456</property>

        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 使用二级缓存 -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!--设置缓存的类型,设置缓存的提供商 -->
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</property>

        <!-- #hibernate.show_sql true
             #hibernate.format_sql true
        -->
        <!-- 将hibernate生成的sql语句打印到控制台 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 将hibernate生成的sql语句格式化(语法缩进) -->
        <property name="hibernate.format_sql">true</property>
        <!--
        ## auto schema export  自动导出表结构. 自动建表
        #hibernate.hbm2ddl.auto create        自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
        #hibernate.hbm2ddl.auto validate    校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
         -->
        <property name="hibernate.hbm2ddl.auto">create</property>

        <!-- 引入orm注解类         -->
        <mapping class="cn.qlq.domain.Student" />
    </session-factory>
</hibernate-configuration>

测试:

package cn.qlq.test;

import org.junit.Test;

import cn.qlq.util.HibernateUtil;

public class TestEntityAnno {

    @Test
    public void test1() {
        HibernateUtil.openSession();
    }
}

日志:

Hibernate:
    drop table if exists t_student
2018-08-27 23:12:02 [net.sf.ehcache.util.UpdateChecker]-[DEBUG] Checking for update...
Hibernate:
    create table t_student (
        id integer not null,
        address varchar(255),
        age integer,
        birthDay datetime,
        name varchar(255),
        sex char(1),
        primary key (id)
    )

SQL表:(主键没有自增)

mysql> desc t_student;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int(11)      | NO   | PRI | NULL    |       |
| address  | varchar(255) | YES  |     | NULL    |       |
| age      | int(11)      | YES  |     | NULL    |       |
| birthDay | datetime     | YES  |     | NULL    |       |
| name     | varchar(255) | YES  |     | NULL    |       |
| sex      | char(1)      | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+

[email protected]注解

@Table(name="xxx",catalog="xxx",schema="xxx")

@Entity配合使用,只能标注在实体的class处定义,表示实体对应的数据库表的信息

name:可选映射表的名称,不写的话与类名称相同

catalog:可选(目录名称),表示Catalog名称,默认为Catalog("")

schema:可选的模式名称,表示Scheme名称,默认为Scheme("")

Catalog与Schema解释:

自己的测试:

package cn.qlq.domain;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu", schema = "hibernate") // 注意包名是javax
public class Student {
    // @Id
    private Integer id;
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private String address;

    @Id
    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

SQL:

Hibernate:
    drop table if exists t_stu
2018-09-06 21:50:43 [net.sf.ehcache.util.UpdateChecker]-[DEBUG] Checking for update...
2018-09-06 21:50:44 [net.sf.ehcache.util.UpdateChecker]-[DEBUG] Update check failed: java.io.IOException: Server returned HTTP response code: 403 for URL: http://www.terracotta.org/kit/reflector?kitID=ehcache.default&pageID=update.properties&id=-1062731519&os-name=Windows+8.1&jvm-name=Java+HotSpot%28TM%29+64-Bit+Server+VM&jvm-version=1.7.0_80&platform=amd64&tc-version=UNKNOWN&tc-product=Ehcache+Core+2.4.3&source=Ehcache+Core&uptime-secs=1&patch=UNKNOWN
Hibernate:
    create table t_stu (
        id integer not null,
        address varchar(255),
        age integer,
        birthDay datetime,
        name varchar(255),
        sex char(1),
        primary key (id)
    )

[email protected]表示此类一个嵌入类,经常作为另一个类的成员属性,在生成数据库表的时候该类的成员会作为其主类的属性添加到数据库

例如如下Address是一个嵌入类:

package cn.qlq.domain;

import javax.persistence.Embeddable;

@Embeddable /** 表示此类是一个嵌入类,作为其他类 的成员属性 **/
public class Address {

    private int addreCode;
    private String addressName;

    public int getAddreCode() {
        return addreCode;
    }

    public void setAddreCode(int addreCode) {
        this.addreCode = addreCode;
    }

    public String getAddressName() {
        return addressName;
    }

    public void setAddressName(String addressName) {
        this.addressName = addressName;
    }

}
package cn.qlq.domain;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu", schema = "hibernate") // 注意包名是javax
public class Student {
    // @Id
    private Integer id;
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private Address address;

    @Id
    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

发出的SQL:

    create table t_stu (
        id integer not null,
        addreCode integer not null,
        addressName varchar(255),
        age integer,
        birthDay datetime,
        name varchar(255),
        sex char(1),
        primary key (id)
    )

6.属性级别的注解:

  使用方法有两种:第一种可以放在属性的头顶,第二种可以在属性的getter方法前面。

主要有以下注解(红色是重要的):

  @Id,@SequenceGenerator,@GeneratedValue,@Column,@Embedded,@EmbeddedId,@Lob,@Version,@Basic,@Transient

[email protected]注解(必须有)

  定义了映射到数据库表的主键的属性,一个实体类可以有一个或者多个属性被映射为主键,如果是多个属性为主键属性,实体必须实现Serializable接口。而且String类型的ID长度不能太长,默认长度是255(超过允许的主键长度),所以需要结合@Column指定列的长度。

例如:(注意注解放的位置一致,都放在getter或者属性前面)

package cn.qlq.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu", schema = "hibernate") // 注意包名是javax
public class Student implements Serializable {

    private Integer id;
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private Address address;

    @Id
    public Integer getId() {
        return id;
    }

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

    @Id
    @Column(length = 8)
    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

SQL:

    drop table if exists t_stu

    create table t_stu (
        name varchar(8) not null,
        id integer not null,
        addreCode integer not null,
        addressName varchar(255),
        age integer,
        birthDay datetime,
        sex char(1),
        primary key (name, id)
    )
mysql> desc t_stu;
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| name        | varchar(8)   | NO   | PRI | NULL    |       |
| id          | int(11)      | NO   | PRI | NULL    |       |
| addreCode   | int(11)      | NO   |     | NULL    |       |
| addressName | varchar(255) | YES  |     | NULL    |       |
| age         | int(11)      | YES  |     | NULL    |       |
| birthDay    | datetime     | YES  |     | NULL    |       |
| sex         | char(1)      | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
7 rows in set (0.01 sec)

2.GeneratedValue注解---定义注解生成策略

如下测试都是基于mysql数据库:

  •  测试int类型(Hibernate)

  Auto是利用一个表生成全局唯一ID。查询的时候利用for udate锁住表防止生成重复的ID,这也是生成全局唯一ID的思路。

package cn.qlq.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu", schema = "hibernate") // 注意包名是javax
public class Student implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) // 等价于@GeneratedValue,根据底层数据库选择。因为数据库是mysql,5.0之后是利用表生成全局唯一ID
    private Integer id;
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private Address address;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

测试类:

package cn.qlq.test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.qlq.domain.Address;
import cn.qlq.domain.Student;
import cn.qlq.util.HibernateUtil;

public class TestEntityAnno {

    @Test
    public void test1() {
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        Address a = new Address();
        a.setAddressName("地球");

        Student st = new Student();
        st.setAddress(a);

        session.save(st);

        tx.commit();
        session.close();
    }
}

SQL:

Hibernate:
    drop table if exists hibernate_sequence
2018-09-06 22:57:34 [net.sf.ehcache.util.UpdateChecker]-[DEBUG] Checking for update...
Hibernate:
    drop table if exists t_stu
2018-09-06 22:57:34 [net.sf.ehcache.util.UpdateChecker]-[DEBUG] Update check failed: java.io.IOException: Server returned HTTP response code: 403 for URL: http://www.terracotta.org/kit/reflector?kitID=ehcache.default&pageID=update.properties&id=-1062731519&os-name=Windows+8.1&jvm-name=Java+HotSpot%28TM%29+64-Bit+Server+VM&jvm-version=1.7.0_80&platform=amd64&tc-version=UNKNOWN&tc-product=Ehcache+Core+2.4.3&source=Ehcache+Core&uptime-secs=1&patch=UNKNOWN
Hibernate:
    create table hibernate_sequence (
        next_val bigint
    )
Hibernate:
    insert into hibernate_sequence values ( 1 )
Hibernate:
    create table t_stu (
        id integer not null,
        addreCode integer not null,
        addressName varchar(255),
        age integer,
        birthDay datetime,
        name varchar(255),
        sex char(1),
        primary key (id)
    )
Hibernate:
    select
        next_val as id_val
    from
        hibernate_sequence for update

Hibernate:
    update
        hibernate_sequence
    set
        next_val= ?
    where
        next_val=?
Hibernate:
    insert
    into
        t_stu
        (addreCode, addressName, age, birthDay, name, sex, id)
    values
        (?, ?, ?, ?, ?, ?, ?)

总结:

hibernate5.0之后是新建一个数据表生成全局唯一的ID,每次查询的时候利用update语句去锁住表然后查询到ID,然后将表的值加一,并将取出的ID使用上,这也是生成全局唯一ID的一种思路。

mysql> select * from hibernate_sequence;
+----------+
| next_val |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)

mysql> select * from t_stu;
+----+-----------+-------------+------+----------+------+------+
| id | addreCode | addressName | age  | birthDay | name | sex  |
+----+-----------+-------------+------+----------+------+------+
|  1 |         0 | 地球        | NULL | NULL     | NULL | NULL |
+----+-----------+-------------+------+----------+------+------+
1 row in set (0.06 sec)

我们将int型设为自增:

package cn.qlq.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu") // 注意包名是javax
public class Student implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private Address address;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

测试类:

package cn.qlq.test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.qlq.domain.Address;
import cn.qlq.domain.Student;
import cn.qlq.util.HibernateUtil;

public class TestEntityAnno {

    @Test
    public void test1() {
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        Address a = new Address();
        a.setAddressName("地球");

        Student st = new Student();
        st.setAddress(a);

        session.save(st);

        tx.commit();
        session.close();
    }
}

SQL:

Hibernate:
    drop table if exists t_stu
2018-09-06 23:05:19 [net.sf.ehcache.util.UpdateChecker]-[DEBUG] Checking for update...
Hibernate:
    create table t_stu (
        id integer not null auto_increment,
        addreCode integer not null,
        addressName varchar(255),
        age integer,
        birthDay datetime,
        name varchar(255),
        sex char(1),
        primary key (id)
    )
2018-09-06 23:05:20 [net.sf.ehcache.util.UpdateChecker]-[DEBUG] Update check failed: java.io.IOException: Server returned HTTP response code: 403 for URL: http://www.terracotta.org/kit/reflector?kitID=ehcache.default&pageID=update.properties&id=-1062731519&os-name=Windows+8.1&jvm-name=Java+HotSpot%28TM%29+64-Bit+Server+VM&jvm-version=1.7.0_80&platform=amd64&tc-version=UNKNOWN&tc-product=Ehcache+Core+2.4.3&source=Ehcache+Core&uptime-secs=1&patch=UNKNOWN
Hibernate:
    insert
    into
        t_stu
        (addreCode, addressName, age, birthDay, name, sex)
    values
        (?, ?, ?, ?, ?, ?)
mysql> desc t_stu;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| addreCode   | int(11)      | NO   |     | NULL    |                |
| addressName | varchar(255) | YES  |     | NULL    |                |
| age         | int(11)      | YES  |     | NULL    |                |
| birthDay    | datetime     | YES  |     | NULL    |                |
| name        | varchar(255) | YES  |     | NULL    |                |
| sex         | char(1)      | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
  • 测试String类型的UUID生成值与手动设置值

(1)string类型做主键手动设置值:(需要结合hibernate的主键生成器)

package cn.qlq.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu") // 注意包名是javax
public class Student implements Serializable {

    private Integer id;
    @Id
    @GeneratedValue(generator = "sid") // 指定生成器d名字
    @GenericGenerator(name = "sid", strategy = "assigned") // hibernate的生成器,name必须与上面一样
    @Column(length = 40)
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private Address address;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

测试类:

package cn.qlq.test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.qlq.domain.Address;
import cn.qlq.domain.Student;
import cn.qlq.util.HibernateUtil;

public class TestEntityAnno {

    @Test
    public void test1() {
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        Address a = new Address();
        a.setAddressName("地球");

        Student st = new Student();
        st.setAddress(a);
        st.setName("张三");

        session.save(st);

        tx.commit();
        session.close();
    }
}

SQL:

Hibernate:
    drop table if exists t_stu
create table t_stu (
        name varchar(40) not null,
        addreCode integer not null,
        addressName varchar(255),
        age integer,
        birthDay datetime,
        id integer,
        sex char(1),
        primary key (name)
    )
insert
    into
        t_stu
        (addreCode, addressName, age, birthDay, id, sex, name)
    values
        (?, ?, ?, ?, ?, ?, ?)
mysql> desc t_stu;
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| name        | varchar(40)  | NO   | PRI | NULL    |       |
| addreCode   | int(11)      | NO   |     | NULL    |       |
| addressName | varchar(255) | YES  |     | NULL    |       |
| age         | int(11)      | YES  |     | NULL    |       |
| birthDay    | datetime     | YES  |     | NULL    |       |
| id          | int(11)      | YES  |     | NULL    |       |
| sex         | char(1)      | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

mysql> select * from t_stu;
+------+-----------+-------------+------+----------+------+------+
| name | addreCode | addressName | age  | birthDay | id   | sex  |
+------+-----------+-------------+------+----------+------+------+
| 张三 |         0 | 地球        | NULL | NULL     | NULL | NULL |
+------+-----------+-------------+------+----------+------+------+
1 row in set (0.07 sec)

(2)string类型做主键UUID生成值:(需要结合hibernate的主键生成器)

package cn.qlq.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu") // 注意包名是javax
public class Student implements Serializable {

    private Integer id;
    @Id
    @GeneratedValue(generator = "uid") // 指定生成器d名字
    @GenericGenerator(name = "uid", strategy = "uuid") // hibernate的生成器,name必须与上面一样
    @Column(length = 40)
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    private Address address;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

测试类:

package cn.qlq.test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.qlq.domain.Address;
import cn.qlq.domain.Student;
import cn.qlq.util.HibernateUtil;

public class TestEntityAnno {

    @Test
    public void test1() {
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        Address a = new Address();
        a.setAddressName("地球");

        Student st = new Student();
        st.setAddress(a);

        session.save(st);

        tx.commit();
        session.close();
    }
}

SQL:

    drop table if exists t_stu

    create table t_stu (
        name varchar(40) not null,
        addreCode integer not null,
        addressName varchar(255),
        age integer,
        birthDay datetime,
        id integer,
        sex char(1),
        primary key (name)
    )

    insert
    into
        t_stu
        (addreCode, addressName, age, birthDay, id, sex, name)
    values
        (?, ?, ?, ?, ?, ?, ?)
mysql> desc t_stu;
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| name        | varchar(40)  | NO   | PRI | NULL    |       |
| addreCode   | int(11)      | NO   |     | NULL    |       |
| addressName | varchar(255) | YES  |     | NULL    |       |
| age         | int(11)      | YES  |     | NULL    |       |
| birthDay    | datetime     | YES  |     | NULL    |       |
| id          | int(11)      | YES  |     | NULL    |       |
| sex         | char(1)      | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

mysql> select * from t_stu;
+----------------------------------+-----------+-------------+------+----------
| name                             | addreCode | addressName | age  | birthDay
+----------------------------------+-----------+-------------+------+----------
| 4028818165af748f0165af749da50000 |         0 | 地球        | NULL | NULL
+----------------------------------+-----------+-------------+------+----------
1 row in set (0.00 sec)

[email protected]注解(简单但是重要)

  可将属性映射到列,使用该注解来覆盖默认值,@Column描述了数据库表中该字段的详细定义,这对于根据JPA注解生成数据库表结构的工具非常有作用。

常用属性:

  name:可选,表示数据库表中该字段的名称,默认与属性名称一致。

  nullable:可选,表示该字段是否允许为null,默认为true

  unique:可选表示该字段是否唯一,默认false。

  length:可选,表示该字段的大小,仅对String类型的字段有效,默认值是255.(如果是主键不能使用默认值)

  insertable:可选,表示在ORM框架执行插入操作时,该字段是否应该出现在INSERT语句中,默认为true

  updateable:可选,表示在ORM框架执行更新操作时,该字段是否应该出现在update语句中,默认为true。对于一经创建就不可以更改的字段,该属性非常有用,比如birthday字段。

[email protected]属性注解:

  表示该成员属性是一个嵌入类。在其类上面也要有注解@Embeddable表示此类是一个嵌入类,作为其他类的成员属性,否则会报错。如下:

package cn.qlq.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

//@Entity(name = "t_student") // 注意包名是javax
@Entity
@Table(name = "t_stu") // 注意包名是javax
public class Student implements Serializable {

    private Integer id;
    @Id
    @GeneratedValue(generator = "uid") // 指定生成器d名字
    @GenericGenerator(name = "uid", strategy = "uuid") // hibernate的生成器,name必须与上面一样
    @Column(length = 40)
    private String name;
    private Integer age;
    private Date birthDay;
    private Character sex;
    @Embedded
    private Address address;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}
package cn.qlq.domain;
import javax.persistence.Embeddable;
@Embeddable /** 表示此类是一个嵌入类,作为其他类 的成员属性 **/
public class Address {

    private int addreCode;
    private String addressName;

    public int getAddreCode() {
        return addreCode;
    }

    public void setAddreCode(int addreCode) {
        this.addreCode = addreCode;
    }

    public String getAddressName() {
        return addressName;
    }

    public void setAddressName(String addressName) {
        this.addressName = addressName;
    }

}

[email protected]属性注解:

原文地址:https://www.cnblogs.com/qlqwjy/p/9545453.html

时间: 2024-08-26 05:07:10

Hibernate注解开发(未完待续)的相关文章

【06】Java注解 (未完待续)

B站地址:https://www.bilibili.com/video/av62102209 —————————————————————————————————————— 目录: 1.注解作用分类 2.自定义注解 —————————————————————————————————————— 1.注解作用分类 1)代码分析/检查代码,如:@override:检查方法是否是父类方法 2)生成文档,如jdk文档 编码格式 2.Java中预定义的注解使用 1)@Override名称不一样会报错 不加,就

慕课网-安卓工程师初养成-1-2 开发环境搭建 未完待续

http://www.imooc.com/video/1459 Java开发环境搭建 第一步:安装JDK 下载: http://www.oracle.com/technetwork/java/javase/downloads/ 针对不同的系统有不同文件,32bit和64bit也有不同文件 未完待续

iOS开发系统版本适配(未完待续。。。)

1.iOS9引入了新特性App Transport Security (ATS).新特性要求App内访问的网络必须使用HTTPS协议:iOS9系统发送的网络请求将统一使用TLS 1.2 SSL.采用TLS 1.2 协议,目的是强制增强数据访问安全,而且 系统 Foundation 框架下的相关网络请求,将不再默认使用 Http 等不安全的网络协议,而默认采用 TLS 1.2.简单的说,就是苹果限制了HTTP协议,如果你用的是http协议的,要处理请参考我的另一文章,iOS9网络适配 2.iOS9

听风讲MVC丶 —— 一言不合就撸码 (未完待续&#183;&#183;&#183;&#183;&#183;&#183;)

     希望你看了此小随 可以实现自己的MVC框架     也祝所有的程序员身体健康一切安好                                                                                                                                                ——久伴深海丶默 1.什么是前端控制器(font controller).Java Web中的前端控制器是应用的门面,

[译]App Framework 2.1 (1)之 Quickstart (未完待续)

最近有移动App项目,选择了 Hybrid 的框架Cordova  和  App Framework 框架开发. 本来应该从配置循序渐进开始写的,但由于上班时间太忙,这段时间抽不出空来,只能根据心情和兴趣,想到哪写到哪,前面的部分以后慢慢补上. App Framework 前生是是叫 jqMobi 注意大家不要和 jQuery Mobile 混淆了,它们是两个不同的框架,一开始我还真混淆了0.01秒. 这里我先翻译一下Quickstart 部分,一是自己工作上用的上,二是也想顺便练练英文,最关键

git个人使用总结 —— idea命令行、撤销commit (未完待续)

近期在使用git,最开始在idea界面操作,后来要求用命令行.刚开始还不是很习惯,感觉很麻烦,用了几天后感觉爽极了! 其实git的命令也不是很多,熟悉一段时间就差不多能顺利使用了.使用过程中遇到了各种各样的问题,有些小问题就在这里集中总结一下. 1.idea命令行.git安装后就自带终端git bash,使用起来很方便.但是用idea开发,开发后还要在相应文件夹下打开git bash很麻烦.其实idea也带有终端terminal,在最下方可以找到,在这里就可以执行命令.但是如果是默认方式安装的g

jdbc14 及 jdbc16 共存所带来的问题【未完待续】

在JAVA中JDK版本与JDBC版本的一致性十分重要,开发都们常常会忽略了这一点导致很多不必要的错误.昨天给客户排查了一个关于EDB在JBoss中使用时关于这方面的问题,希望给大家一点启发. 系统环境: Red Hat Enterpirse Linux 6 JBoss Enterprise Application Server 6 EnterpriseDB Postgres Plus Advanced Server 9 Oracle JDK 1.6 问题症状: 在JBoss日志中间歇性地出现以下

JavaWeb ajax编程(未完待续)

1.Ajax 1.1Ajax的定义 Ajax:(Asynchronous JavaScript And XML)指异步 JavaScript 及 XML. 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript.XML.HTML.CSS新用法. Ajax:只刷新局部页面的技术 JavaScript:更新局部的网页 XML:一般用于请求数据和响应数据的封装 XMLHttpRequest对象:发送请求到服务器并获得返回结果 CSS:美化页面

ASP.NET Core 2.2 基础知识(八) 主机 (未完待续)

主机负责应用程序启动和生存期管理.共有两个主机 API : 1.Web 主机 : 适用于托管 Web 应用,基于 IWebHostBuilder ; 2.通用主机 : 适用于托管非 Web 应用. 基于 HostBuilder . 官方: 通用主机的目标是将 HTTP 管道从 Web 主机 API 中分离出来,从而启用更多的主机方案. 基于通用主机的消息.后台任务和其他非 HTTP 工作负载可从横切功能(如配置.依赖关系注入 [DI] 和日志记录)中受益 通用主机是 ASP.NET Core 2