SSH框架(hibernate)

本文介绍Hibernate ORM框架的基本概念,包括其作为对象关系映射工具如何简化数据库操作,并提供了一个简单的入门示例,涵盖配置文件、映射文件及基本的CRUD操作。
一.什么是hibernate。
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,
 是一个全自动的 orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命 意义的是,
 Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
 Hibernate是一个持久层的ORM框架。


二.hibernate入门。
   *创建映射
映射文件通常有一个命名规则:类名.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>
<!-- ORM:Object Relational Mapping,将实体类O和数据库的表R 建立映射关系 -->
<!-- 
class标签:用来描述类与表的映射关系。
* name :类的全路径的。(Object)
* table :数据库中的表名称。(Relational)
* 如果类名和表名称一致的话,那么table可以省略。
* catalog :数据库名称
-->
<class name="com.lk.hibernate.domain.Customer" table="cst_customer">
<!-- 类中的属性与表中的主键对应 -->
<!-- 
id标签:用来描述类中的OID与表中的主键建立映射。
* name :类中的属性名称。
* column :表中的字段名称。
* 如果类中的属性名称和表中的字段名称一致,column可以省略。
* length :字段的长度。(Hibernate自动建表的时候)
* type :数据类型。
* Java的数据类型
* Hibernate的数据类型
* SQL的数据类型
-->
<id name="cust_id" column="cust_id" type=""//数据类型可以省略>
<!-- 主键生成策略: -->
<generator class="native"/>
</id>
<!-- 类中的属性与表中的字段对应如果名字一样可以省略 -->
<!-- 类中的属性与表中的字段对应 -->
<!-- 
property标签:用来描述类中的属性与表中的字段建立映射 
* name :类中的属性名称。
* column :表中的字段名称。
* 如果类中的属性名称和表中的字段名称一致,column可以省略。
* length :字段的长度。(Hibernate自动建表的时候)
* type :数据类型。
* Java的数据类型
* Hibernate的数据类型
* SQL的数据类型
-->
<property name="cust_name" column="cust_name"/>
<property name="cust_source" column="cust_source"/>
<property name="cust_industry" column="cust_industry"/>
<property name="cust_level" column="cust_level"/>
<property name="cust_phone" column="cust_phone"/>
<property name="cust_mobile" column="cust_mobile"/>
<!-- 在多的一方配置many-to-one -->
<!-- 
many-to-one标签:用来描述多对一的关系配置。
* name :一的一方的对象的属性名称。
* class :一的一方的类的全路径
* column :外键的名称
-->
<many-to-one name="customer" class="com.lk.hibernate.domain.Customer" column="lkm_cust_id"/>
//cascade="save-update,delete"哪一方保存关联另一方就在保存的一方配置这个属性.inverse="true"消除产生的多余sql

/*
<!-- 配置多对多的映射 -->
<!-- 
set标签
* name :多对多另一方的集合的属性名称
* table :多对多建立的中间表的名称。
-->
<set name="roles" table="sys_user_role" cascade="save-update,delete" >
<!-- 
key标签:描述外键
* column:当前对象在中间表的外键的名称
-->
<key column="user_no"/>
<!-- 
many-to-many标签:多对多配置
* class:对方的类的全路径
* column:对方在中间表的外键名称
-->
<many-to-many class="com.lk.hibernate.domain.Role" column="role_no"/>
</set>*/
</class>
</hibernate-mapping>
   *创建Hibernate.cfg.xml的核心配置文件
<?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>
<session-factory>
<!-- 连接数据库的信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<!-- 数据库的方言:根据底层的数据库生成不同的SQL -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 配置格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 配置hbm2ddl -->
<property name="hibernate.hbm2ddl.auto">update</property>
/*hibernate.hbm2ddl.auto有几个取值
none:不使用映射转成DDL。
create:如果原来有表将原有的表删除。每次都会新创建一个表。测试的时候使用。
create-drop:如果原来有表将原有的表删除。每次都会新创建一个表。执行完操作以后会将表删除掉。测试的时候使用。
update:如果数据库中有表使用原来的表。如果没有表会创建一个表。而且可以更新原有表结构。
validate:不会创建表。校验映射和表结构是否正确*/
<!-- 配置C3P0连接池 可以省略-->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目  -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
<!-- 加载映射文件 -->
<mapping resource="com/itheima/hibernate/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
   *java代码实现
