一、Hibernate - 核心接口

它是  JBoss Community team (社区团队) 开发的。Hibernate 是一个开源的,对象关系模型框架 (ORM),它对JDBC进行了轻量的封装, 使java程序员可以面对象的方式进行数据库操作。Hibernate 一共有5个核心接口

1.Session

用于连接数据库,相当于 jdbc 中的 Connection (它和 servlet 中 的Session  一点关系也没有),负责执行对象的CRUD操作 ,它是非线程安全的。

2.SessionFactory //用于得到 Session ,相当于jdbc中 DriverManager

3.Transaction //用于事务管理

4.Query 和 Criteria //主要用于查询数据

5.Configuration //用于得到配置信息

二、Hibernate - 类库简介

Hibernate3.jar

antlr-2.7.6.jar(必需):Hibernate使用ANTLR来产生查询分析器,这个类库在运行环境下时也是必需的。

dom4j(必需):Hibernate使用dom4j解析XML配置文件和XML映射元文件。

commons-collections-3.1,CommonsLogging(必需):Hibernat使用ApacheJakartaCommons项目提供的多个工具类库。

dom4j-1.6.1(可选):Hibernate使用CommonsLoggingAPI,它也可以依次使用Log4j作为底层实施log的机制。

如果上下文类目录中存在Log4j库,则CommonsLogging使用Log4j和并它在上下文类路径中寻找的log4j.properties文件。

你可以使用在Hibernate发行包中包含中的那个示例Log4j的配置文件。这样,把log4j.jar和它的配置文件(位于src/目录中)拷贝到你的上下文类路径下,就可以在后台看到底程序如何运行的。

javassist-3.12.0.GA 一个开源的分析、编辑和创建Java字节码的类库

slf4j-api-1.6.1 为java提供的简单日志Facade。Facade:门面,更底层一点说就是接口

jta-1.1.jar  Java事务API( Java Transaction API )

其他文件是不是必需的:请察看Hibernate发行包中的lib/README.txt文件,这是一个Hibernate发行包中附带的第三方类库的列表,他们总是保持最新的。你可以在那里找到所有必需或者可选的类库(注意:其中的 "buildtimerequired" 指的是编译Hibernate时所需要而非编译你自己的程序所必需的类库)。

三、第一个Hibernate 程序

1) 导包

2) 配置文件

1)Hibernate 的主配置文件

 <?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://Hibernate.sourceforge.net/Hibernate-configuration-3.0.dtd"> <Hibernate-configuration> <session-factory>
<property name="show_sql">true</property> //把生成的sql显示出来
<property name="dialect">org.Hibernate.dialect.MySQLDialect</property> //指定数据库用的方言
<property name="connection.url">jdbc:mysql://localhost:3306/shop</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="myeclipse.connection.profile">mysql_cat</property> <mapping resource="cat/beans/AdminInfo.hbm.xml" /> //引入一个映射文件 </session-factory> </Hibernate-configuration>

可以查找 Hibernate-3.6.10.Final\project\etc\Hibernate.properties  这个文件,找到相应的配置项和内容。

2) 实体类

public class AdminInfo {
private int id;
private String adminName;
private String password;
private String note;
... get set 方法
}

3) 生成实体类的映射文件  AdminInfo.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE Hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://Hibernate.sourceforge.net/Hibernate-mapping-3.0.dtd"> <Hibernate-mapping package="cat.beans">
<class name="AdminInfo"> <id name="id" >
<generator class="native"/> <!-- 指明主键的生成策略 -->
</id> <property name="adminName" />
<property name="password" />
<property name="note" /> </class>
</Hibernate-mapping>

3)测试

