【Hibernate】(2)Hibernate的核心接口、增删改查操作、主键ID生成方式、查询方式

一、Hibernate的核心接口

1、Configuration接口

Configuration 接口负责管理Hibernate 的配置信息。为了能够连上数据库必须配置一些属性,这些属性包括:
数据库URL
数据库用户
数据库用户密码
数据库JDBC驱动类
数据库dialect,用于对特定数据库提供支持,其中包含了针对特定数据库特性的实现。

/创建一个配置对象,读取配置文件/
Configuration config = new Configuration();
config.configure(“/hibernate.cfg.xml”);

2、SessionFactory接口

应用程序从SessionFactory(会话工厂)里获得Session(会话)实例。这里用到了一个设计模式即工厂模式,用户程序从工厂类SessionFactory中取得Session的实例。SessionFactory不是轻量级的。它占的资源比较多,所以它应该能在整个应用中共享。一个项目通常只需要一个SessionFactory就够了,但是当项目要操作多个数据库时,必须为每个数据库指定一个SessionFactory。

会话工厂缓存了生成的SQL语句和Hibernate在运行时使用的映射元数据。它也保存了在一个工作单元中读入的数据并且可能在以后的工作单元中被重用(只有类和集合映射指定了使用这种二级缓存时才会如此)Session类。

/通过配置对象产生一个会话工厂/
SessionFactory factory=config.buildSessionFactory();

3、Session接口

该接口是Hibernate使用最多的接口。Session不是线程安全的,它代表与数据库之间的一次操作。Session是持久层操作的基础,相当于JDBC中的Connection。然而在Hibernate中,实例化的Session是一个轻量级的类,创建和销毁它都不会占用很多资源。Session通过SessionFactory打开,在所有的工作完成后,需要关闭。但如果在程序中,不断地创建以及销毁Session对象,则会给系统带来不良影响。所以有时需要考虑session的管理合理的创建合理的销毁。

/通过工厂产生一个会话/
Session session=factory.openSession();

4、Query类

Query类可以很方便地对数据库及持久对象进行查询,它可以有两种表达方式:查询语句使用HQL(HQL是Hibernate Query Lanaguage的简称,是Hibernate配备的一种非常强大的查询语言,类似于SQL)或者本地数据库的SQL语句编写。

/通过会话产生一个查询对象/
Query query = session.createQuery(“from Dept”);
/通过查询对象查询数据库,返回集合/
List list = query.list();
for (int i = 0; i < list.size(); i++) {
Dept dept = (Dept) list.get(i);
System.out.println(dept.getDname());
}

5、Transaction接口

如果你向数据库中增加数据或修改数据时,需要使用事务处理,这时你需要Transaction接口。Transaction接口是对实际事务实现的一个抽象,该接口可以实现JDBC的事务、JTA中的UserTransaction、甚至可以是CORBA事务等跨容器的事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移值。

6、一个完整示例,显示了Hibernate编程基本思路

/创建一个配置对象,读取配置文件/
String configfile=”/hibernate.cfg.xml”;
Configuration config=new Configuration();
config.configure(configfile);
/通过配置对象产生一个会话工厂类/
SessionFactory sessionfactory=config.buildSessionFactory();
/通过会话工厂类产生一个会话实例/
Session session=sessionfactory.openSession();
/通过会话产生一个查询对象Query/
Query query=session.createQuery(“from bean.Customer”);
/进行查询返回一个集合List/
List cuslist=query.list();
for(Customer cus:cuslist){
System.out.println(cus.getCustomerId()+
” “+cus.getName()+” “+cus.getPhone());
}

二、Hibernate常见操作

如果利用Hibernate修改数据库时,需要使用事务处理,一个事务提交时才真正将修改过的记录更新到数据库中。

1、增加记录

