hibernate 基础

时间:2021-08-02 15:34:10

Hibernate:是开源的ORM框架技术,对jdbc进行了非常轻量级的对象封装,处于业务逻辑层和数据库层之间,称作持久化层。

持久化层的作用:把程序生成的对象持久化到数据库,也就是保存到数据库。

hibernate 基础

 hibernate执行流程

hibernate 基础

1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件(下述代码简略解释)

*****
public Configuration configure() throws HibernateException {
configure( "/hibernate.cfg.xml" );
return this;
}
*****
    public Configuration configure(String resource) throws HibernateException {
LOG.configuringFromResource( resource );
InputStream stream = getConfigurationInputStream( resource );
return doConfigure( stream, resource );
}
*****
protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {
try {
ErrorLogger errorLogger = new ErrorLogger( resourceName );
Document document = xmlHelper.createSAXReader( errorLogger, entityResolver )
.read( new InputSource( stream ) );
if ( errorLogger.hasErrors() ) {
throw new MappingException( "invalid configuration", errorLogger.getErrors().get( 0 ) );
}
doConfigure( document );
}
catch (DocumentException e) {
throw new HibernateException( "Could not parse configuration: " + resourceName, e );
}
finally {
try {
stream.close();
}
catch (IOException ioe) {
LOG.unableToCloseInputStreamForResource( resourceName, ioe );
}
}
return this;
}
*****
protected Configuration doConfigure(Document doc) throws HibernateException {
Element sfNode = doc.getRootElement().element( "session-factory" );
String name = sfNode.attributeValue( "name" );
if ( name != null ) {
properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
}
addProperties( sfNode );
parseSessionFactory( sfNode, name ); Element secNode = doc.getRootElement().element( "security" );
if ( secNode != null ) {
parseSecurity( secNode );
} LOG.configuredSessionFactory( name );
LOG.debugf( "Properties: %s", properties ); return this;
}
*****
private void addProperties(Element parent) {
Iterator itr = parent.elementIterator( "property" );
while ( itr.hasNext() ) {
Element node = (Element) itr.next();
String name = node.attributeValue( "name" );
String value = node.getText().trim();
LOG.debugf( "%s=%s", name, value );
properties.setProperty( name, value );
if ( !name.startsWith( "hibernate" ) ) {
properties.setProperty( "hibernate." + name, value );
}
}
Environment.verifyProperties( properties );
}
*****
    private void parseSessionFactory(Element sfNode, String name) {
Iterator elements = sfNode.elementIterator();
while ( elements.hasNext() ) {
Element subelement = (Element) elements.next();
String subelementName = subelement.getName();
if ( "mapping".equals( subelementName ) ) {
parseMappingElement( subelement, name );
}
else if ( "class-cache".equals( subelementName ) ) {
String className = subelement.attributeValue( "class" );
Attribute regionNode = subelement.attribute( "region" );
final String region = ( regionNode == null ) ? className : regionNode.getValue();
boolean includeLazy = !"non-lazy".equals( subelement.attributeValue( "include" ) );
setCacheConcurrencyStrategy( className, subelement.attributeValue( "usage" ), region, includeLazy );
}
else if ( "collection-cache".equals( subelementName ) ) {
String role = subelement.attributeValue( "collection" );
Attribute regionNode = subelement.attribute( "region" );
final String region = ( regionNode == null ) ? role : regionNode.getValue();
setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region );
}
}
}

总结来说就是在Configuration类中有一个properties变量,通过类加载器动态的加载xml中配置的变量(session-factory,property,mapping),并且以key,value键值对的方式保存在properties中。

2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息或者<mapping class="xxx">读取解析entity注释信息

3.通过config.buildSessionFactory();//创建SessionFactory

    public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException {
LOG.debugf( "Preparing to build session factory with filters : %s", filterDefinitions ); buildTypeRegistrations( serviceRegistry );
secondPassCompile();
if ( !metadataSourceQueue.isEmpty() ) {
LOG.incompleteMappingMetadataCacheProcessing();
} validate(); Environment.verifyProperties( properties );
Properties copy = new Properties();
copy.putAll( properties );
ConfigurationHelper.resolvePlaceHolders( copy );
Settings settings = buildSettings( copy, serviceRegistry ); return new SessionFactoryImpl(
this,
mapping,
serviceRegistry,
settings,
sessionFactoryObserver
);
}

简单来说就是SessionFacrory是一个重量级的容器,里面包含了配置文件的所有信息,ServiceRegistry等等。

4.sessionFactory.openSession();//打开Sesssion