public class Test {
public static void main(String[] args) {
test();
}
//可能出现的问题
//1 Unknown entity: cat.beans.AdminInfo 原因是没有把映射文件引入到主配置文件
//2 为什么没有真正的添到数据库中呢,因为没有开启事务
public static void test(){
//读配置文件
Configuration cxf=new Configuration();
cxf.configure(); //会去读配置文件,扩号中可以写上配置文件的名称,也可以不写,如果不写,默认读 Hibernate.cfg.xml 这个文件 //创建SessionFactory对象
SessionFactory sessionFactory=cxf.buildSessionFactory(); //创建Session对象
Session session= sessionFactory.openSession(); //开启事务
Transaction tx= session.beginTransaction();
AdminInfo admin=new AdminInfo();
admin.setAdminName("管理员Hibernate");
admin.setPassword("adminaaa");
admin.setNote("这是第一个用户用Hibernate添加的");
session.save(admin); //提交事务
tx.commit();
session.close(); System.out.println("操作成功");
System.out.println(admin.getId()); //它居然能得到id }
}

说明: 对于 beans 中的 实体类(AdminInfo) ,没有什么特别的要求(但必须要有get 和set  ),但必须有一个无参的构造方法,最好不要声明为 final 的, 对懒加载有影响。对映射文件的要求和简单说。

1) 通常,命名是 类名.hbm.xml => AdminInfo.hbm.xml

2) 可以在一个映射文件中,映射多个类,但通常不推荐这么做

3)

<Hibernate-mapping package="cat.beans">  //这里的package可以不写,但如果不写,下面的 要写成全类名
<class name="AdminInfo" > 如果上面的package不写,这里要写成 <class name="cat.beans.AdminInfo" >
....

4) 一些属性是有默认值的,可以明确的指定值,也可以使用默认值

<class name="AdminInfo" table="adminInfo" >
<id name="id" >
<generator class="native" /> //native 主键生成器,会根据不同的数据库选择不同的主键生成方式
</id> <property name="adminName" column="aminName" type="string"/>
<property name="password" />
<property name="note" />
</class>

四、工具类和标准的代码
工具类代码实例

package cat.hibutils;

import org.Hibernate.Session;
import org.Hibernate.SessionFactory;
import org.Hibernate.cfg.Configuration; public class HibUtil {
private HibUtil(){} //防止别人创建本类的实例
private static SessionFactory _factory; static{
Configuration cxf=new Configuration();
cxf.configure();
_factory=cxf.buildSessionFactory();
} //得到Session
//Session 对象是线程不安全的
public static Session getSession(){
return _factory.openSession();
} //得到 SessionFactory
public SessionFactory getSessionFactory(){
return _factory;
} //关闭连接
public static void close(Session s){
if(s!=null){
s.close();
}
} } //标准的添加方法
public static void main(String[] args) {
AdminInfo admin=new AdminInfo();
admin.setAdminName("标准方法添的用户");
admin.setPassword("123");
add(admin); System.out.println("用户添加成功");
} //标准的add方法
public static void add(AdminInfo admin){
Session s=null;
Transaction tx=null;
try{
s=HibUtil.getSession();
tx=s.beginTransaction();
s.save(admin);
tx.commit();
}
catch(Exception ex){
if(tx!=null){
tx.rollback();
}
ex.printStackTrace();
}finally{
HibUtil.close(s);
}
} //精简的写法
public static void simpleAdd(AdminInfo admin){
Session s=null;
Transaction tx=null;
try {
s=HibUtil.getSession();
tx=s.beginTransaction();
s.save(admin);
tx.commit();
}
finally{
HibUtil.close(s);
}
}

五、使用 threadLocal

public class HibUtil {
private HibUtil(){} //防止别人创建本类的实例
private static SessionFactory _factory;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); static{
Configuration cxf=new Configuration();
cxf.configure();
_factory=cxf.buildSessionFactory();
} //得到Session
//Session 对象是线程不安全的
public static Session getSession(){
//return _factory.openSession();
Session s=threadLocal.get();
if(s == null){
s=_factory.openSession();
threadLocal.set(s);
}
return s;
} //得到 SessionFactory
public SessionFactory getSessionFactory(){
return _factory;
} //关闭连接
public static void closeSession(){
Session s=threadLocal.get();
threadLocal.set(null); if(s!=null){
s.close();
}
}
} public static void simpleAdd(AdminInfo admin){
Session s=null;
Transaction tx=null;
try {
s=HibUtil.getSession();
tx=s.beginTransaction();
s.save(admin);
tx.commit();
}
finally{
HibUtil.closeSession(); //关连接的时候,可以这样关
}
}

