hibernate框架说明:
hibernate是一个orm框架,与之类似的是MyBatis(更轻量级)
两个框架各有特点,只要指定好对应的数据库驱动,可以支持Oracle,My Sql,Ms Sql Server等多种主流关系型数据库,这两个框架不需要太多关注具体的sql语句实现。
hibernate相比可能较更难上手一点
Hibernate是一个全自动的ORM映射工具,配置好cfg,建好映射hbm,它可以自动生成sql语句,并执行返回java结果
准备工作:
eclipse下载hibernate 插件:
在help->Eclipse MarketPlace中搜索JBossTool,也可以去官网搜索,注意插件有多个版本,每个版本对应eclipse的唯一一个版本,两者是一一对应的关系,安装插件时要选对
Maven 本地部署:
参考链接:
https://www.runoob.com/maven/maven-setup.html
hibernate使用:
1.添加pom.xml 引用:(hibernate的版本在官网上查更新的版本号)
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.0.Final</version>
</dependency>
2.添加cfg.xml
右键选中项目-new-other
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!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.microsoft.sqlserver.jdbc.SQLServerDriver
</property>
<property name="hibernate.connection.url">jdbc:sqlserver://127.0.0.1:1433;databaseName=kjtx_TVSensor
</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">password</property>
<property name="show_sql">false</property>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect
</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping
resource="com/xxx.....xxx.hbm.xml" />
</session-factory>
</hibernate-configuration>
属性:
hibernate.connection.driver_class:数据库驱动
hibernate.connection.url:数据库地址(带端口号)
hibernate.connection.username:用户名
hibernate.connection.password:密码
show_sql:是否显示自动生成的sql语句
hibernate.dialect:数据库方言(对于Ms SqlServer:org.hibernate.dialect.SQLServerDialect)
hibernate.current_session_context_class:hibernate的currentSession绑定对象(填Thread或其他),指定后即可通过调用sessionFactory.getCurrentSession()方法
hibernate.hbm2ddl.auto:自动创建|更新|验证数据库表结构
validate:加载hibernate时,验证创建数据库表结构
create:每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
create-drop:加载hibernate时创建,退出是删除表结构
update:加载hibernate自动更新数据库结构
映射资源:
mapping resource
指定hbm.xml文件的相对路径(在src下的相对路径)
3.建立关系映射:
根据需求创建数据库表,设计相关字段,根据表创建对应的类,成员属性的类型应和数据库中字段对应
参考链接
除此之外,对于时间,可以用时间戳(即在java中用Date或者long),也可以用字符串,将日期格式化成yyyy-MM-dd hh:mm:ss之类的格式
除此之外,类应该符合以下几点:
1.对所有需要映射的成员属性,需要生成getter 和setter(建议所有成员属性为private,通过public 的getter 和setter开放对外操作)
不生成getter和setter,则必须要对此类使用序列化接口Serializable,并且指定一个序列化ID
(这两个操作在映射文件中字段的access属性有所区别)
2.该类可以部分成员属性映射数据库
3.一个类只能有一个映射文件(hibernate中的hql是基于类的,而不是基于表的)
4.根据需要重写hashCode及equals方法
这个并不是强制性的,但是在一些特殊场合,重写了对缓存管理中可能会有作用
5.命名规范:成员属性的第一个字母是大写,每个单词的第一个字母是大写
虽然有时这个没啥用,就一个规范问题。
生成映射文件:
右键点击上步创建的类,new-> other->Hibernate XML Mapping file(hbm.xml)
创建后直接在默认模板上修改即可
class节点中,name:类,table:表名,默认生成时和类同名,且转为全大写的状态
首先需要检查自动生成的主键id,是否正确
hibernate中必须要有指定的主键,关系型数据库中有一些表可以什么都没有,但是在hibernate中不同,每个object都要是唯一的,没有主键时,可以加一个自增字段id,或者使用复合主键(比较麻烦,不推荐)
hibernate的映射关系:
一对一 或 一对多,多对一
一对一:比较常见,也比较简单,成员属性不局限于基本类型,也可包括其他的映射类
一对多:某个类中的某个成员属性可能和其他映射类有关
(没有所谓的多对一)
比如说
一个学生只有一个老师:是一对一
一个老师有多个学生:是一对多
class Teacher{
Set<Student> students;//一个老师有多个学生
......
}
class Student{
Teacher teacher;//只有一个老师
......
}
<?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">
<!-- Generated 2020??2??25?? ????2:53:15 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.Model.AlarmRecord" table="ALARMRECORD"><!--类及对应的表-->
<id name="id" type="int"><!--属性名称及类型-->
<column name="ID" /><!--主键列名 -->
<generator class="native" /><!--主键递增或默认自动生成:native 不需指定,positive 需要指定-->
</id>
<property name="deviceid" type="java.lang.Integer"><!--属性名称及类型-->
<column name="DEVICEID" /><!--列名-->
</property>
............
</class>
</hibernate-mapping>
除此生成映射文件的方式,也可以通过注解的方式代替
参考链接
感觉这样会更省事,但是后续可能代码上不太直观,维护起来比较麻烦
4.hibernate基本使用
SessionFactory:
包含数据库配置信息,主要用于获取Session
Configuration cfg = new Configuration().configure(cfgName);//加载配置文件
//除了配置文件中声名属性外,也可通过代码指定其属性
String user = ConfigsManager.getString("DBuser");
cfg.setProperty(Environment.URL, "jdbc:sqlserver://" + url + ";databaseName=" + DBname);
cfg.setProperty(Environment.USER, user);
cfg.setProperty(Environment.PASS, DBpwd);
sessionFactory = cfg.buildSessionFactory();//创建工厂
getSession().setFlushMode(FlushMode.AUTO);//设置缓存模式(此模式自动释放一级缓存)
session:
每个session就是一个数据库链接,session的每一个操作都是在事物下的(数据库事物:对数据库的一系列操作,要么成功,要么中间出现一步出错,则全部回滚,保持一致性的手段)
session能做的事很多,大概分为以下几类:
1.原生sql语句
2.存储过程
public Session getSession() {
return sessionFactory.getCurrentSession();
}
/**
* 执行sql语句更新
*
* @param sql sql语句
*/
public void ExcuteUpdate(String sql) {
try {
Session session = getSession();
session.beginTransaction();
SQLQuery query = session.createSQLQuery(sql);
query.executeUpdate();
session.getTransaction().commit();
} catch (Exception e) {
// TODO: handle exception
ReConnected(0);
}
}
/**
* 执行存储过程
*
* @param queryString hql语句
* @param params 参数
* @return 存储过程是否调用成功
*/
public boolean executeVoidProcedureSql(final String queryString, final Object[] params) {
Session ProceDureSession = getSession();
try {
ProceDureSession.doWork(new Work() {
public void execute(Connection conn) throws SQLException {
CallableStatement call = conn.prepareCall("{" + queryString + "}");
if (null != params) {
for (int i = 0; i < params.length; i++) {
call.setObject(i + 1, params[i]);
}
}
call.execute();
}
});
return true;
} catch (Exception e) {
// TODO: handle exception
return false;
}
}
3.维护对象和关系映射
对象在hibernate中分为三种状态:
1)自由态:
在 对象被实例化时
2)持久态:
对象已被保存在数据库中,在缓存与数据库之间的一种状态,缓存中的修改,会被同步到数据库之中
3)游离态:
从持久态变为游离态,即脱离了数据库,这个对象在数据库中可能存在一条记录,就算存在,也不一定完全同步
自由态到持久态是单向的(其实自由态等价于游离态)
游离态和持久态可以相互转换
参考链接
hql语句:
对于平时的sql语句,查询一般是:
select * from 表名 where 条件
而对于hql,面向的是对象
from 类名 where 条件
参考链接
简单使用:
String hql = "From AlarmType";
Session session = sessionFactory.openSession();
session.beginTransaction();
Query query = session.createQuery(hql);
List List = query.list();
session.getTransaction().commit();
session.clear();
session.close();
saveorUpdate (差不多的还有save Update)
/**
* 新增或保存
*
* @param obj Object
*/
public void saveOrUpdate(Object obj) {
try {
Session session = getCacheSession();
session.beginTransaction();
session.saveOrUpdate(obj);
session.getTransaction().commit();
session.clear();
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 批量新增或保存
*
* @param collections Collection<?>
*/
public void saveOrUpdate(Collection<?> collections) {
try {
Session session = getCacheSession();
session.beginTransaction();
collections.forEach(a -> {
try {
session.saveOrUpdate(a);
} catch (Exception e) {
// TODO: handle exception
System.out.println(a.getClass().getName());
System.out.println(e.getLocalizedMessage());
}
});
session.getTransaction().commit();
session.clear();
} catch (Exception e) {
}
}
Refresh(差不多的还有load等)
/**
* 刷新
*
* @param obj Object
*/
public void Refresh(Object obj) {
try {
Session session = getCacheSession();
session.refresh(obj);
} catch (Exception e) {
return;
}
}
4.缓存
缓存的作用是降低访问数据库的频率
类比cpu cache 硬盘之间的关系
hibernate中分为三级缓存,
主要用的是一级缓存(Session的)
其次的二级,三级(基本没怎么用)
参考链接1
参考链接2