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();
		}

多对一关系

Category实体类

一个Product对应一个Category
一个Category对应多个Product

Product和Category是多对一的关系

public class Category {
	int id;
	String name;
    
}
Category.hbm.xml
<!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">
	<class name="Category" table="category_">
		<id name="id" column="id">
			<generator class="native">
			</generator>
		</id>
		<property name="name"></property>
	</class>
</hibernate-mapping>
在Product实体类中增加Category属性
Category category;
在Product.hbm.xml中设置Category多对一关系

使用many-to-one 标签设置多对一关系
name=“category” 对应Product类中的category属性
class=“Category” 表示对应Category类
column=“cid” 表示指向 category_表的外键

<many-to-one name="category" class="Category" column="cid"></many-to-one>
在hibernate.cfg.xml增加Category的映射
<mapping resource="com/pojo/Category.hbm.xml"/>
测试many-to-one
Category c = new Category();
		c.setName("c1");
		s.save(c);

		Product p = (Product) s.get(Product.class, 5);
		p.setCategory(c);
		s.update(p);
category_ 表可以自动生成

一对多

Category和Product是一对多的关系

Category实体类加set集合
Set<Product> products;
Category.hbm.xml增加one-to-many映射
<!-- set用于设置一对多关系,或用list,name="products" 对应Category类中的products属性 lazy="false"表示不使用加载延时 -->
		<set name="products" lazy="false">
			<!-- 表示外检是cid,可以为空 -->
			<key column="cid" not-null="false"></key>
			<!-- 表示一对多的类是Product -->
			<one-to-many class="Product" />
		</set>
TestHibernate测试one-to-many关系
Category c=(Category) s.get(Category.class, 2);
		Set<Product> ps=c.getProducts();
		System.out.println();
		for (Product product : ps) {
			System.out.println(product.getName());
		}
posted @ 2018-01-24 20:55  小沐酱  阅读(0)  评论(0编辑  收藏  举报  来源