Hibernate4实战之Hibernate4注解零配置
@Entity,注册在类头上,将一个类声明为一个实体bean(即一个持久化POJO类) 。
@Table,注册在类头上,注解声明了该实体bean映射指定的表(table)。
@Id用来注册主属性,@GeneratedValue用来注册主属性的生成策略,@Column用来注册属性,@Version用来注册乐观锁,@Transient用来注册不是属性。
以上的@Id、@GeneratedValue、 @Column 、 @Version,可以用来注册属性,既可以写在Java类的属性上,也可以注册在属性对应的getter上。
@Transient注册在多余的属性或多余的getter上,但是必须与以上的@Column等对应。
@Column
标识属性对应的字段,示例:@Column(name=“userName")
java代码:
- @Column(
- name="columnName"; (1)
- boolean unique() default false; (2)
- boolean nullable() default true; (3)
- boolean insertable() default true; (4)
- boolean updatable() default true; (5)
- String columnDefinition() default ""; (6)
- String table() default ""; (7)
- int length() default 255; (8)
- int precision() default 0; // decimal precision (9)
- int scale() default 0; // decimal scale (10)
(1) name 可选,列名(默认值是属性名)
(2) unique 可选,是否在该列上设置唯一约束(默认值false)
(3) nullable 可选,是否设置该列的值可以为空(默认值false)
(4) insertable 可选,该列是否作为生成的insert语句中的一个列(默认值true)
(5) updatable 可选,该列是否作为生成的update语句中的一个列(默认值true)
(6) columnDefinition 可选: 为这个特定列覆盖SQL DDL片段 (这可能导致无法在不同数据库间移植)
(7) table 可选,定义对应的表(默认为主表)
(8) length 可选,列长度(默认值255)
(8) precision 可选,列十进制精度(decimal precision)(默认值0)
(10) scale 可选,如果列十进制数值范围(decimal scale)可用,在此设置(默认值0)
@Id,标识这个属性是实体类的唯一识别的值。
注意:这个注解只能标注单一列构成的主键,如tbl_grade那种有两个字段组成的联合主键由其他注解标识。
回忆*.hbm.xml:
<id name=
"uuid">
<generator class=
"assigned"/>
</id>
@Id,只是标识这个属性是主键,但是并没有指出其生成策略,如上例中的assigned就是由程序员指定的生成策略。
如果仅仅写出@Id,即是使用assigned生成略,如:
java代码:
- @Id
- @Column
- private int uuid;
- 如果想使用Oracle支持的sequence取主键,必须通过@GeneratedValue来指定生成策略,而由@SequenceGenerator指定如何使用sequence。
- @Id
- @Column
- @GeneratedValue(
- strategy = GenerationType.SEQUENCE,//使用sequence生成主键
- generator =“generator“//引用下面名为gernator的生成策略
- )
- @SequenceGenerator(
- name = “generator”,//定义名为generator的生成策略
- allocationSize = 1,//每次sequence加1
- name=“seq_a”//引用名为seq_a的sequence
- )
- private int uuid;
- @Version
标识这个属性用来映射乐观锁的version
@Transient
标识这个属性不用持久化
@Embeddable【小对象的头上】
标识实体中可以定义一个嵌入式组件(embedded component)。组件类必须在类一级定义@Embeddable注解。
@Embedded【大对象的属性头上】
引用定义的小对象。
@Embeddable【小对象的头上】
标识实体中可以定义一个嵌入式组件(embedded component)。组件类必须在类一级定义@Embeddable注解。
注意:如果这个小对象作为复合主键,一定要实现Serializable接口。这并不是注解决定的,而是Hibernate的主键都需要实现Serializable接口。
@EmbeddedId 【大对象的属性头上】
引用定义的小对象作为主键。
注意:不需要再使用@Id注解。
标准的1:1
XML的配置
java代码:
- 主1【tbl_product】:
- <one-to-one name="info" cascade="all"/>
- 从1【tbl_product_info】:
- <id name="uuid">
- <generator class=“foreign【写死,使用外来生成策略】">
- <param name=“property”>product【引用自己的Java属性名】 </param>
- </generator>
- </id>
- <one-to-one name="product"/>
注解的配置
java代码:
- 主1【tbl_product】:
- @OneToOne(cascade=CascadeType.ALL)
- @PrimaryKeyJoinColumn
- private ProductInfoModel info;
- 从1【tbl_product_info】:
- @Id
- @Column
- @GeneratedValue(generator=“copy【引用生成策略】")
- @GenericGenerator(name=“copy【定义生成策略】”,strategy=“foreign【写死,使用外来策略】”,parameters=@Parameter(name=“property”,value=“product【引用自己的Java属性】"))
- private int uuid;
- @OneToOne(mappedBy=“info【引用对方的Java属性】")
- private ProductModel product;
-
标准的1:M
XML的配置
java代码:
- 1【tbl_parent】:
- <set name="children">
- <key column=“puuid【对方的数据库外键列名】"/>
- <one-to-many class=“cn.javass.model.c.ChildModel【对方的Java类名】"/>
- </set>
- 多【tbl_child】:
- <many-to-one name=“parent” column=“puuid【自己的数据库外键列名】"/>
注解的配置
java代码:
- 1【tbl_parent】:
- @OneToMany
- @JoinColumn(name="puuid【对方的数据库外键列名】")
- private Set<ChildModel> children = new HashSet<ChildModel>();
- 多【tbl_child】:
- @ManyToOne
- @JoinColumn(name="puuid【自己的数据库外键列名】")
- private ParentModel parent;
-
标准的1:M
XML的配置
java代码:
- <set name=“courses” table=“tbl_grade【联接表】">
- <key column=“suuid【联接表里代表自己的数据库字段名】"/>
- <many-to-many column=“cuuid【联接表里代表对方的数据库字段名】” class=“cn.javass.model.e.CourseMode【对方的类名】l"/>
- </set>
- 注解的配置
- @ManyToMany
- @JoinTable(
- name=“tbl_grade【联接表】",
- joinColumns=@JoinColumn(name="suuid【联接表里代表自己的数据库字段名】"),
- inverseJoinColumns=@JoinColumn(name="cuuid 【联接表里代表对方的数据库字段名】” )
- )
- private Set<CourseModel> courses = new HashSet<CourseModel>();
-
标准的1:M
XML的配置
java代码:
- 主1【tbl_product】:
- <one-to-one name=“info” foreign-key=“puuid【对方的数据库外键列名】" cascade="all"/>
- 从1【tbl_product_info】:
- <many-to-one name=“product” column=“puuid【自己的数据库外键列名】” unique=“true【写死】"/>
注解的配置
java代码:
- 主1【tbl_product】:
- @OneToOne(cascade=CascadeType.ALL,mappedBy=“product【对方的Java类属性名 】")
- private ProductInfoModel info;
- 从1【tbl_product_info】:
- @OneToOne
- @JoinColumn(name=“puuid【自己的数据库外键列名】")
- private ProductModel product;
标准的1:M
XML的配置
java代码:
- 1【tbl_parent】:
- <set name=“children” table=“tbl_parent_child【联接表】">
- <key column=“puuid【联接表里代表自己的数据库列名】"/>
- <many-to-many column=“cuuid【联接表里代表对方的数据库列名】” unique=“true【写死】”
- class=“cn.javass.model.d.ChildModel【对方的Java类名】"/>
- </set>
- <join table=“tbl_parent_child【联接表】">
- <key column="cuuid【联接表里代表自己的数据库列名】"/>
- <many-to-one name="parent" column="puuid【联接表里代表对方的数据库列名】" unique="true【写死】"/>
- </join>
注解的配置
java代码:
- 1【tbl_parent】:
- @OneToMany(mappedBy="parent【对方的Java类属性名 】")
- private Set<ChildModel> children = new HashSet<ChildModel>();
- 多【tbl_child】:
- @ManyToOne
- @JoinTable(
- name=“tbl_parent_child【联接表】",
- joinColumns=@JoinColumn(name="cuuid【联接表里代表自己的数据库字段名】"),
- inverseJoinColumns=@JoinColumn(name="puuid【联接表里代表对方的数据库字段名】")
- )
- private ParentModel parent;
标准的1:M
XML的配置
java代码:
- 1【tbl_product】:
- <join table=“tbl_product_relation【联接表】">
- <key column=“puuid【联接表里代表自己的列名】"/>
- <many-to-one name=“course【自己的Java属性名】” column=“cuuid【联接表里代表对方的列名】” unique=“true【写死】"/>
- </join>
注解的配置
java代码:
- 1【tbl_product】:
- @ManyToOne
- @JoinTable(
- name=" tbl_product_relation 【联接表】",
- joinColumns=@JoinColumn(name="suuid【联接表里代表自己的列名】"),
- inverseJoinColumns=@JoinColumn(name="cuuid【联接表里代表对方的列名】",unique=true【写死】)
- )
- private CourseModel course;
@Id用来注册主属性,@GeneratedValue用来注册主属性的生成策略,@Column用来注册属性,@Version用来注册乐观锁,@Transient用来注册不是属性。
以上的@Id、@GeneratedValue、 @Column 、 @Version,可以用来注册属性,既可以写在Java类的属性上,也可以注册在属性对应的getter上。
@Transient注册在多余的属性或多余的getter上,但是必须与以上的@Column等对应。
@Column
标识属性对应的字段,示例:@Column(name=“userName")
java代码:
- @Column(
- name="columnName"; (1)
- boolean unique() default false; (2)
- boolean nullable() default true; (3)
- boolean insertable() default true; (4)
- boolean updatable() default true; (5)
- String columnDefinition() default ""; (6)
- String table() default ""; (7)
- int length() default 255; (8)
- int precision() default 0; // decimal precision (9)
- int scale() default 0; // decimal scale (10)
(1) name 可选,列名(默认值是属性名)
(2) unique 可选,是否在该列上设置唯一约束(默认值false)
(3) nullable 可选,是否设置该列的值可以为空(默认值false)
(4) insertable 可选,该列是否作为生成的insert语句中的一个列(默认值true)
(5) updatable 可选,该列是否作为生成的update语句中的一个列(默认值true)
(6) columnDefinition 可选: 为这个特定列覆盖SQL DDL片段 (这可能导致无法在不同数据库间移植)
(7) table 可选,定义对应的表(默认为主表)
(8) length 可选,列长度(默认值255)
(8) precision 可选,列十进制精度(decimal precision)(默认值0)
(10) scale 可选,如果列十进制数值范围(decimal scale)可用,在此设置(默认值0)
@Id,标识这个属性是实体类的唯一识别的值。
注意:这个注解只能标注单一列构成的主键,如tbl_grade那种有两个字段组成的联合主键由其他注解标识。
回忆*.hbm.xml:
<id name=
"uuid">
<generator class=
"assigned"/>
</id>
@Id,只是标识这个属性是主键,但是并没有指出其生成策略,如上例中的assigned就是由程序员指定的生成策略。
如果仅仅写出@Id,即是使用assigned生成略,如:
java代码:
- @Id
- @Column
- private int uuid;
- 如果想使用Oracle支持的sequence取主键,必须通过@GeneratedValue来指定生成策略,而由@SequenceGenerator指定如何使用sequence。
- @Id
- @Column
- @GeneratedValue(
- strategy = GenerationType.SEQUENCE,//使用sequence生成主键
- generator =“generator“//引用下面名为gernator的生成策略
- )
- @SequenceGenerator(
- name = “generator”,//定义名为generator的生成策略
- allocationSize = 1,//每次sequence加1
- name=“seq_a”//引用名为seq_a的sequence
- )
- private int uuid;
- @Version
标识这个属性用来映射乐观锁的version
@Transient
标识这个属性不用持久化
@Embeddable【小对象的头上】
标识实体中可以定义一个嵌入式组件(embedded component)。组件类必须在类一级定义@Embeddable注解。
@Embedded【大对象的属性头上】
引用定义的小对象。
@Embeddable【小对象的头上】
标识实体中可以定义一个嵌入式组件(embedded component)。组件类必须在类一级定义@Embeddable注解。
注意:如果这个小对象作为复合主键,一定要实现Serializable接口。这并不是注解决定的,而是Hibernate的主键都需要实现Serializable接口。
@EmbeddedId 【大对象的属性头上】
引用定义的小对象作为主键。
注意:不需要再使用@Id注解。
标准的1:1
XML的配置
java代码:
- 主1【tbl_product】:
- <one-to-one name="info" cascade="all"/>
- 从1【tbl_product_info】:
- <id name="uuid">
- <generator class=“foreign【写死,使用外来生成策略】">
- <param name=“property”>product【引用自己的Java属性名】 </param>
- </generator>
- </id>
- <one-to-one name="product"/>
注解的配置
java代码:
- 主1【tbl_product】:
- @OneToOne(cascade=CascadeType.ALL)
- @PrimaryKeyJoinColumn
- private ProductInfoModel info;
- 从1【tbl_product_info】:
- @Id
- @Column
- @GeneratedValue(generator=“copy【引用生成策略】")
- @GenericGenerator(name=“copy【定义生成策略】”,strategy=“foreign【写死,使用外来策略】”,parameters=@Parameter(name=“property”,value=“product【引用自己的Java属性】"))
- private int uuid;
- @OneToOne(mappedBy=“info【引用对方的Java属性】")
- private ProductModel product;
标准的1:M
XML的配置
java代码:
- 1【tbl_parent】:
- <set name="children">
- <key column=“puuid【对方的数据库外键列名】"/>
- <one-to-many class=“cn.javass.model.c.ChildModel【对方的Java类名】"/>
- </set>
- 多【tbl_child】:
- <many-to-one name=“parent” column=“puuid【自己的数据库外键列名】"/>
注解的配置
java代码:
- 1【tbl_parent】:
- @OneToMany
- @JoinColumn(name="puuid【对方的数据库外键列名】")
- private Set<ChildModel> children = new HashSet<ChildModel>();
- 多【tbl_child】:
- @ManyToOne
- @JoinColumn(name="puuid【自己的数据库外键列名】")
- private ParentModel parent;
标准的1:M
XML的配置
java代码:
- <set name=“courses” table=“tbl_grade【联接表】">
- <key column=“suuid【联接表里代表自己的数据库字段名】"/>
- <many-to-many column=“cuuid【联接表里代表对方的数据库字段名】” class=“cn.javass.model.e.CourseMode【对方的类名】l"/>
- </set>
- 注解的配置
- @ManyToMany
- @JoinTable(
- name=“tbl_grade【联接表】",
- joinColumns=@JoinColumn(name="suuid【联接表里代表自己的数据库字段名】"),
- inverseJoinColumns=@JoinColumn(name="cuuid 【联接表里代表对方的数据库字段名】” )
- )
- private Set<CourseModel> courses = new HashSet<CourseModel>();
标准的1:M
XML的配置
java代码:
- 主1【tbl_product】:
- <one-to-one name=“info” foreign-key=“puuid【对方的数据库外键列名】" cascade="all"/>
- 从1【tbl_product_info】:
- <many-to-one name=“product” column=“puuid【自己的数据库外键列名】” unique=“true【写死】"/>
注解的配置
java代码:
- 主1【tbl_product】:
- @OneToOne(cascade=CascadeType.ALL,mappedBy=“product【对方的Java类属性名 】")
- private ProductInfoModel info;
- 从1【tbl_product_info】:
- @OneToOne
- @JoinColumn(name=“puuid【自己的数据库外键列名】")
- private ProductModel product;
标准的1:M
XML的配置
java代码:
- 1【tbl_parent】:
- <set name=“children” table=“tbl_parent_child【联接表】">
- <key column=“puuid【联接表里代表自己的数据库列名】"/>
- <many-to-many column=“cuuid【联接表里代表对方的数据库列名】” unique=“true【写死】”
- class=“cn.javass.model.d.ChildModel【对方的Java类名】"/>
- </set>
- <join table=“tbl_parent_child【联接表】">
- <key column="cuuid【联接表里代表自己的数据库列名】"/>
- <many-to-one name="parent" column="puuid【联接表里代表对方的数据库列名】" unique="true【写死】"/>
- </join>
注解的配置
java代码:
- 1【tbl_parent】:
- @OneToMany(mappedBy="parent【对方的Java类属性名 】")
- private Set<ChildModel> children = new HashSet<ChildModel>();
- 多【tbl_child】:
- @ManyToOne
- @JoinTable(
- name=“tbl_parent_child【联接表】",
- joinColumns=@JoinColumn(name="cuuid【联接表里代表自己的数据库字段名】"),
- inverseJoinColumns=@JoinColumn(name="puuid【联接表里代表对方的数据库字段名】")
- )
- private ParentModel parent;
标准的1:M
XML的配置
java代码:
- 1【tbl_product】:
- <join table=“tbl_product_relation【联接表】">
- <key column=“puuid【联接表里代表自己的列名】"/>
- <many-to-one name=“course【自己的Java属性名】” column=“cuuid【联接表里代表对方的列名】” unique=“true【写死】"/>
- </join>
注解的配置
java代码:
- 1【tbl_product】:
- @ManyToOne
- @JoinTable(
- name=" tbl_product_relation 【联接表】",
- joinColumns=@JoinColumn(name="suuid【联接表里代表自己的列名】"),
- inverseJoinColumns=@JoinColumn(name="cuuid【联接表里代表对方的列名】",unique=true【写死】)
- )
- private CourseModel course;
HIbernate的annotation注解总结
类图:
代码:
Salesman.java:
- package basicCar.bean;
- import java.util.HashSet;
- import java.util.Set;
- import javax.persistence.AttributeOverride;
- import javax.persistence.AttributeOverrides;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Embedded;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.JoinTable;
- import javax.persistence.ManyToMany;
- import javax.persistence.OneToMany;
- import javax.persistence.OneToOne;
- import javax.persistence.Table;
- //import org.hibernate.annotations.CascadeType;
- import org.hibernate.annotations.Cache;
- import org.hibernate.annotations.CacheConcurrencyStrategy;
- import org.hibernate.annotations.GenericGenerator;
- @Entity
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- @Table(name = "salesman")
- public class Salesman implements java.io.Serializable {
- @Id
- @GeneratedValue(generator = "mysqlIncrement")
- @GenericGenerator(name = "mysqlIncrement", strategy = "increment")
- private long sid;
- //@Length(min=1,max=3)
- @Column
- private String salesName;
- @OneToOne(mappedBy="salesman",cascade=CascadeType.ALL)
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- private Alias alias;
- @OneToMany(mappedBy="salesman",cascade = CascadeType.ALL)//双向一对多
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- private Set<CarOrder> carOrders = new HashSet();
- @ManyToMany( //双向多对多
- targetEntity=basicCar.bean.BasicCar.class,
- cascade = CascadeType.ALL
- )
- @JoinTable(
- name = "carorder",
- joinColumns = { @JoinColumn(name = "salesId")} ,
- inverseJoinColumns={@JoinColumn(name="carId")}
- )
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- private Set<BasicCar> cars = new HashSet();
- @Embedded //搞定映射组件
- @AttributeOverrides({
- @AttributeOverride(name="province", column=@Column(name="province")),
- @AttributeOverride(name="city", column=@Column(name="city")),
- @AttributeOverride(name="street", column=@Column(name="street")),
- @AttributeOverride(name="number", column=@Column(name="number"))
- })
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- private Address address;
- /*
- @Embedded
- @AttributeOverrides({
- @AttributeOverride(name="province", column=@Column(name="wprovince")),
- @AttributeOverride(name="city", column=@Column(name="wcity")),
- @AttributeOverride(name="street", column=@Column(name="wstreet")),
- @AttributeOverride(name="number", column=@Column(name="wnumber"))
- })
- private Address waddress;*/
- public Salesman() {
- }
- public Salesman(String N) {
- this.salesName = N;
- }
- public long getSid() {
- return this.sid;
- }
- private void setSid(long sid) {
- this.sid = sid;
- }
- public String getSalesname() {
- return this.salesName;
- }
- public void setSalesname(String salesName) {
- this.salesName = salesName;
- }
- public void setAddress(Address address) {
- this.address = address;
- }
- public Address getAddress() {
- return address;
- }
- public void setCarOrders(Set<CarOrder> carOrders) {
- this.carOrders = carOrders;
- }
- public Set<CarOrder> getCarOrders() {
- return carOrders;
- }
- public void setAlias(Alias alias) {
- this.alias = alias;
- }
- public Alias getAlias() {
- return alias;
- }
- public void setCars(Set<BasicCar> cars) {
- this.cars = cars;
- }
- public Set<BasicCar> getCars() {
- return cars;
- }
- /*public Set<String> getAliases() {
- return this.aliases;
- }
- public void setAliases(Set s){
- this.aliases=s;
- }*/
- /*public Address getaddress() {
- return this.address;
- }
- public void sethaddress(Address a) {
- this.address = a;
- }*/
- /*
- public Address getwaddress() {
- return this.waddress;
- }
- public void setwaddress(Address a) {
- this.waddress = a;
- }*/
- }
Alias.java:
- package basicCar.bean;
- import java.util.HashSet;
- import java.util.Set;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.ManyToMany;
- import javax.persistence.OneToOne;
- import javax.persistence.PrimaryKeyJoinColumn;
- import javax.persistence.Table;
- import javax.persistence.Version;
- import org.hibernate.annotations.Cache;
- import org.hibernate.annotations.GenericGenerator;
- import org.hibernate.annotations.CacheConcurrencyStrategy;
- @Entity
- @Table(name = "alias")
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- public class Alias implements java.io.Serializable{
- /*@Id
- @GeneratedValue(generator = "mysqlIncrement")
- @GenericGenerator(name = "mysqlIncrement", strategy = "increment")
- private long aid;*/
- @Id
- @GeneratedValue(generator = "mysqlIncrement")
- @GenericGenerator(name = "mysqlIncrement", strategy = "increment")
- private long aid;
- @Column
- private String aliasName;
- @Column
- private Long amoney;
- @Version
- @Column(name="version",nullable=false,unique=true)
- private int version;
- @OneToOne(cascade=CascadeType.ALL)
- @PrimaryKeyJoinColumn
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- private Salesman salesman;
- public Alias(){}
- public void setAliasName(String aliasName) {
- this.aliasName = aliasName;
- }
- public String getAliasName() {
- return aliasName;
- }
- public void setSalesman(Salesman salesman) {
- this.salesman = salesman;
- }
- public Salesman getSalesman() {
- return salesman;
- }
- public void setAid(long aid) {
- this.aid = aid;
- }
- public long getAid() {
- return aid;
- }
- public void setVersion(int version) {
- this.version = version;
- }
- public int getVersion() {
- return version;
- }
- public void setAmoney(Long amoney) {
- this.amoney = amoney;
- }
- public Long getAmoney() {
- return amoney;
- }
- }
BasicCar.java:
- package basicCar.bean;
- import java.util.Date;
- import java.util.HashSet;
- import java.util.Set;
- import javax.persistence.Basic;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.FetchType;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.Lob;
- import javax.persistence.ManyToMany;
- import javax.persistence.Table;
- import javax.persistence.Temporal;
- import javax.persistence.TemporalType;
- import org.hibernate.annotations.Cache;
- import org.hibernate.annotations.CacheConcurrencyStrategy;
- import org.hibernate.annotations.GenericGenerator;
- @Entity
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- @Table(name="basiccar")
- public class BasicCar implements java.io.Serializable {
- @Id
- @GeneratedValue(generator="mysqlIncrement")
- @GenericGenerator(name="mysqlIncrement", strategy="increment")
- private long id;
- @Column(name = "name")
- private String name;
- @Column(name = "factory" , length=50)
- @Lob
- private String factory;
- @Column(name = "date")
- //@Temporal(TemporalType.TIME)出错Data truncated for column 'date' at row 1
- @Temporal(TemporalType.DATE)
- @Basic(fetch=FetchType.LAZY)
- private Date date;
- @ManyToMany(
- mappedBy="cars",
- targetEntity=basicCar.bean.Salesman.class,
- cascade = {CascadeType.PERSIST,CascadeType.MERGE}
- )
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- private Set<Salesman> salesmans = new HashSet();
- public BasicCar() {
- }
- public BasicCar(String N) {
- this.name = N;
- }
- public BasicCar(String name, String factory, Date date) {
- this.name = name;
- this.factory = factory;
- this.date = date;
- }
- public long getId() {
- return this.id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getFactory() {
- return this.factory;
- }
- public void setFactory(String factory) {
- this.factory = factory;
- }
- public Date getDate() {
- return this.date;
- }
- public void setDate(Date date) {
- this.date = date;
- }
- public boolean eauals(Object o){
- if(this==o)
- return true;
- if(!(o instanceof BasicCar))
- return false;
- final BasicCar other=(BasicCar)o;
- if(this.getName().equals(other.getName())
- &&this.getDate().equals(other.getDate())
- &&this.getFactory().equals(other.getFactory()))
- return true;
- else
- return false;
- }
- public void setSalesmans(Set<Salesman> salesmans) {
- this.salesmans = salesmans;
- }
- public Set<Salesman> getSalesmans() {
- return salesmans;
- }
- }
CarOrder.java:
- package basicCar.bean;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.ManyToOne;
- import javax.persistence.Table;
- import org.hibernate.annotations.Cache;
- import org.hibernate.annotations.CacheConcurrencyStrategy;
- import org.hibernate.annotations.GenericGenerator;
- @Entity
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- @Table(name = "carorder1")
- public class CarOrder implements java.io.Serializable {
- @Id
- @GeneratedValue(generator = "mysqlIncrement")
- @GenericGenerator(name = "mysqlIncrement", strategy = "increment")
- private long cid;
- @Column
- private String carName;
- @ManyToOne
- @JoinColumn(name = "salesId")
- @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
- private Salesman salesman;
- public CarOrder() {
- }
- public CarOrder(String name) {
- this.carName = name;
- }
- public long getCid() {
- return this.cid;
- }
- public void setCid(long id) {
- this.cid = id;
- }
- public String getcarname() {
- return this.carName;
- }
- public void setcarname(String cName) {
- this.carName = cName;
- }
- public Salesman getSalesman() {
- return this.salesman;
- }
- public void setSalesman(Salesman salesman) {
- this.salesman = salesman;
- }
- }
Address.java:
- package basicCar.bean;
- import javax.persistence.Column;
- import javax.persistence.Embeddable;
- import org.hibernate.annotations.Cache;
- import org.hibernate.annotations.CacheConcurrencyStrategy;
- @SuppressWarnings("serial")
- @Embeddable
- public class Address implements java.io.Serializable {
- @Column
- private String province;
- @Column
- private String city;
- @Column
- private String street;
- @Column
- private String number;
- public Address(){}
- public Address(String P,String C,String S,String N)
- {
- this.province=P;
- this.city=C;
- this.street=S;
- this.number=N;
- }
- public void setProvince(String province) {
- this.province = province;
- }
- public String getProvince() {
- return province;
- }
- public void setCity(String city) {
- this.city = city;
- }
- public String getCity() {
- return city;
- }
- public void setStreet(String street) {
- this.street = street;
- }
- public String getStreet() {
- return street;
- }
- public void setNumber(String number) {
- this.number = number;
- }
- public String getNumber() {
- return number;
- }
- }
hibernate.hbm.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="hibernate.connection.password">001052</property>
- <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/chwa</property>
- <property name="hibernate.connection.username">root</property>
- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <!--设置安全级别-->
- <property name="hibernate.connection.isolation">2</property>
- <!-- 配置EhCache的缓存提供者 -->
- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider </property>
- <!-- 启动sessionfactory级别的Statistics统计,用于记录持久化操作 -->
- <property name="hibernate.generate_statistics">true</property>
- <!-- 设置二级缓存 -->
- <property name="hibernate.cache.use_second_level_cache">true</property>
- <!-- 查询缓存 -->
- <property name="hibernate.cache.use_query_cache">true</property>
- <!-- 观看查询是输出的sql语句,知道使用和不使用二级缓存的区别-->
- <property name="hibernate.show_sql">true</property>
- <mapping class="basicCar.bean.Salesman"/>
- <mapping class="basicCar.bean.CarOrder"/>
- <mapping class="basicCar.bean.Alias"/>
- <mapping class="basicCar.bean.BasicCar"/>
- </session-factory>
- </hibernate-configuration>
ehcache.xml:
- <ehcache>
- <diskStore path="C:\\temp"/>
- <defaultCache
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="true"
- />
- <cache name="basicCar.bean.Salesman"
- maxElementsInMemory="5"
- eternal="false"
- timeToIdleSeconds="30"
- timeToLiveSeconds="30"
- overflowToDisk="true"
- />
- <cache name="basicCar.bean.BasicCar"
- maxElementsInMemory="5"
- eternal="false"
- timeToIdleSeconds="30"
- timeToLiveSeconds="30"
- overflowToDisk="true"
- />
- <cache name="basicCar.bean.CarOrder"
- maxElementsInMemory="5"
- eternal="false"
- timeToIdleSeconds="30"
- timeToLiveSeconds="30"
- overflowToDisk="true"
- />
- <cache name="basicCar.bean.Alias"
- maxElementsInMemory="5"
- eternal="false"
- timeToIdleSeconds="30"
- timeToLiveSeconds="30"
- overflowToDisk="true"
- />
- <cache name="sampleCache2"
- maxElementsInMemory="1000"
- eternal="true"
- timeToIdleSeconds="0"
- timeToLiveSeconds="0"
- overflowToDisk="false"
- />
- <!-- Place configuration for your caches following -->
- <cache name="org.hibernate.cache.StandardQueryCache"
- maxElementsInMemory="50"
- eternal="false"
- timeToIdleSeconds="60"
- timeToLiveSeconds="60"
- overflowToDisk="true"
- />
- <!-- 设置时间戳缓存的数据过期策略 ,保存每个表的最近更新时间-->
- <!-- 查看它的生成时间是不是最后更新时间,如果不是,则证明这个查询缓存已经过期了。
- 因此只要更新过一个表,涉及这个表的查询缓存就过期了-->
- <cache name="org.hibernate.cache.UpdateTimestampsCahe"
- maxElementsInMemory="5000"
- eternal="true"
- overflowToDisk="true"
- />
- </ehcache>
Test.java:
- package basicCar;
- import java.sql.Date;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Locale;
- import java.util.ResourceBundle;
- import java.util.Set;
- import org.hibernate.Query;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import eventListener.MyLoadListener;
- import eventListener.MyPreInsertListener;
- import basicCar.bean.Address;
- import basicCar.bean.Alias;
- import basicCar.bean.BasicCar;
- import basicCar.bean.Salesman;
- import basicCar.bean.CarOrder;
- public class Test {
- Configuration cfg;
- SessionFactory sf;
- Session session;
- public static void main(String[] args) {
- Test test = new Test();
- test.doConfiguration();
- test.openSession();
- //test.saveEntity();
- test.updateEntity();
- //test.queryEntity3();
- // test.deleteEntity();
- test.closeSession();
- System.out.println("end");
- }
- void doConfiguration() {
- cfg = new Configuration();
- //实现监听器
- /*MyLoadListener mll = new MyLoadListener();
- MyPreInsertListener mpl = new MyPreInsertListener();
- cfg.setListener("load", mll);*/
- //cfg.setListener("pre-inset",mpl);
- cfg.configure();
- sf = cfg.configure().buildSessionFactory();
- }
- // open session from session factory
- void openSession() {
- session = sf.openSession();
- }
- // close session
- void closeSession() {
- session.close();
- }
- // save a BasicCar in database
- void saveEntity() {
- // begin a transaction to save
- Transaction tx1 = session.beginTransaction();
- /*
- * Salesman sc = new Salesman(); sc.setSalesname("aaa"); CarOrder co =
- * new CarOrder(); co.setcarname("dd"); co.setSalesman(sc); Set cs = new
- * HashSet(); cs.add(co); sc.setCarorders(cs);
- */
- Salesman sc = new Salesman("hello33");
- Address as = new Address("广东","茂名","鳌头","34号");
- Alias alia = new Alias();
- alia.setAliasName("dkfjk");
- CarOrder co1=new CarOrder();
- co1.setcarname("aa111");
- CarOrder co2=new CarOrder();
- co2.setcarname("aa112");
- Set carorders = new HashSet();
- carorders.add(co1);
- carorders.add(co2);
- sc.setAlias(alia);
- alia.setSalesman(sc);
- co1.setSalesman(sc);
- co2.setSalesman(sc);
- sc.setCarOrders(carorders);
- sc.setAddress(as);
- session.save(sc);
- session.save(co1);
- session.save(co2);
- session.save(alia);
- /*Salesman sm1 = new Salesman("xiaox");
- Salesman sm2 = new Salesman("xiaox2");
- Salesman sm3 = new Salesman("xiaox3");
- BasicCar bc1 = new BasicCar("BB");
- BasicCar bc2 = new BasicCar("BB2");
- BasicCar bc3 = new BasicCar("BB3");
- Set<Salesman> salesmans = new HashSet();
- Set<BasicCar> basiccars = new HashSet();
- salesmans.add(sm1);
- salesmans.add(sm2);
- salesmans.add(sm3);
- basiccars.add(bc1);
- basiccars.add(bc2);
- basiccars.add(bc3);
- sm1.setCars(basiccars);
- bc1.setSalesmans(salesmans);
- session.save(sm1);
- session.save(sm2);
- session.save(sm3);
- session.save(bc1);
- session.save(bc2);
- session.save(bc3);*/
- tx1.commit();
- }
- // delete a BasicCar in database
- /*
- * void deleteEntity() { // delete the id=1 basicCar Object from database
- * Transaction tx3 = session.beginTransaction(); try { BasicCar bc4 =
- * (BasicCar) session.load(BasicCar.class, new Long(1));
- * session.delete(bc4); } catch (Exception e) { System.out.println("id=1 car
- * are not existed, can't be deleted"); } tx3.commit(); } // update a
- * BasicCar in database void updateEntity() { // update "factory" and "name"
- * of the id=1 basicCar Object in database Transaction tx2 =
- * session.beginTransaction(); BasicCar bc2 = (BasicCar)
- * session.load(BasicCar.class, new Long(1)); bc2.setFactory("ShangHai");
- * bc2.setName("SHCar"); session.update(bc2); tx2.commit(); }
- */
- void updateEntity() {
- //测试乐观锁
- Session session1=sf.openSession();
- Session session2=sf.openSession();
- Transaction tx1 = session1.beginTransaction();
- Transaction tx2 = session2.beginTransaction();
- try{
- Alias ao1 = (Alias) session1.load(Alias.class, new Long(3));
- Alias ao2 = (Alias) session2.load(Alias.class, new Long(3));
- //这时候,两个版本号是相同的
- ao1.setAmoney(ao1.getAmoney()+10);
- tx1.commit();
- //这时候,两个版本号是不相同的
- ao2.setAmoney(ao2.getAmoney()-10);
- tx2.commit();
- System.out.println("OK!");
- }catch(Exception e){
- System.out.println(e);
- if(tx2 != null)//有同步数据库的作用
- {
- tx2.rollback();
- //updateEntity2();
- }
- else if(tx1 != null)//有同步数据库的作用
- {
- tx1.rollback();
- //updateEntity2();
- }
- }finally{
- session1.close();
- session2.close();
- }
- }
- void updateEntity2() {
- //测试乐观锁
- Session session1=sf.openSession();
- Transaction tx1 = session1.beginTransaction();
- try{
- Alias ao1 = (Alias) session1.load(Alias.class, new Long(3));
- //重新执行该事务
- ao1.setAmoney(ao1.getAmoney()+10);
- tx1.commit();
- System.out.println("OK2!");
- }catch(Exception e){
- //System.out.println(e);
- if(tx1 != null)//有同步数据库的作用
- {
- tx1.rollback();
- updateEntity();
- }
- }finally{
- session1.close();
- }
- }
- void queryEntity()
- {
- Session session2 = sf.openSession();
- Query query2 = session2.createQuery("from Salesman");
- java.util.List list2 = query2.list();
- for(int i=0;i<list2.size();i++)
- {
- Salesman ac2 = (Salesman)list2.get(i);
- if((ac2.getCars())!=null)
- {
- Set<BasicCar> s1 = ac2.getCars() ;
- if(s1!=null)
- {
- for(Iterator<BasicCar> it = s1.iterator(); it.hasNext();)
- {
- String name1 = ac2.getSalesname();
- System.out.print(name1+"拥有职务:");
- BasicCar r = (BasicCar) it.next() ;
- System.out.println("\t【"+r.getName()+"】");
- }
- }
- }
- }
- session2.close();
- }
- //queryEntity2和queryEntity3都还要在对类启用二级缓存<cache usage="read-write">
- void queryEntity2() //对类对象进行缓存
- {
- Session session1 = sf.openSession();
- try{
- Query query = session1.createQuery("from Salesman");
- java.util.List list = query.list();
- for(int i=0;i<list.size();i++)
- {
- Salesman ac1 = (Salesman)list.get(i);
- System.out.println("id for the selectedaccout is:"
- +ac1.getSalesname());
- }
- session1.close();
- //第二个session
- Session session2 = sf.openSession();
- Salesman ac2 = (Salesman)session2.load(Salesman.class, new Long(6));
- System.out.println("money for the selectedaccount is:"+ac2.getSalesname());
- session2.close();
- }catch (Exception e) {
- System.out.println(e);
- }
- }
- void queryEntity3() //对查询进行缓存
- {
- Session session1 = sf.openSession();
- try{
- Query query = session1.createQuery("from Salesman where sid > 72");
- //设置使用查询缓存
- query.setCacheable(true);
- query.setCacheRegion("basiCar.bean.Salesman");
- java.util.List list = query.list();
- for(int i=0;i<list.size();i++)
- {
- Salesman ac1 = (Salesman)list.get(i);
- System.out.println("id for the selectedaccout is:"
- +ac1.getSid());
- }
- session1.close();
- //第二个session
- Session session2 = sf.openSession();
- Query query2 = session2.createQuery("from Salesman where sid > 72");
- //设置使用查询缓存
- query2.setCacheable(true); //设置第二个查询是否使用第一个session的缓存
- query2.setCacheRegion("basiCar.bean.Salesman");//缓存区域不同结果查询重新从数据库导入
- java.util.List list2 = query2.list();
- for(int i=0;i<list2.size();i++)
- {
- Salesman ac2 = (Salesman)list2.get(i);
- System.out.println("id for the selectedaccout is:"
- +ac2.getSid());
- }
- session2.close();
- }catch (Exception e) {
- System.out.println(e);
- }
- }
- }
数据库图:
要导入的包:
最后:还有映射复合主键和继承关系映射没做,需要再补充。
HIbernate注解
(1)
简介:
在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准。它非常强大、灵活,而且具备了优异的性能。在本文中,我们将了解如何使用Java 5 注释来简化Hibernate代码,并使持久层的编码过程变得更为轻松。
传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。
在最近发布的几个Hibernate版本中,出现了一种基于 Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照您的想法来定义——注释直接嵌入到您的Java 类中,并提供一种强大及灵活的方法来声明持久性映射。
简介:
在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准。它非常强大、灵活,而且具备了优异的性能。在本文中,我们将了解如何使用Java 5 注释来简化Hibernate代码,并使持久层的编码过程变得更为轻松。
传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。
在最近发布的几个Hibernate版本中,出现了一种基于 Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照您的想法来定义——注释直接嵌入到您的Java 类中,并提供一种强大及灵活的方法来声明持久性映射。
即利用hibernate注解后,可不用定义持久化类对应的*.hbm.xml文件,直接以注解方式写入在持久化类中来实现。
Hibernate annotation使用了ejb JPA的注解,所以,下面安装配置hibernate annotation环境时,需要导入ejb的包。许多网上的资料都是jpa hibernate annotation方面的资料。
(2)
安装 Hibernate Annotation
第一步,
环境与jar包:
要使用 Hibernate Annotation,您至少需要具备 Hibernate 3.2和Java 5。可以从 Hibernate 站点下载 Hibernate 3.2 和 Hibernate Annotation库。除了标准的 Hibernate JAR 和依赖项之外,您还需要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。
安装 Hibernate Annotation
第一步,
环境与jar包:
要使用 Hibernate Annotation,您至少需要具备 Hibernate 3.2和Java 5。可以从 Hibernate 站点下载 Hibernate 3.2 和 Hibernate Annotation库。除了标准的 Hibernate JAR 和依赖项之外,您还需要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。
添加hibernate3.2.jar,hibernate-annotations-3.3.0.jar,hibernate-commons-annotations.jar和ejb3-persistence.jar 。这样就可以使用hibernate的annotation了。
如果您正在使用 Maven,只需要向 POM 文件添加相应的依赖项即可,如下所示:
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
如果您正在使用 Maven,只需要向 POM 文件添加相应的依赖项即可,如下所示:
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
第二步,
获取 Hibernate 会话工厂。尽管无需惊天的修改,但这一工作与使用 Hibernate Annotations有所不同。您需要使用 AnnotationConfiguration 类来建立会话工厂:
sessionFactory = new AnnotationConfiguration().buildSessionFactory();
第三步,
尽管通常使用 <mapping> 元素来声明持久性类,您还是需要在 Hibernate 配置文件(通常是 hibernate.cfg.xml)中声明持久性类:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
" http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.onjava.modelplanes.domain.PlaneType"/>
<mapping class="com.onjava.modelplanes.domain.ModelPlane"/>
</session-factory>
</hibernate-configuration>
近期的许多 Java 项目都使用了轻量级的应用框架,例如 Spring。如果您正在使用 Spring 框架,可以使用
获取 Hibernate 会话工厂。尽管无需惊天的修改,但这一工作与使用 Hibernate Annotations有所不同。您需要使用 AnnotationConfiguration 类来建立会话工厂:
sessionFactory = new AnnotationConfiguration().buildSessionFactory();
第三步,
尽管通常使用 <mapping> 元素来声明持久性类,您还是需要在 Hibernate 配置文件(通常是 hibernate.cfg.xml)中声明持久性类:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
" http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.onjava.modelplanes.domain.PlaneType"/>
<mapping class="com.onjava.modelplanes.domain.ModelPlane"/>
</session-factory>
</hibernate-configuration>
近期的许多 Java 项目都使用了轻量级的应用框架,例如 Spring。如果您正在使用 Spring 框架,可以使用
AnnotationSessionFactoryBean 类轻松建立一个基于注释的 Hibernate 会话工厂,如下所示:
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
...
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.onjava.modelplanes.domain.PlaneType</value>
<value>com.onjava.modelplanes.domain.ModelPlane</value>
...
</list>
</property>
</bean>
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
...
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.onjava.modelplanes.domain.PlaneType</value>
<value>com.onjava.modelplanes.domain.ModelPlane</value>
...
</list>
</property>
</bean>
(3)
hibernate Annotation标签的使用:
hibernate Annotation标签的使用:
[1]
1.带注释的持久性类也是普通 POJO,它们只是具备了持久性注释的普通 POJO 。
1.带注释的持久性类也是普通 POJO,它们只是具备了持久性注释的普通 POJO 。
2.事实上,您既可以保持字段的持久性(注释写在成员变量之上),也可以保持属性(注释写在getter方法之上)的持久性。
3.常用的hibernate annotation标签如下:
@Entity --注释声明该类为持久类。将一个Javabean类声明为一个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类属性都为映射到数据表的持久性字段.若在类中,添加另外属性,而非映射来数据库的,要用下面的Transient来注解.
@Table(name= "promotion_info") --持久性映射的表(表名="promotion_info).@Table是类一级的注解,定义在@Entity下,为实体bean映射表,目录和schema的名字, 默认为实体bean的类名,不带包名.
@Id--注释可以表明哪种属性是该类中的独特标识符(即相当于数据表的主键)。
@GeneratedValue --定义自动增长的主键的生成策略.
@Transient --将忽略这些字段和属性,不用持久化到数据库.适用于,在当前的持久类中,某些属性不是用于映射到数据表,而是用于其它的业务逻辑需要,这时,须将这些属性进行transient的注解.否则系统会因映射不到数据表相应字段而出错.
@Temporal(TemporalType.TIMESTAMP)--声明时间格式
@Enumerated --声明枚举
@Version --声明添加对乐观锁定的支持
@OneToOne --可以建立实体bean之间的一对一的关联
@OneToMany --可以建立实体bean之间的一对多的关联
@ManyToOne --可以建立实体bean之间的多对一的关联
@ManyToMany --可以建立实体bean之间的多对多的关联
@Formula --一个SQL表达式,这种属性是只读的,不在数据库生成属性(可以使用sum、average、max等)
@OrderBy --Many端某个字段排序(List)
1.2
Hibernate 能够出色地自动生成主键。Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略。
其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法, JPA提供四种标准用法,由@GeneratedValue的源代码可以明显看出.
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.
TABLE:使用一个特定的数据库表格来保存主键。
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
IDENTITY:主键由数据库自动生成(主要是自动增长型)
AUTO:主键由程序控制。
Hibernate 能够出色地自动生成主键。Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略。
其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法, JPA提供四种标准用法,由@GeneratedValue的源代码可以明显看出.
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.
TABLE:使用一个特定的数据库表格来保存主键。
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
IDENTITY:主键由数据库自动生成(主要是自动增长型)
AUTO:主键由程序控制。
在指定主键时,如果不指定主键生成策略,默认为AUTO。
@Id
@Id
相当于
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@GeneratedValue(strategy = GenerationType.AUTO)
identity:
使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)。
Oracle就要采用sequence了.
同时,也可采用uuid,native等其它策略.(相关用法,上网查询)
[2]
第一个持久性类
该内容将映射到下表中:
CREATE TABLE T_MODEL_PLANE
(
PLANE_ID long,
PLANE_NAME varchar
其它字段省略...
)
默认情况下,Hibernate 会将持久类以匹配的名称映射到表和字段中。例如,下例中,若不用注解,则会映射到如下一表中:
CREATE TABLE MODELPLANE
(
ID long,
NAME varchar
@Entity
@Table(name= "T_MODEL_PLANE")
public class ModelPlane implements Serializable {
@Id
@Column(name= "PLANE_ID")
@GeneratedValue(strategy=GenerationType.AUTO) //注解于属性中
/*
对于oracle想使用各自的Sequence,设置如下:
@GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ")
@SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ")
@Table(name= "T_MODEL_PLANE")
public class ModelPlane implements Serializable {
@Id
@Column(name= "PLANE_ID")
@GeneratedValue(strategy=GenerationType.AUTO) //注解于属性中
/*
对于oracle想使用各自的Sequence,设置如下:
@GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ")
@SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ")
另外:
对于自动增长后,在数据表中的相应字段,要设置字段为auto_increment.
*/
private Long id;
private String name; //注解写于getter方法之上.请见下.
//DATE - java.sql.Date
//TIME - java.sql.Time
//TIMESTAMP - java.sql.Timestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name= "start_time")
private Date startTime;
//显示0 隐藏1
public static enum DisplayType {显示,隐藏}
@Enumerated(value = EnumType.ORDINAL) //ORDINAL序数
private DisplayType displayType = DisplayType.显示;
//1.sql语句中的字段和表名都应该和数据库相应,而不是类中的字段,
//若带有参数如la.id= id,这个=id才是类中属性
//2.操作字段一定要用别名
@Formula(select COUNT(la.id) from largess la)
private int count;
//注解于方法中
@Column(name= "PLANE_ID", length=80, nullable= true) //较详细定义
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
其它的setter,getter省略......
}
*/
private Long id;
private String name; //注解写于getter方法之上.请见下.
//DATE - java.sql.Date
//TIME - java.sql.Time
//TIMESTAMP - java.sql.Timestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name= "start_time")
private Date startTime;
//显示0 隐藏1
public static enum DisplayType {显示,隐藏}
@Enumerated(value = EnumType.ORDINAL) //ORDINAL序数
private DisplayType displayType = DisplayType.显示;
//1.sql语句中的字段和表名都应该和数据库相应,而不是类中的字段,
//若带有参数如la.id= id,这个=id才是类中属性
//2.操作字段一定要用别名
@Formula(select COUNT(la.id) from largess la)
private int count;
//注解于方法中
@Column(name= "PLANE_ID", length=80, nullable= true) //较详细定义
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
其它的setter,getter省略......
}
该内容将映射到下表中:
CREATE TABLE T_MODEL_PLANE
(
PLANE_ID long,
PLANE_NAME varchar
其它字段省略...
)
CREATE TABLE MODELPLANE
(
ID long,
NAME varchar
其它字段省略...
)
)
[3]
一对多注解:
一对多注解:
1.
在一对多注解中,会用到:
"一"方:
@OneToMany --> mappedBy:"多"方的关联属性 (被控方)
"多"方:
@ManyToOne --> @JoinColumn,"多"方定义的外键字段.
@OneToMany --> mappedBy:"多"方的关联属性 (被控方)
"多"方:
@ManyToOne --> @JoinColumn,"多"方定义的外键字段.
如数据表定义外键如下:
FOREIGN KEY (classid) REFERENCES classes(id)
则:
@JoinColumn(name=
"classid")
2.
在双向关联中,有且仅有一端作为主体(owner)端存在:主体端负责维护联接列(即更新),对于不需要维护这种关系的从表则通过mappedNy属性进行声明。mappedBy的值指向另一主体的关联属性。例子中,mappedBy的值为classes。
附加说明:
mappedBy相当于过去的inverse="true".
inverse=false的side(side其实是指inverse=false所位于的class元素)端有责任维护关系,而inverse=true端无须维护这些关系。
inverse=false的side(side其实是指inverse=false所位于的class元素)端有责任维护关系,而inverse=true端无须维护这些关系。
3.
cascade与fetch使用说明:
Cascade
CascadeType.PERSIST (级联新建)
CascadeType.REMOVE (级联删除)
CascadeType.REFRESH (级联刷新)
CascadeType.MERGE (级联更新)中选择一个或多个。
CascadeType.ALL
CascadeType.REMOVE (级联删除)
CascadeType.REFRESH (级联刷新)
CascadeType.MERGE (级联更新)中选择一个或多个。
CascadeType.ALL
fetch属性:
关联关系获取方式,即是否采用延时加载。
LAZY(默认值)采用延时加载,查询数据时,不一起查询关联对象的数据。而是当访问关联对象时(如:getStudnets()时)才触发相应的查询操作,获取关联对象数据。
EAGER:是在查询数据时,也直接一起获取关联对象的数据。
LAZY(默认值)采用延时加载,查询数据时,不一起查询关联对象的数据。而是当访问关联对象时(如:getStudnets()时)才触发相应的查询操作,获取关联对象数据。
EAGER:是在查询数据时,也直接一起获取关联对象的数据。
package oneToMany;
import java.util.Set;
import javax.persistence.*;
/*
注意导入时,是导入:import javax.persistence.*;
非导入org.hibernate的相关类:import org.hibernate.annotations.Entity;
*/
@Entity
@Table(name= "classes")
public class Classes implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@OneToMany(cascade=CascadeType.ALL,mappedBy= "classes")
private Set<Student> students;
//getter,setter省略
}
package oneToMany;
import javax.persistence.*;
@Entity
@Table(name= "student")
public class Student implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int sid;
private String sname;
//若有多个cascade,可以是:{CascadeType.PERSIST,CascadeType.MERGE}
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name= "classid") //student类中对应外键的属性:classid
private Classes classes;
//getter,setter省略
}
public class TestOneToMany {
/*
CREATE TABLE student ( --要定义外键!!!!!!!
`sid` double NOT NULL auto_increment,
`classid` double NULL,
`sname` varchar(255) NOT NULL,
PRIMARY KEY (sid),
INDEX par_ind (classid),
FOREIGN KEY (classid) REFERENCES classes(id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
*/
public static void main(String[] args) throws SQLException
{
try
{
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();
import java.util.Set;
import javax.persistence.*;
/*
注意导入时,是导入:import javax.persistence.*;
非导入org.hibernate的相关类:import org.hibernate.annotations.Entity;
*/
@Entity
@Table(name= "classes")
public class Classes implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@OneToMany(cascade=CascadeType.ALL,mappedBy= "classes")
private Set<Student> students;
//getter,setter省略
}
package oneToMany;
import javax.persistence.*;
@Entity
@Table(name= "student")
public class Student implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int sid;
private String sname;
//若有多个cascade,可以是:{CascadeType.PERSIST,CascadeType.MERGE}
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name= "classid") //student类中对应外键的属性:classid
private Classes classes;
//getter,setter省略
}
public class TestOneToMany {
/*
CREATE TABLE student ( --要定义外键!!!!!!!
`sid` double NOT NULL auto_increment,
`classid` double NULL,
`sname` varchar(255) NOT NULL,
PRIMARY KEY (sid),
INDEX par_ind (classid),
FOREIGN KEY (classid) REFERENCES classes(id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
*/
public static void main(String[] args) throws SQLException
{
try
{
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();
/*
因为mappedBy是定义在classes中,即classes类不负责维护级联关系.即维护者是student.所以,
1.要将clsses的数据,赋给student,即用student的setClasses()方法去捆定class数据;
2.在进行数据插入/更新session.save()/session.update()时,最后操作的是student.
*/
Classes classes= new Classes();
classes.setName( "access");
Student st1= new Student();
st1.setSname( "jason");
st1.setClasses(classes);
session.save(st1);
Student st2= new Student();
st2.setSname( "hwj");
st2.setClasses(classes);
session.save(st2);
tx.commit();
Classes classes= new Classes();
classes.setName( "access");
Student st1= new Student();
st1.setSname( "jason");
st1.setClasses(classes);
session.save(st1);
Student st2= new Student();
st2.setSname( "hwj");
st2.setClasses(classes);
session.save(st2);
tx.commit();
/*
输出如下:
Hibernate: insert into classes (name) values (?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
*/
/*
因为一端维护关系另一端不维护关系的原因,我们必须注意避免在应用中用不维护关系的类(class)建立关系,因为这样建立的关系是不会在数据库中存储的。
如上的代码倒过来,则插入时,student的外键值为空.如下:
*/
// Student st1=new Student();
// st1.setSname("jason");
// session.save(st1);
//
// Student st2=new Student();
// st2.setSname("hwj");
// session.save(st2);
//
// Set<Student> students=new HashSet<Student>();
// students.add(st1);
// students.add(st2);
//
// Classes classes=new Classes();
// classes.setName("access");
// classes.setStudents(students);
// session.save(classes);
// st1.setSname("jason");
// session.save(st1);
//
// Student st2=new Student();
// st2.setSname("hwj");
// session.save(st2);
//
// Set<Student> students=new HashSet<Student>();
// students.add(st1);
// students.add(st2);
//
// Classes classes=new Classes();
// classes.setName("access");
// classes.setStudents(students);
// session.save(classes);
/*
输出如下:
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into classes (name) values (?)
*/
}
catch(HibernateException e)
{
e.printStackTrace();
}
}
}
}
catch(HibernateException e)
{
e.printStackTrace();
}
}
}
多对多注解:
在多对多注解中,双方都采用@ManyToMany.
其中被控方,像一对多注解中设置一样,也要设置mappedBy.
其中主控方,不像一对多注解那样,采用@joinColumn,而是采用@joinTable.如下:
@JoinTable(name="j_student_course" ,joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="cid")})
其中,
如上所说,mappedBy,相当于inverse="true".所以,在@joinTable中的inverseJoinColumns中定义的字段为mappedBy所在类的主键.
joinColumns定义的字段,就是当前类的主键.
joinColumns定义的字段,就是当前类的主键.
@Entity
@Table(name= "jcourse")
public class Jcourse {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int cid;
private String cname;
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY ,mappedBy= "courses")
private Set<Jstudent> students;
//setter,getter省略....
}
@Entity
@Table(name= "jstudent")
public class Jstudent {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int sid;
private String sname;
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.EAGER)
//inverseJoinColumns中对应的id为以下属性course的对应id.
@JoinTable(name= "j_student_course" ,joinColumns={@JoinColumn(name= "sid")},inverseJoinColumns={@JoinColumn(name= "cid")})
private Set<Jcourse> courses;
//setter,getter省略....
}
public class Test {
public static void main(String[] args) {
try
{
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();
Jcourse course= new Jcourse();
course.setCname( "jason-english");
session.save(course); //先各自保存.
Jcourse course2= new Jcourse();
course2.setCname( "herry-english");
session.save(course2);
Set<Jcourse> courses= new HashSet<Jcourse>();
courses.add(course);
courses.add(course2);
Jstudent student= new Jstudent();
student.setSname( "jason");
student.setCourses(courses);
session.save(student); // 要用非mapby定义的类(studet)来作为主者(会控制级联关系),一对多,多对一也一样道理.
//可以尝试反过来.
tx.commit();
}
catch(HibernateException e)
{
e.printStackTrace();
}
}
}
@Table(name= "jcourse")
public class Jcourse {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int cid;
private String cname;
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY ,mappedBy= "courses")
private Set<Jstudent> students;
//setter,getter省略....
}
@Entity
@Table(name= "jstudent")
public class Jstudent {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int sid;
private String sname;
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.EAGER)
//inverseJoinColumns中对应的id为以下属性course的对应id.
@JoinTable(name= "j_student_course" ,joinColumns={@JoinColumn(name= "sid")},inverseJoinColumns={@JoinColumn(name= "cid")})
private Set<Jcourse> courses;
//setter,getter省略....
}
public class Test {
public static void main(String[] args) {
try
{
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();
Jcourse course= new Jcourse();
course.setCname( "jason-english");
session.save(course); //先各自保存.
Jcourse course2= new Jcourse();
course2.setCname( "herry-english");
session.save(course2);
Set<Jcourse> courses= new HashSet<Jcourse>();
courses.add(course);
courses.add(course2);
Jstudent student= new Jstudent();
student.setSname( "jason");
student.setCourses(courses);
session.save(student); // 要用非mapby定义的类(studet)来作为主者(会控制级联关系),一对多,多对一也一样道理.
//可以尝试反过来.
tx.commit();
}
catch(HibernateException e)
{
e.printStackTrace();
}
}
}