六、Session接口

几个常用的方法

1) save , persist 保存数据,  persist 在事务外不会产生insert语句

2) delete 删除对象

3) update 更新一个对象,如果数据库中没有对应的记录,将出错

4) get 根据ID查询对象,会立刻访问数据库

5) load 根据ID查询对象 (返回的是代理对象,不会立即访问数据库,懒加载)

6) saveOrUpdate (根据ID和version来决定是要保存还是要更新) , merge (调用 merge 你的对象还是脱管的)

7) lock 把对象变成持久对象,但不会同步对象的状态

 //例子,使用get查询用户

public static void main(String[] args) {
AdminInfo admin=getAdmin(89);
System.out.println(admin);
} public static AdminInfo getAdmin(int id){
try{
Session s=HibUtil.getSession();
return (AdminInfo)s.get(AdminInfo.class, id); }finally{
HibUtil.closeSession();
}
}
//例子,使用load方法进行查询
public static AdminInfo loadAdmin(int id){
try{
Session s=HibUtil.getSession();
AdminInfo admin= (AdminInfo)s.load(AdminInfo.class, id);
return admin; //如果这里不直接访问 admin 对象,则返回的是代理,并不是真正查询出来的数据 }finally{
HibUtil.closeSession();
}
} public static void main(String[] args) {
AdminInfo admin=loadAdmin(89);
System.out.println(admin.getAdminName()); //could not initialize proxy - no Session 不能初始化代理对象,因为没有session了
}

七、对象状态   

1.瞬时 (transien) : 数据库中没有数据与之对应,超过作用域就失效,会被垃圾回收器回收。一般的 new 出来的对象,且与session无关

2.持久 (persistent): 数据库中有数据与之对应,与 Session有关联,而且相关的Session没有关闭,事务还没有提交, 持久对象的状态发生改变, 在事务提交的时候,会保存到数据库 (Hibernate会检测到)

3.脱管 (detached) ,数据库中有数据与之对应, 但当前没有Session与之关联, 脱管对象状态发生改变也不会影响到数据库

瞬时: 自由人

持久: 法庭上被审问中的人,有案底 , 所有的话都是呈堂证供

脱管: 审完了,放了的人 , 有案底,但言论自由

八、封装简单的操作到HibUtil

//增加
public static void add(Object obj){
Session s=null;
Transaction tx=null;
try{
s=getSession();
tx=s.beginTransaction();
s.save(obj);
tx.commit(); }finally{
closeSession();
}
} //删除
public static void del(Object obj){
try{
Session s=getSession();
Transaction tx=s.beginTransaction();
s.delete(obj);
tx.commit(); }finally{
closeSession();
}
} //修改
public static void update(Object obj){
Session s=null;
Transaction tx=null;
try{
s=getSession();
tx=s.beginTransaction();
s.update(obj);
tx.commit(); }finally{
closeSession();
}
} //查询
public static Object get(Class clazz, Serializable id){
try{
Session s=getSession();
return s.get(clazz, id);
}finally{
closeSession();
}
}

九、HQL

public class AdminDao {
//根据用户名和密码查询用户
public AdminInfo getLoginAdmin(String adminName,String password){
try{
Session s=HibUtil.getSession();
String hql="from AdminInfo a where a.adminName= ? and a.password= ?"; //AdminInfo 必须是对象名,不能是表名
Query q=s.createQuery(hql);
q.setString(0, adminName); //注意,它是从0开始的
q.setString(1, password); AdminInfo admin= (AdminInfo)q.uniqueResult(); //只返回一对象,如果返回的不是一条数据,将出现异常 query did not return a unique result 54
return admin; }finally{
HibUtil.closeSession();
}
} //查询所有用户
@SuppressWarnings("unchecked")
public List<AdminInfo> getAllAdmin(){
try{
Session s=HibUtil.getSession();
/* Query q =s.createQuery("from AdminInfo");
return q.list(); //返回一个列表
*/
return s.createQuery("from AdminInfo").list(); }finally{
HibUtil.closeSession();
}
}
}

