学习hibernate笔记基础篇
使用JDBC做数据库相关功能开发会做很多重复性的工作,比如创建连接,关闭连接,把字段逐一映射到属性中。 Hibernate把这一切都封装起来了,使得数据库访问变得轻松而简单,代码也更加容易维护。
MySQL数据库信息:
应用程序通过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进行模糊查询
- 首先根据hql创建一个Query对象
- 设置参数(和基1的PreparedStatement不一样,Query是基0的)
- 通过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();
}