学习hibernate笔记基础篇

使用JDBC做数据库相关功能开发会做很多重复性的工作,比如创建连接,关闭连接,把字段逐一映射到属性中。 Hibernate把这一切都封装起来了,使得数据库访问变得轻松而简单,代码也更加容易维护。
hibernate结构
MySQL数据库信息:
mysql

1
应用程序通过Hibernate把 一个 Product对象插入到数据库的product_表中
hibernate.cfg.xml 配置文件提供链接数据库的基本信息账号 密码 驱动 数据库ip 端口。
Product.hbm.xml 提供对象与表的映射关系、对应表、属性,对应字段。

实体类对象在Hibernate有三种状态
瞬时: 指的是没有和Hibernate发生任何关系,在数据库中也没有对应记录,一旦JVM结束,这个对象也就消失了。
持久:指的是一个对象和hibernate发生联系,有对应的session,并且在数据库中有对应的一条记录。
脱管:指的是一个对象虽然在数据库中有对应的一条记录,但是他所对应的Session已经关闭。
状态

HQL(Hibernate Query Language)是hibernate专门用于查询数据的语句,有别于SQL,HQL跟接近于面向对象的思维方式。
比如使用的是类的名字Product,而非表格的名字product_。

Product实体类;

public class Product {
    int id;
    String name;
    float price;
}

Product.hbm.xml映射实体类和数据库中的表;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.pojo">
    <!-- 本文件用于映射Product类对应的数据库中的表 -->
    <!-- Product类对应product_表 -->

    <class name="Product" table="product_">
        <!-- 表示属性id映射表里字段id -->
        <id name="id" column="id">
        <!-- id自增长方式采用数据库本地方式 -->
        <!-- 链接oracle时指定sequnce作为id自增长方式 -->
            <generator class="native">
            </generator>
        </id>
        <!-- 这里的name没有用column指定,说明字段名字也是name -->
        <property name="name" />
        <property name="price" />
    </class>

</hibernate-mapping>

hibernate.cfg.xml配置文件链接数据库启动、url、账号、密码等;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<!-- 本文件用于配置驱动、url、账号密码 -->
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <!-- SQL dialect -->
        <!-- 对于方言,只要告诉hibernate底层用的数据库,hibernate边用对应的方言对话。 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- hibernate事物管理方式,一个线程一个事物 -->
        <property name="current_session_context_class">thread</property>
        <!-- 表示是否在控制台显示sql语句 -->
        <property name="show_sql">true</property>
        <!-- 表示时候自动更新数据库的表结构 -->
        <property name="hbm2ddl.auto">update</property>
        <!-- 表示hibernate会识别Product这个实体类 -->
        <mapping resource="com/pojo/Product.hbm.xml" />
    </session-factory>

</hibernate-configuration>

TestHibernate测试类

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.pojo.Product;

public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        // hibernate基本步骤
        Session s = sf.openSession();// 获取SessionFactory,开启一个Session事物
        s.beginTransaction();// 通过SessionFactory获取一个Session

        /*
         * Product p = new Product(); p.setName("honor"); p.setPrice(1000);
         * s.save(p);//调用Session的save方法保存对象到数据库
         */
        /*
         * for (int i = 0; i < 10; i++) { Product p=new Product(); p.setName("honor"+i);
         * p.setPrice(i); s.save(p); }// 插入数据
         */

        Product p=new Product();
        p.setName("p1");
        System.out.println("此时p是瞬时的");
        s.save(p);
        System.out.println("此时p是持久的");


        s.getTransaction().commit();// 提交
        s.close();
        System.out.println("此时p是脱管的");
        sf.close();
    }
}
对象状态

new 了一个Product();,在数据库中还没有对应的记录,这个时候Product对象的状态是瞬时的。

通过Session的save把该对象保存在了数据库中,该对象也和Session之间产生了联系,此时状态是持久的。

最后把Session关闭了,这个对象在数据库中虽然有对应的数据,但是已经和Session失去了联系,相当于脱离了管理,状态就是脱管的

通过Id获取一个对象:

调用Session的get方法,根据id获取对象。 除了id之外,还需要传递一个类对象,毕竟需要知道获取的是哪个对象
除了使用get方法,还可以使用load获取对象。

        Product p=(Product) s.get(Product.class, 7);
        System.out.println("id=7的产品名称是:"+p.getName());
修改一个对象的属性,并更新到数据库中
        Product p = (Product) s.get(Product.class, 6);
        System.out.println("id=6的产品名称是:" + p.getName());
        p.setName("iphone-modified");
        s.update(p);
使用HQL根据name进行模糊查询
  1. 首先根据hql创建一个Query对象
  2. 设置参数(和基1的PreparedStatement不一样,Query是基0的)
  3. 通过Query对象的list()方法即返回查询的结果了。

注: 使用hql的时候,用的是类名Product,而不是表名product_
注: 使用hql的时候,不需要在前面加 select *

        String name = "iphone";
        Query q = (Query) s.createQuery("from Product p where p.name like ?");
        q.setString(0, "%" + name + "%");
        List<Product> list=q.list();
        for (Product product : list) {
            System.out.println(product.getName());
        }
使用Criteria,根据name进行模糊查询

使用Criteria 查询数据
1. 通过session的createCriteria创建一个Criteria 对象
2. Criteria.add 增加约束。 在本例中增加一个对name的模糊查询(like)
3. 调用list()方法返回查询结果的集合

除此之外,Criteria 还可以很方便的进行进行分页查询和获取总数

Criteria c=s.createCriteria(Product.class);
        c.add(Restrictions.like("name", "%"+name+"%"));
        List<Product> list=c.list();
        for (Product product : list) {
            System.out.println(product.getName());
        }
使用标准的sql,根据name进行模糊查询

使用Session的createSQLQuery方法执行标准SQL语句

因为标准SQL语句有可能返回各种各样的结果,比如多表查询,分组统计结果等等。 不能保证其查询结果能够装进一个Product对象中,所以返回的集合里的每一个元素是一个对象数组。 然后再通过下标把这个对象数组中的数据取出来。

        String sql = "select * from product_ p where p.name like '%" + name + "%'";
        Query q = s.createSQLQuery(sql);
        List<Object[]> list = q.list();
        for (Object[] objects : list) {
            for (Object object : objects) {
                System.out.print(object+"\t");
            }
            System.out.println();
        }
posted @ 2018-01-24 20:55  小沐酱  阅读(113)  评论(0编辑  收藏  举报