* JDBC {@link Connection connection(s} will be obtained from the
* configured {@link org.hibernate.service.jdbc.connections.spi.ConnectionProvider} as needed
* to perform requested work.

通过org.hibernate.service.jdbc.connections.spi.ConnectionProvider配置返回一个JDBC Connection

5.session.beginTransaction();//创建事务Transation

6.persistent operate持久化操作 //一般指Save这个方法

7.session.getTransaction().commit();//提交事务

8.关闭Session

9.关闭SesstionFactory

操作示例:

public class test_add {
SessionFactory sessionFactory; @Before
public void sessionFacroty() {
Configuration cfg = new Configuration(); cfg.configure(); ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).build(); try {
sessionFactory = cfg.buildSessionFactory(sr);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
} @Test
public void add() {
Session session = sessionFactory.openSession();
session.beginTransaction();
Students stu = new Students();
session.save(stu);
session.getTransaction().commit();
session.close();
}
}

Configuration:用来创建SessionFactory实例

常见方法:Configuration configure()   :Use the mappings and properties specified in an application resource named hibernate.hbm.xml

SessoinFactory:一个application对应一个SessionFactory实例,它被创建以后其内部的hibernate配置和映射关系是固定不变的,对于请求,它会创建Session实例

常用方法:Session  openSession()

Sessoin  getCurrentSession()

Session:对于SessionFactory建立的每个轻量级的Session,相当于对数据库的一次Connecion,每当需要与数据库进行交互的时候就实例化一个Session,Session中封装了持久化实例。

常见方法:void save()

void update()

void delete()

SQLQuery createSQLQuery(String queryString)   Create a SQLQuery instance for the given SQL query string.

Object get(Class clazz, Serializable id)     Return the persistent instance of the given entity class with the given identifier

Transaction:对数据库操作的封装对象,在session执行CRUB操作后,必须手动提交事务,对象才会写入数据库,也可以设置自动提交:

注:使用Session的doWork方法,重写execute方法,虽然不用提交事务,但Sesion.save()后需要Session.flush();

hibernate 基础

常用方法:void begin()

void commit()

hibernate.cfg.xm常见配置

详情见:http://www.cnblogs.com/kundeg/p/7153452.html

hibernate.show_sql--打印出sql语句

hibernate.format_sql--格式化sql语句

hibernate.dialect-数据库方言,针对不同数据库不同

hbm2ddl.auto : create表示每次生成新的表结构,删除已存在的表再创建新表

update,表示在原有表结构的基础上进行更新,保留原有的数据,对表结构进行更新,并插入新的数据

connection.url  connection.username  connection.password connection.driver_name

持久化类设计原则:

1.公有的类,私有属性

2.提供公有的不带参数的默认的构造方法

3.属性setter、getter封装

4.最好有像id一样作为标识符的属性

 Junit测试

@Before:初始化方法(表示在测试前会先执行before方法进行初始化)

@Test:要测试的方法

@After:释放资源。

openSession与getCurrentSession的区别

1.getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需要手动关闭,否者会造成连接池溢出,

2.openSession每次创建新的Session对象(对应不同的Connection),getCurrentSession使用现有的Session对象(对应相同的Connection)。

3.使用getCurrentSession获得Session还需要在cfg中配置:

如果是本地事物(jdbc):<property name="hibernate.current_session_context_class">thread</property>

如果是全局事务(jta):<property name="hibernate,current_session_context_class">jta</property>

Session与Connection的关系

一个Session对应一个Connection而一个Connection可以在不同时刻对应多个Session。

Session中get方法和load方法的区别

1.在不考虑缓存的情况下,get方法会在调用之后立即向数据库发出sql语句,返回持久化对象。 load方法会在调用之后返回一个代理对象。 该代理对象只保存了实体对象的id,直到使用对象的非主键属性时才会发出sql语句。

2.在大部分情况下load的延迟加载机制比get好,但是load会产生LazyInitializationException,当在session关闭后才调用load加载对象的其他属性的时候就会报出这个异常。

3.查询数据库中不存在的数据时,get方法会暴NullPointException,而load方法会抛出ObjectNotFound异常

更加具体的实例http://www.cnblogs.com/xiaoluo501395377/p/3371776.html

CLOB和BLOB的区别

1.CLOB使用CHAR来保存数据。 如:保存XML文档。

2. BLOB就是使用二进制保存数据。 如:保存位图,声音

3.都可以保存大对象

assigned与native区别

assigned:由java应用程序负责生成(手工赋值),没有赋值的话,int型默认为0;其他类型会报错

native:由底层数据库自动生成标识符,如果是MySQL就是increment,如果是Oracle就是sequence

hql与sql区别

1.hql操作的目标是持久化对象,sql操作的目标是数据库,在语法结构上大致相同。

2.由于第一条区别的存在,hql语句对大小写敏感,而sql语句则不敏感