生成测试用例 :

在类上,右键, new 输入 other , 搜索 junit 然后一步步添加即可。

public class AdminDaoTest {
private AdminDao dao; @BeforeClass //注解
public static void setUpBeforeClass() throws Exception {
//主要用于对静态成员进行初始化
} @AfterClass
public static void tearDownAfterClass() throws Exception {
} @Before //表示在执行之前做的处理
public void setUp() throws Exception {
dao=new AdminDao();
} @After //执行之后做的处理
public void tearDown() throws Exception {
System.out.println("测试完毕"); //在每个方法执行完后都会调用
} @Test
public void testGetLoginAdmin() {
AdminInfo admin=dao.getLoginAdmin("aaaaaaa", "aaa"); if(admin==null){
System.out.println("没查到");
}
else{
System.out.println(admin);
}
} @Test
public void testGetAllAdmin() {
List<AdminInfo> list=dao.getAllAdmin(); for (AdminInfo a:list) {
System.out.println(a);
}
}
}

HQL 的补充说明

1)上面的写法

String hql="from AdminInfo a where a.adminName= ? and a.password= ?";

也可以不用别名,如下:

String hql="from AdminInfo  where adminName= ? and password= ?"

2) 可以使用命名参数

String hql="from AdminInfo a where a.adminName=:aname and a.password= :pwd ";   //AdminInfo 必须是对象名,不能是表名
Query q=s.createQuery(hql);
q.setString("aname", adminName); //注意,它是从0开始的
q.setString("pwd", password);

3) Query 接口有个种set 方法, 可以对指定类型的参数进行传入

4) 可以使用  setFirstResult  和  setMaxResults 进行结果集过滤,实现分页查询

public List<AdminInfo> getAdminList(int beginRow,int pageSize){
try{
Session s=HibUtil.getSession();
Query q=s.createQuery("from AdminInfo");
q.setFirstResult(beginRow);
q.setMaxResults(pageSize); return q.list(); }finally{
HibUtil.closeSession();
}
}

5) 查询数据行数

public int getAdminCount(){
try{
Session s=HibUtil.getSession();
Query q=s.createQuery("select count(*) from AdminInfo"); //后面是对象名,
long count=(Long)q.uniqueResult();
return new Integer(count+""); }finally{
HibUtil.closeSession();
}
}

补充:HQL 常见的查询

// 使where
Query q=s.createQuery("from AdminInfo where id not between 10 and 20"); //查询id不在10 到20之间的 // 使用in
Query q=s.createQuery("from AdminInfo where AdminName in('张三','李四','王五')"); //只要在这个('张三','李四','王五')集合中含有的,就查出来 // 使用 like
Query q=s.createQuery("from AdminInfo where AdminName like %赵%"); // 查询名字中含有赵的所有用户 // 使用 null
Query q=s.createQuery("from AdminInfo where note is null"); //查询所有备注为null的用户 // 使用 and
Query q=s.createQuery("from AdminInfo where note is null and id<5"); //查询备注信息是null而且id<5的用户 // 执行删除
Query q=s.createQuery("from AdminInfo where password is null"); // 批量删除:
public void delAdmins(String password){
try{
Session s=HibUtil.getSession();
Transaction tx=s.beginTransaction();
Query q=s.createQuery("delete from AdminInfo where password= :pwd");
q.setString("pwd", password);
q.executeUpdate(); //执行删除 tx.commit(); }finally{
HibUtil.closeSession();
}
}

