Hibernate注解开发(未完待续)
Posted Qiao_Zhi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.类注解的使用
5.1@Entity注解的使用---属于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 | | +----------+--------------+------+-----+---------+-------+
5.2@Table注解
@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) )
5.3@Embeddable表示此类一个嵌入类,经常作为另一个类的成员属性,在生成数据库表的时候该类的成员会作为其主类的属性添加到数据库
例如如下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
1.@Id注解(必须有)
定义了映射到数据库表的主键的属性,一个实体类可以有一个或者多个属性被映射为主键,如果是多个属性为主键属性,实体必须实现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() { returnSpring集成Activemq使用(未完待续)