記事のディレクトリ
永続的な構成ファイル
クラス要素
<class>要素は、クラスとテーブル間のマッピングを指定するために使用されます。
name-クラス名(パスを含む)を
設定します。table-テーブル名を設定します。デフォルトでは、クラス名がテーブル名として使用されます。
<class>要素には、1つの子要素と複数の<property>子要素が含まれます。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
<!-- 类与表的映射 -->
<class name="User" table="USER">
<!-- 上面的类名与数据库名之所以可以简写,是因为 hibernate-mapping package属性规定了文件所处的包名 -->
<!-- 主键的映射,必选 -->
<id name="id">
<!-- 数据库的字段 -->
<column name="ID"></column>
<generator class="native"/>
</id>
<!--column可以通过嵌套的形式放在id标签里面 ,和上面那种形式等价
<id name="id" column="ID">
<generator class="native"/>
</id>
-->
<!-- id标签只有一个,且必须在property标签上面 -->
<property name="name" column="NAME" type="java.lang.String"></property>
<property name="password" column="PASSWORD"></property>
</class>
</hibernate-mapping>
id要素
<id>子要素は、永続クラスのOID(オブジェクト識別子)とテーブルの主キーの間のマッピング関係を設定します。
column –テーブル列の名前を
指定します。generator–要素はOIDのジェネレーターを指定します。
プロパティ要素
<property>子要素は、クラスの他の属性とテーブルのフィールドの間のマッピング関係を設定します。
name-対応するクラスの属性名
; type-属性のタイプを指定します;オプションの
column-テーブルフィールドの名前を指定します;
not-null-属性を空にすることができるかどうかを指定します。
型の文字列型は参照型であるため、全体としてjava.lang.Stringという名前にする必要がありますが、基本的な型は必要ありません。int、charなどを記述してください。
フィールド名が属性名と同じである場合、列もオプションです。つまり、名前の属性値は列の属性値と同じです。
操作の追加、削除、変更、およびチェックの実装
package com.hibernate.ui;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hibernate.entity.User;
import com.hibernate.util.HibernateUtil;
public class Test {
public static void main(String[] args) {
// saveUser();
// getUserById();
updateUser();
//deleteUser();
//关闭SessionFactory
HibernateUtil.closeSessionFactory();
}
/*
* 增添操作
* */
public static void saveUser() {
Session session = null;
Transaction tx = null;
try {
//1. 打开Session
session=HibernateUtil.openSession();
//2. 开启数据库事务
tx = session.beginTransaction();
//3. 保存操作
User user=new User();
user.setName("李四");
user.setPassword("LiSi");
session.save(user);
//4. 提交事务
tx.commit();
} catch (Exception e) {
//捕获异常,事务回滚
tx.rollback();
} finally {
//5. 关闭Sesson,回收资源
session.close();
}
}
/*
* 查询操作
* */
public static void getUserById() {
//得到Session对象
Session session=HibernateUtil.openSession();
//参数1:要查询的对象类型,参数2:主键数值,最好是引用类型而不是基本类型
User user=session.get(User.class,new Integer(2));
System.out.println(user);
//打印时候为了美观,记得重写User类的toString方法
session.close();
}
/*
* 更新操作
* */
public static void updateUser() {
Session session = null;
Transaction tx = null;
try {
//1. 打开Session
session=HibernateUtil.openSession();
//2. 开启数据库事务
tx = session.beginTransaction();
//3. 更新操作(先查询,再修改,最后更新)
User user=session.get(User.class, new Integer(2));
user.setPassword("LiSi-2");
session.update(user);
//update方法更新时候,那条数据的所有项都更新了,哪怕没有变化
session.save(user);
//4. 提交事务
tx.commit();
} catch (Exception e) {
//捕获异常,事务回滚
tx.rollback();
} finally {
//5. 关闭Sesson,回收资源
session.close();
}
}
/*
* 删除操作
* */
public static void deleteUser() {
Session session = null;
Transaction tx = null;
try {
//1. 打开Session
session=HibernateUtil.openSession();
//2. 开启数据库事务
tx = session.beginTransaction();
//3.删除操作(先找到,再删除),实际删除的是数据库中的那条记录
User user=session.get(User.class, new Integer(1));
session.delete(user);
//4. 提交事务
tx.commit();
} catch (Exception e) {
//捕获异常,事务回滚
tx.rollback();
} finally {
//5. 关闭Sesson,回收资源
session.close();
}
}
}
単一エンティティ属性マッピング
マテリアライズされたクラスに対応するgetメソッドとsetメソッドがない場合、対応するデータは見つからず、インスタンス化はできません。これは、オブジェクトプロパティにアクセスするHibernateのデフォルトのメソッドです。
エンティティクラスの属性とテーブルフィールドが非対称の場合のマッピング
間接的なデータベースデータをクエリする必要がある場合
たとえば、totalOrders属性がユーザーテーブルに追加された場合、注文テーブルの総消費量をクエリする必要があります。
最初にordersデータベーステーブルordersを作成します。属性は次のとおりです。
次に、totalPrice属性をユーザーオブジェクトに追加し、対応するgetメソッドとsetメソッドを設定し、構築メソッドとtoStringメソッドを書き直して
、永続クラスの構成ファイルに対応する属性を追加します。
変更はクエリ操作であるため、テストクラスでクエリ操作を使用するたびに効果を確認できます。
休止状態の初期化
単一エンティティオブジェクト識別子のマッピング
自然な構成要素:たとえば、特定の実用的な意味を持つ学生の学生ID。
代理主キー方式がより一般的です。
Hibernateオブジェクト識別子OID(オブジェクトの識別)
Hibernateがこれら2つのオブジェクトがメモリ内の同じオブジェクトであるかどうかを区別するのに役立ちます。
U1を初めて照会するときは、メモリがないため、実際のクエリです
。U2は、メモリに結果があるかどうかを判断します。U1= U2であるため、U2はクエリを実行せず、U1を直接割り当てます。
パッケージにはすべての参照型があるため、便宜上、OIDを定義するときにラッパー型が使用されます。
主キーは一意であるため、OIDも一意です。
マッピングファイルのOID構成
ジェネレータはOID生成の方法を指定します
Hibernateには多くの識別子ジェネレータが付属しています。
increment 采用 Hibernate 数值递增的方式;
identity 采用数据库提供的自增长方式;
assigned 主键由应用逻辑产生;
---------上面三种是重点
sequence 采用数据库提供的序列方式;
hilo 通过hi/lo算法 // Hibernate 5.0 以后不支持;,高低位算法
seqhilo 通过hi/lo算法;
native 自动选择合适的标识符生成器;
uuid.hex 通过uuid算法。
インクリメント識別子の適用範囲
Hibernateプログラムによって生成されます。
まず、データベースの主キーの最大値を確認します。最大値+1がデータベースの新しいデータに保存されます。
SQLステートメントにスプライスされた主キーがあります
ID識別子の適用範囲
データベースは主キーを自動的にインクリメントできるため、SQLステートメントにはIDフィールドはありません。
割り当てられた識別子の範囲
値はプログラムによって割り当てられ、挿入する前に手動で割り当てる必要があります。値が割り当てられていない場合、挿入ステートメントは実行されません。
この方法は強くお勧めしません。人間の操作が繰り返される可能性があります。
プログラム内で値を割り当てる
単一エンティティをマッピングする注釈
アノテーションマッピングを設定する場合、マテリアライズクラスの設定ファイルを作成する代わりに、マテリアライズクラスを変更するだけで済みます。
美しくも不明瞭でもないため、推奨されません。焦点は上記のXML構成にあります。
@Entity:声明一个实体类。
@Table(name="table_name"):为实体类指定对应的数据库表。name就是表的名字
@Id:声明实体类的OID属性。
@GeneratedValue(generator="increment_generator"):声明OID的生成策略。
@GenericGenerator(name="increment_generator", strategy="increment"):使用Hibernate提供的生成策略。
先定义生成器,选择生存策略,然后被上面的注解调用。
どの属性がマップされ、どの列注釈が追加され
ます。属性名がデータベースフィールド名と一致している場合は省略できます。
マッピングファイルのソースを構成します
package com.hibernate.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
//声明一个实体类
@Table(name="CUSTOMER")
//为实体类指定对应的数据库
public class Customer {
private Integer id;
private String name;
private int age;
//创建两个构造方法,一个有参数,一个无参数,缺一不可
public Customer() {
super();
}
public Customer(Integer id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
@Id
//定义生成策略与别名,注意位置,在get,set方法之上
@GeneratedValue(generator = "linshi")
//应用下面定义的策略
@GenericGenerator(strategy="increment",name = "linshi")
//私有属性的get set方法
// @Column(name="id") 主键id自增长,所以可以注释掉
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@Override
public String toString() {
return "Customer [sum=" + sum + "]";
}
@Formula(value="(select sum(o.age) from customer as o where o.id>10)")
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}