Session session=HibernateSessionFactory.getSession();
/定义事务开始/
Transaction tran=session.beginTransaction();
Dept dept=new Dept(new Long(1001),”math”,”shanghai”);
session.save(dept);
/提交事务,真正保存到数据库中/
tran.commit();

2、 删除记录

public static void main(String[] args) {
Session session=HibernateSessionFactory.getSession();
/首先查找待删除记录 通过ID/
Dept dept=(Dept)session.get(Dept.class,new Long(10));
Transaction tran=session.beginTransaction();
session.delete(dept);
tran.commit();
}

3、修改记录

public class Demo {
public static void main(String[] args) {
Session session= HibernateSessionFactory.getSession();
Transaction tran=session.beginTransaction();
/首先查找待修改记录 通过ID/
Dept dept=(Dept)session.get(Dept.class,new Long(10));
dept.setDname(“math”);
session.saveOrUpdate(dept);
tran.commit();
}
}

三、Hibernate主键ID生成方式

数据库中表有主键、主键的唯一性决定了数据库表中记录唯一。缓存在Session中的数据即实例都有一个唯一的ID,ID映射了数据库中主键。那么ID如何产生呢?

1、assigned

主键由外部程序负责生成,无需Hibernate参与。即当增加一个实体时,由程序设定它的ID值(手工分配值)。

<class name="bean.Customer" table="customers" catalog="support">
        <id name="customerId" type="java.lang.String">
            <column name="customerID" length="8" />
            <generator class="assigned"></generator>
        </id>
        .......
</class>

2、identity

在DB2、SQL Server、MySQL等数据库产品中表中主键列可以设定是自动增长列,则增加一条记录时主键的值可以不赋值。用数据库提供的主键生成机制。

(1) 表结构:
create table test1 ( tid int not null primary key auto_increment,
name char(40));
(2) 映射文件

<class name="bean.Test1" table="test1" catalog="support">
    <id name="tid" type="java.lang.Integer">
        <column name="tid" />
        <generator class="identity"></generator>
    </id>
    <property name="name" type="java.lang.String">
        <column name="name" length="40" />
    </property>
</class>

3、increment

主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。

<class name="bean.Test2" table="test2" catalog="support">
    <id name="tid" type="java.lang.Integer">
        <column name="tid" />
        <generator class="increment"></generator>
    </id>
    <property name="name" type="java.lang.String">
        <column name="name" length="40" />
    </property>
</class>

4、sequence

采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence,在Oracle中创建序列:create sequence hibernate_sequence;

当需要保存实例时,Hibernate自动查询Oracle中序列”hibernate_sequence”的下一个值;该值作为主键值。可以改变默认的序列名称。

<id name="sid" type="java.lang.Integer">
     <column name="sid" />
     <generator class="sequence"></generator>
</id>

5、native

由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。

6、uuid.hex

由Hibernate为ID列赋值,依据当前客户端机器的IP、JVM启动时间、当前时间、一个计数器生成串,以该串为ID值。

<class name="bean.Test3" table="test3" catalog="support">
     <id name="tid" type="java.lang.String">
         <column name="tid" length="50" />
         <generator class="uuid.hex"></generator>
     </id>
     <property name="name" type="java.lang.String">
         <column name="name" length="40" />
     </property>
</class>

四、Hibernate的查询方式

Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。但是不要被语法结构上的相似所迷惑,HQL(Hibernate query lauguage) 被设计为完全面向对象的查询。

HQL对关键字的大写小并不区分,但是对查询的对象就要区分大小写,因为它是面向对象的查询,所以查询的是一个对象,而不是数据库的表,在sql中如果要加条件的话就是列,而在HQL里面条件就是对象的属性,而且还要给对象起别名。

1、Hibernate查询 HQL语句

限制查询结果记录数与起始记录
Session session=HibernateSessionFactory.getSession();
Query query=session.createQuery(“from Customer”);
query.setFirstResult(10); //设置查询记录开始位置,索引从0开始。
query.setMaxResults(10);//设置查询返回的最大记录个数。
List list=query.list();
注意:条件查询
Session session=HibernateSessionFactory.getSession();
Query query=session.createQuery(“from Customer cus where cus.name=’zhou’”);