Java框架之Hibernate(一)的更多相关文章

  1. java框架篇---hibernate入门

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDB ...

  2. Java框架之Hibernate(三)

    本文主要讲解: 1 级联 cascade 关键字 2 级联删除 3 inverse 关键字 4 懒加载 5 缓存的模拟 6 Hibernate 的一级缓存 7 Hibernate 的二级缓存 一.级联 ...

  3. JAVA框架之Hibernate框架的学习步骤

    首先介绍一下Java三大框架的关系 以CRM项目即客户关系管理项目示例 hibernate框架的学习路线: 1.学习框架入门,自己搭建框架,完成增删改查的操作 2.学习一级缓存,事物管理和基本查询 3 ...

  4. java框架之Hibernate(1)-简介及初使用

    简介 hibernate 是一个开源 ORM ( Object / Relationship Mipping ) 框架,它是对象关联关系映射的持久层框架,它对 JDBC 做了轻量级的封装,而我们 ja ...

  5. java框架之Hibernate(2)-持久化类&主键生成策略&缓存&事务&查询

    持久化类 概述 持久化:将内存中的对象持久化到数据库中的过程就是持久化.Hibernate 就是用来进行持久化的框架. 持久化类:一个 Java 对象与数据库的表建立了映射关系,那么这个类在 Hibe ...

  6. java框架篇---hibernate之缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  7. JAVA框架之Hibernate【配置文件详解】

    Hibernate配置文件主要功能是配置数据库连接和Hibernate运行时所需的各种属性,配置文件应该位于JAVA应用或者JAVA Web应用的类文件中,刚开始接触Hibernate的时候,感觉Hi ...

  8. 【JAVA框架】Hibernate 与Mybatis 区别

    Hibernate Mybatis 简介 区别 与联系 欢迎提出见解及转载. 1 简单简介     1.1    Hibernate 框架          Hibernate是一个开放源代码的对象关 ...

  9. Java框架之Hibernate(四)

    本文主要介绍: 1 悲观锁和乐观锁 2 使用版本号控制并发访问 3 flush方法和批量更新的问题 4 DetachedCriteria 5 N + 1 次查询 6 使用sql进行查询 7 注解方式 ...

随机推荐

  1. 某pdf转word v6.3.0.2算法分析

    某pdf转word v6.3.0.2算法分析 [文章标题]某pdf转word v6.3.0.2算法分析 [文章作者]jieliuhouzi[原版下载]www.pdfcword.cn [保护方式]序列号 ...

  2. Android Service组件在新进程绑定(bindService)过程

    1.首先看两个样例 (1)进程内 Client端 public class CounterService extends Service implements ICounterService { .. ...

  3. Nginx平台构架

    深入理解Nginx模块发开与架构解析读书笔记. nginx在启动后,在unix系统中会以daemon的方式(能够手动关闭 nginx.conf daemon off)在后台执行,后台进程包括一个mas ...

  4. CSS3实现的一批hover特效

    本特效的原版是codepen上面的hover.css项目.个人非常喜欢所以把全部的hover特效自己也写了一遍,上传文件麻烦所以直接把css整合到HTML代码中了.代码复制下来保存后就可以用浏览器打开 ...

  5. Hadoop2.4.1伪分布式安装

    本教程的前提是已经在VMware虚拟机上安装了centos6.5,centos的安装过程这里不再赘述 一.准备Linux环境 1.点击VMware快捷方式,右键打开文件所在位置 -> 双击vmn ...

  6. springmvc返回json字符串中文乱码问题

    问题: 后台代码如下: @RequestMapping("menuTreeAjax") @ResponseBody /** * 根据parentMenuId获取菜单的树结构 * @ ...

  7. 理解Vue中的Render渲染函数

    理解Vue中的Render渲染函数 VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数.比如如下我想要实现 ...

  8. 《软件测试的艺术(原书第2版)》【PDF】下载

    <软件测试的艺术(原书第2版)>[PDF]下载链接: https://u253469.ctfile.com/fs/253469-231196343 内容简介 本书以一次自评价测试开篇,从软 ...

  9. springboot 入门六-多环境日志配置

    在应用项目开发阶段,需要对日志进入很详细的输出便于排查问题原因,上线发布之后又只需要输出核心的日志信息的场景.springboot也提供多环境的日志配置.使用springProfile属性来标识使用那 ...

  10. layui样式修改记录

    记录以免遗忘: .layui-elem-quote{ padding 15 改为 5 }