1,简介
JDBC中的SQL语句由开发者编写,Hibernate中SQL是动态生成。
数据表变化,JDBC的SQL语句需要修改,Hibernate只需修改实体类配置即可。
推荐使用@方式配置实体类,因为@对所有ORM框架都通用,是JPA框架。
主要类:
SessionFactory:线程安全的Session工厂类,维护包括数据库连接池,缓存数据等信息;
Session:代表用户一次操作。通过SessionFactory.openSession()生产;通过session.close()关闭。维护包括Transaction,当前数据库连接等信息;
Transaction:代表一次事务,可使用各种事务机制,如JTA、第三方事务管理、数据库事务等。
2,实体类
指与数据库有映射关系的Java类,一般推荐POJO:
@Entity//@Entity表示该类能被Hibernate持久化
@Table(name="user")//指定该Entity对应的数据表名
public class User {
@Id//指定该列为主键
@GeneratedValue(strategy=GenerationType.AUTO)//主键类型,auto为自增长类型
private Integer userid;
@Column(name="username")//指定username属性对应的列名为username
private String username;
@Column(name="password")//同上,@Column与name均可省略
private String password;
注:
1>@Transient标注临时属性,不会被持久化
2>主键最好使用可为null的类型,如Integer、Long
3>必须使用javax.persistence.*的注解,不能使用org.hibernate.*的注解
3,Hibernate配置文件
<hibernate-configuration>
<session-factory>
<!-- JDBC配置代码 -->
<property name="myeclipse.connection.profile">MySQL Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/fortest</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- SQL语句方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 为每一个线程生成一个Session -->
<!-- Hibernate启动时创建表结构 -->
<property name="hbm2ddl.auto">create</property>
<property name="curent_session_context_class">thread</property>
<!-- 在控制台打印sql语句 -->
<property name="show_sql">true</property>
<!-- 配置需要让Hibernate管理的实体类和对应的表 -->
<mapping class="com.hellobbboy.pojo.User" />
</session-factory>
</hibernate-configuration>
注:1>hbm2ddl.auto可取值:
create:加载SessionFactory时,创建表结构;如原表结构存在,则删除原表结构;如classpath下游import.sql文件,创建表结构后执行import.sql中的语句。
create-drop:与create相同,但在SessionFactory卸载时,删除表结构。
update:加载SessionFactory时检查表结构,如果不一致则更新表结构。
validate:加载SessionFactory时检查表结构。
2>curent_session_context_class参数在Web程序中必须配置:如使用JBoss等内置Hibernate的容器,配置为jta;其他容器如Tomcat等,配置为thread
3>配置文件也可采用properties格式,但不可配置实体类。
4>一个配置文件对应维护一个数据库,如在程序中操作多个数据库,只需相应配置多个文件,生成多个SessionFactory,来操作多个数据库。
5>Hibernate推荐,在容器中运行的程序,数据库配置为JNDI,程序通过JNDI获取数据库连接,事务将自动由容器维护。
4,Hibernate工具类
5,执行Hibernate
1>通过HibernateSessionUtil的SessionFactory开启一个Session
2>开启一个Transaction
3>通过Session执行操作
4>提交Transaction
5>关闭Session
Session session=HibernateSessionFactory.getSessionFactory().openSession();
Transaction transaction=session.beginTransaction();
session.persist(user1);
transaction.commit();
session.close();
6,配置数据库连接池
只需在Hibernate配置中添加hibernate.c3p0.*参数,Hibernate自动使用c3p0数据库连接池。
7,复杂映射关系
面向对象中,一对多,多对一,多对多,是对象引用持有关系。
在数据库中,通过表关联实现。
1>单边一对多
例如逻辑上,一个用户可拥有多个游戏角色。
面向对象中,一个用户引用要持有一个列表,列表中是游戏角色对象引用,但游戏角色对象中没有用户任何信息。
在数据库中,则是通过在角色表中添加“用户_id”列,并且将该列与用户表的id关联。
角色类是纯POJO,用户类如下:
@OneToMany(fetch = FetchType.EAGER, targetEntity = Role.class, cascade = {
CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE,
CascadeType.REFRESH })
@JoinColumns(value={@JoinColumn(name="roleuserid",referencedColumnName="userid")})//会自动为role表生成roleuserid列,并关联user表的userid列。
private List<Role> roles=new ArrayList<Role>();
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
2>单边多对一
例如逻辑上,一个论文拥有一个论文类别。
面向对象中,一个论文引用拥有一个类别引用,类别引用中没有论文引用。
在数据库中,则是通过在论文表中添加“类别_id”列,并且将该列与论文表的id关联。
类别类是纯POJO,论文类如下:
@ManyToOne(fetch = FetchType.EAGER,cascade = {CascadeType.PERSIST})
@JoinColumn(name="typeid")//会自动为Article表生成typeid列,并关联type表的主键。
private Type type;
3>双边多对一,一对多关系