2、取表中部分列时

(1) 单一属性查询。还是返回一个集合,只不过集合中存储的不是表的实例而是对象。

Session session = null;
session = HibernateSessionFactory.getSession();
List cnames = session.createQuery(“select cname from Customer”).list();
for (int i=0;i< cnames.size();i++) {
String name = (String)cnames.get(i);
System.out.println(name);
}

(2) 多个属性的查询,使用对象数组。

Session session = null;
session = HibernateSessionFactory.getSession();
//查询多个属性,其集合元素是对象数组
//数组元素的类型,跟实体类的属性的类型相关
List students = session.createQuery(“select sno, sname from Students”).list();
for (int i=0;i< students.size();i++) {
Object[] obj = (Object[])students.get(i);
System.out.println(obj[0] + “, ” + obj[1]);
}

(3) 多个属性的查询,使用List集合装部分列

Session session = HibernateSessionFactory.getSession();
Query query = session.createQuery(“select new list(cus.name,cus.phone) from Customer cus”);
List list = query.list();
for (int i = 0; i < list.size(); i++) {
List temp=(List)list.get(i);
System.out.println(temp.get(0)); //0是索引
}

(4) 使用Map集合装部分列

Session session = HibernateSessionFactory.getSession();
Query query = session.createQuery(“select new map(cus.name,cus.phone) from Customer cus”);
List list = query.list();
for (int i = 0; i < list.size(); i++) {
Map temp=(Map)list.get(i);
System.out.println(temp.get(“1”)); //”1”是key
}

3、内连接

Query query=session.createQuery(“select c.name, s.name from Student s join s.classes c “).list();
for (Iterator iter = students.iterator();iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + “, ” + obj[1]);
}

4、外连接

select c.name, s.name from Classes c left join c.students s
select c.name, s.name from Classes c right join c.students s

5、带参数的查询

(1) ?作为参数 如” from Customer cus where cus.name=?”;

Session session = HibernateSessionFactory.getSession();
Query query = session.createQuery(“from Customer cus where cus.name=?”);
query.setParameter(0, “zhou”);
List list = query.list();

(2) 参数名称 :name 如” from Customer cus where cus.name=:name”;

Session session = HibernateSessionFactory.getSession();
Query query = session.createQuery(“from Customer cus where cus.name=:name “);
query.setParameter(“name”, “zhou”);
List list = query.list();

助理解:
用?参数时,设置参数需用序号(0,1,2,3…)等依次赋值,如果参数比较多,容易赋错
因此,出现采用参数名称的方式,这种方式可以一对一准确地进行赋值。

(3) 条件查询,使用 ?的方式传递参数

Query query = session.createQuery(“SELECT s.id, s.name FROM Student s WHERE s.name LIKE ?”);
query.setParameter(0, “%周%”); //传递参数参数的索引是从0开始的。 如条件查询,使用”:参数”名称的方式传递参数
Query query = session.createQuery(“SELECT s.id, s.name FROM Student s WHERE s.name LIKE :myname”);
query.setParameter(“myname”, “张三”);//传递参数
因为setParameter方法返回Query接口,所以可用省略方式来查询
List students = session.createQuery(“SELECT s.id, s.name FROM Student s WHERE s.name LIKE :myname and s.id = :myid”)
setParameter(“myname”, “%周%”).setParameter(“myid”, 15).list();

6、嵌入原生sql测试

SQLQuery sqlQuery = session.createSQLQuery(“select * from t_student”);
List students = sqlQuery.list();
for (Iterator iter = students.iterator();iter.hasNext();) {
Object[] obj = (Object[])iter.next();
System.out.println(obj[0] + “, ” + obj[1]);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值