public class HibernateDemo2 {
@Test
/**
* 级联保存:
* * 保存客户同时级联保存联系人。
* * 保存的主体对象是客户对象,那么就需要在Customer.hbm.xml文件中配置。
* * 在<set>标签上配置cascade="save-update"
* 保存的主体对象是联系人对象,那么就需要在LinkMan.hbm.xml文件中配置。
* * 在<many-to-one>标签上配置cascade="save-update"
* 保存客户
*/
public void demo1(){
// 加载Hibernate的核心配置文件.
Configuration configuration = new Configuration().configure();
// 创建一个SessionFactory的对象.
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 创建Session(相当于JDBC中的Connection)
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_name("梁");
session.save(customer);
session.update(customer);
tx.commit();
session.close();
}

@Test
/**
* 查询某个对象
* 面试:get方法和load方法的区别?
* * get方法采用的是立即加载,执行到该行代码的时候,马上发送SQL语句进行查询。查询之后返回的是真实对象本身。
* 查询一个找不到的对象返回null.
*  * load方法采用的是延迟加载(lazy),执行到改行的代码的时候,不会马上发送SQL语句,
*   只有真正使用这个对象的时候(使用这个对象的普通属性的时候)才会发送SQL语句。
*      load方法返回的是代理对象。(产生的是Customer的子类对象)
*      查询一个找不到的对象抛出异常:ObjectNotFoundException
*/
/**
* 级联删除:
* * 删除客户同时级联删除联系人。
* * 在Customer.hbm.xml中的<set>上配置cascade="delete"
 在删除的时候要先查询一下在删除
* 删除联系人同时级联删除客户。
* * 在LinkMan.hbm.xml中在<many-to-one>上配置cascade="delete"
*/
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 调用session.get()方法查询某个对象。
//Customer customer = session.get(Customer.class, 100l);// 马上发送SQL语句.
// 调用session.load()方法查询某个对象。
Customer customer = session.load(Customer.class, 300l);// 不会马上发送SQL语句.
System.out.println(customer);
tx.commit();
session.close();
}

@Test
/**
* 修改某个对象
*/
public void demo3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// 1.直接创建对象进行修改.(没有设置的属性会被修改为null)
/*Customer customer = new Customer();
customer.setCust_id(4l);
customer.setCust_name("梁如花");
session.update(customer);*/
// 2.先查询再修改.(推荐)
Customer customer = session.get(Customer.class, 4l);
customer.setCust_name("梁如花");
session.update(customer);
tx.commit();
session.close();
}

@Test
/**
* 删除某个对象
*/
public void demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

// 1.直接new 对象 删除
/*Customer customer = new Customer();
customer.setCust_id(2l);

session.delete(customer);*/

// 2.先查询,在删除(推荐)
Customer customer = session.get(Customer.class, 3l);
session.delete(customer);

tx.commit();
session.close();
}


@Test
/**
* 查询某个对象
*/
public void demo1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//基本查询
Criteria criteria = session.createCriteria(Customer.class);
//排序查询
//Criteria criteria = session.createCriteria(Customer.class);
//criteria.addOrder(Order.asc("cust_id")); 升序
//criteria.addOrder(Order.desc("cust_id"));降序
//条件查询
//Criteria criteria = session.createCriteria(Customer.class);
//criteria.add(Restrictions.like("cust_name", "%强%"));
//criteria.add(Restrictions.like("cust_name", "强", MatchMode.ANYWHERE));
//criteria.add(Restrictions.eq("cust_source", "网络营销"))
//分页查询
Criteria criteria = session.createCriteria(LinkMan.class);
Criteria.setFirstResult(10);
Criteria.setMaxResults(10);
//离线条件查询
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
detachedCriteria.add(Restrictions.like("cust_name", "%强%"));
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
//多表查询待定
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
}
   *整合ssh时
HibernateTemplate常用的方法
*Serializable save(Object entity) :添加操作
* void update(Object entity) :修改操作
* void delete(Object entity) :删除操作
*<T> T get(Class<T> entityClass, Serializable id) :根据id查询
*<T> T load(Class<T> entityClass, Serializable id): 根据id查询
  *List find(String queryString, Object... values) :查询操作的方法
public class demo1{
@Resource(name="hibernateTemplate")
private HibernateTemplate hibernatetemplate;
public void demo1(){
// (1),hql语句
String hql = "from t_user where username = ? and password = ?";
// (2),执行
List<User> list = (List<User>) this.getHibernateTemplate().find(hql, user.getUsername(),user.getPassword());
}


三.高级应用
<set>
fetch:抓取策略,控制SQL语句的发送的格式。
* select :默认值。发送一条select语句查询关联对象。
* join :发送一条迫切左外连接查询关联对象。
* subselect :发送一条子查询查询关联对象。
lazy:延迟加载,控制SQL语句的发送的时候。
* true :默认值。采用延迟加载。
* false :不采用延迟加载。
* extra :及其懒惰。

<many-to-one>
fetch:抓取策略,控制SQL语句的发送的格式。
* select :默认值.发送一条select语句查询关联对象。
* join :发送一条迫切左外连接查询关联对象。
lazy:延迟加载,控制SQL的发送的时机。
* proxy :默认值。是否采用延迟,需要由另一方类上的延迟加载来决定。
* false :不采用延迟加载。
* no-proxy:不用研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NPC程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值