hibernate的增删改查

首先了解一下 hibernate的五大核心控制器:

1.Configuration接口:

       Configuration对象用于配置并根启动Hibernate。Hibernate应用通过Configuration实例来指定对象—关系映射文件的位置或者动态配置Hibernate的属性,然后创建SessionFactory实例。

2.SessionFactory接口:

SessionFactroy接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。用到了工厂模式。

需要注意的是:

    它是线程安全的.说明同一个实例可以被应用的多个线程共享

    它不是轻量级的(是重量级).意味着不能随意创建或者销毁它的实例.如果应用之访问一个数据库,只需要创建一个SessionFactory实例.如果应用同时访问多个数据库,则需要为每个数据库创建一个单独的SessionFactory实例.

    之所以说他是是重量级,是因为SessionFactory需要一个很大的缓存,用来存放预定义的SQL语句,以能映射元数据等.用户也可以为SessionFactory配置一个缓存插件--二级缓存.该缓存用来存放被工作单元读过的数据,将来其他工作单元可能会重用这些数据,因此这个缓存中的数据能够被所有的工作单元共享,一个工作单元通常对应一个数据库事务

3.Session接口:

Session接口是Hibernate应用使用最广泛的接口.Session也被称为持久化管理器.提供了和持久化相关的操作:增删改查等(这个和前端的Session不一样)

    Session不是线程安全的,因此在设计软件架构时,应该避免多个线程共享同一个Session实例

    Session实例是轻量级的,所谓轻量级,是指他的创建和销毁不需要消耗太多的资源.这意味着在程序中可以经常创建和销毁Session对象,例如为每个客户请示分配单独的Session实例,或者为每个工作单元分配单独的Session实例

    Session有一个缓存,被称为Hibernate的一级缓存.它存放被当前工作单元加载的对象,每个Session实例都有自己的缓存,这个Session实例的缓存只能被当前工作单元访问.

     Session接口 Session 接口对于Hibernate 开发人员来说是一个最重要的接口。然而在Hibernate中,实例化的Session是一个轻量级的类,创建和销毁它都不会占用很多资源。这在实际项目中确实很重要,因为在客户程序中,可能会不断地创建以及销毁Session对象,如果Session 的开销太大,会给系统带来不良影响。但是Session对象是非线程安全的,因此在你的设计中,最好是一个线程只创建一个Session对象。 session可以看作介于数据连接与事务管理一种中间接口。我们可以将session想象成一个持久对象的缓冲区,Hibernate能检测到这些持久对象的改变,并及时刷新数据库。我们有时也称Session是一个持久层管理器,因为它包含这一些持久层相关的操作, 诸如存储持久对象至数据库,以及从数据库从获得它们。需要注意的是,Hibernate的session不同于JSP 应用中的HttpSession。当我们使用session这个术语时,我们指的Hibernate 中的session,而我们以后会将HttpSesion 对象称为用户session。

4.Transaction接口

        Transaction接口负责事务相关的操作,一般在Hibernate的增删改中出现,但是使用Hibernate的人一般使用Spring去管理事务。

该接口是Hibernate的数据库事务接口.他对底层的事务接口做了封装

底层事务接口包括JDBC API、JTA(Java Transaction API)、CORBA(Common Object Requet Broker Architecture)API

Hibernate应用可通过抑制的Transaction接口来声明事务边界,这有助于应用在不同的环境容器中移植.

尽管应用也可以绕过Transaction接口,直接访问底层的事务接口,但这种方法不值得推荐,因为他不利于应用在不同的环境移植

Query接口(和Criteria接口)

该接口是Hibernate的查询接口,用于向数据库查询对象,以及控制执行查询的过程.Query是包装了一个HQL查询语句.HQL查询语句和SQL查询语句有些相似,但是HQL查询语句是面向对象的,他引用类句及类的属性句,而不是表句及表的字段句.(也就是说,引用的是类和成员属性,而非表名和字段名)

Create接口完全封装了基于字符串的查询语句,比Query接口更加面向对象,Criteria接口擅长执行动态查询.

Query可以使用HQL语言或SQL语句两种表达方式。它的返回值一般是List。需要自己转换。

--------------------------------------------------------------------------------------------------------------------------------

//加载  hibernate.cfg.xml      Configuration是入口,通过它来获得配置文件
Configuration config = new Configuration().configure();

//加载sessionFactory对象(session工厂)
SessionFactory sFactory = config.buildSessionFactory();

//加载session对象
Session session = sFactory.openSesion();

//hibernate不会自动提交事务  我们需要手动提交开启事务
Transaction ts = session.beginTransaction();
            //提交事务后虽然可以再次开启事务,但是一般我们不这样做.sessionFactory属于二级缓存,太耗费资源

加载前两个对象的代码可以封装一下写在一个类的方法里,方法返回的值是session对象,这样每次调用该方法就可以直接获取一个session对象,用该对象开启事务

//提前设置好一个Student类  并配置hbm.xml映射文件  在cfg.xml文件中引入该映射文件  
//该类字段分别为 主键:学号-Integer        姓名-String        年龄-Integer
//学号为主键,唯一,自增

以上的准备工作最好之后,我们就可以在事务里面做增、删、改、查的操作

增加学生

Student student = new Student();
student.setAge(18);
student.setName("小明");

session.save(student);        //把该对象存进数据库里
//为了防止保存失败,把它放到try里
try{
 session.save(student);
tr.commit();            //操作完成后提交事务
}catch{
  if(ts != null){
       ts.rollback();            //防止异常再报一个异常 让他回滚
    }
}finally{
  session.close();    //不管是否成功,记得关闭session
}

只要给该学生类 的每个属性赋值.通过save方法保存进数据库就好了.  注意为了防止出错而写的tru-catch,每个操作都要记得放在try-catch里

查询数据:get和load方法

//get:单条数据             第一个参数:类的class对象  第二个参数:表中主键的值
//load:单条查询             参数和get一样,该方法和get相似,但还是有区别
  //get是立即加载,而load是延时加载
    //查询时.如果使用load方法.load方法会延时:查询的时候他并没有直接通过sql语句去查询结果,而是只得到要查询记录的ID(主键),
        //只有当我们要使用查询记录中的其他字段值时,他才会真正的去表中查询
        //如果查询到的结果是null  get会返回null 而load会报异常
//HQL:多条查询
//get方法查询
Student student = session.get(Student.class,new Integer(1));    //直接写1是int类型 
这样查询到的就是一个学生类啦,可以通过该类的getter方法或重写toString方法来获取该学生的值

//load方法查询
Student student = session.get(Student.class,new Integer(1));
student.getSid();        //调用该方法的时候是没有去查找的,因为Sid是主键,是自己给的(参数就是)
student.getName();        //这才是真正的去查找了

int和Integer的区别  详情可见http://blog.csdn.net/u012110719/article/details/46367365

//HQL查询  这是hibernate的查询语言
String hql = "from Student where name=?0"
Query<Student> query = session.createQuery(hql).setParameter(0,"小明");

List<Student> list = query.list();        //把结果用.list方法转化成list集合
for(Student student : list){
    System.out.println(student);
}

删除数据&修改数据

//修改数据和删除数据只能根据ID来进行操作,且一次只能操作一个对象

//删除数据步骤:创建需要删除的对象-->成员变量对应sql中where后面的条件(主键)-->通过delete方法删除对象
Student deleteStu = new Student;    //要删除的对象
deleteStu.setSid(1);                //该对象的id
session.delete(deleteStu);          //参数是要删除的对象
//也不是一定要创建要删除的对象,也可以通过get或load方法从数据库里获取该数据然后删除

但是该方法一次只能删除一个对象,所以我们可以通过HQL查询出要删除的对象,通过遍历的方式删除他们

String hql = "select sid from student where name=?0";            //0是占位符的ID  新特性,下面要根据下标来赋值
Query query = session.createQuery(sql).setParameter(0,"小明");    //得到所有"小明"的学号 
List<Integer> deleteSid = query.list();    
for(Student sid = deleteSid){
    Student student = new Student();
    student.setSid(sid);            //把学号给一个学生类,再把该类删除(也就从数据库中删除了)
    session.delete(student);        //这种方法比较麻烦,可以直接查询到学生 然后删除学生
}

//如果是个集合用list,确认只有一个结果或者没结果用uniqueResult

修改数据

//修改数据和删除数据差不多 都是找到某个对象  然后用session给update一下这个对象  
//  不过中间要set一下要修改的成员变量(字段),参数是新值
Student student = new Student();
student.setSid(1);    //先用ID确定要赋值的是哪条数据 ,主键是无法修改的
student.setAge(99);        //设置要修改的变量     
session.update(student);    //开始修改!

//修改完可以去数据库看一下,看看改好了没.

//  PS:设置过的变量会被修改,没设置的会变成null(除了主键)

//一次只能修改一条数据,所以也可以用删除数据的方法:     用HQL遍历,然后逐条删除
String hql = "from student where name=?0"; 
Query query = session.createQuery(sql).setParameter(0,"小红");    //得到所有"小明"的学号 
List<Student> updateSid = query.list();
for(Student sid = updateSid){
    session.delete(student);        //直接删除该对象
}

猜你喜欢

转载自blog.csdn.net/Y2418230874/article/details/81044773