- 浏览: 3730 次
- 性别:
- 来自: 温州
文章分类
最新评论
hibernate实现动态表查询的多种解决方案.
方案1.就是写一个继承自NamingStrategy的类,然后把这个类加到hibernate的配制文件中去.
测试例子如下,很容易就成功了,关键在于把配制加到hibernate的配制文件的正确位置.有加载了就能正常运行.
但据试验,这个办法还存在一些问题.这个动态表不是真正的动态表,而是一个别名.因为在实践的运行中都有框架的么.总不可能为了实现一个动态表再重新初
始化一次,那个类这个方案用来做别名还是可以的,算不上真正的动态表.反正我没有找到比较成功的动态加载的办法.
有结论说:这个NamingStrategy类会在项目启动时加载.应该是spring 实例化bean时搞的,一次实例化,就不在创建新实例了,
好像spring的LocalSessionFactoryBean在创建时会将xml与pojo的映射关系放到map里面,在生成这种映射关系时会调tableName方法,此后再取表名的时候就
不用tableName方法了,至于表名具体怎么取的,我就不懂了,源码看着晕.
Teacher类:
view plaincopy to clipboardprint?package org.zxy.model;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
public class Teacher {
private int id;
private String name;
private String title;
private Date birthday;
@Basic
@Temporal(TemporalType.TIME)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
package org.zxy.model;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
public class Teacher {
private int id;
private String name;
private String title;
private Date birthday;
@Basic
@Temporal(TemporalType.TIME)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Student类:
view plaincopy to clipboardprint?package org.zxy.model;
import java.util.Date;
public class Student {
private String id;
private String name;
private int age;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Student() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package org.zxy.model;
import java.util.Date;
public class Student {
private String id;
private String name;
private int age;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Student() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
用JUnit测试:
TeacherTest:
view plaincopy to clipboardprint?package org.zxy.model;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class TeacherTest {
private static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new AnnotationConfiguration().configure().buildSessionFactory();
}
@Test
public void save(){
Teacher t = new Teacher();
t.setId(4);
t.setName("zhangsan");
t.setTitle("chuji");
t.setBirthday(new Date());
Session session = sf.openSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
package org.zxy.model;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class TeacherTest {
private static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new AnnotationConfiguration().configure().buildSessionFactory();
}
@Test
public void save(){
Teacher t = new Teacher();
t.setId(4);
t.setName("zhangsan");
t.setTitle("chuji");
t.setBirthday(new Date());
Session session = sf.openSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
StudentTest:
view plaincopy to clipboardprint?package org.zxy.model;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class StudentTest {
public static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new Configuration().configure().buildSessionFactory();
}
@Test
public void save() {
Student stu = new Student();
stu.setName("wangwu");
stu.setAge(4);
Session session = sf.openSession();
session.beginTransaction();
session.save(stu);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
package org.zxy.model;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class StudentTest {
public static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new Configuration().configure().buildSessionFactory();
}
@Test
public void save() {
Student stu = new Student();
stu.setName("wangwu");
stu.setAge(4);
Session session = sf.openSession();
session.beginTransaction();
session.save(stu);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
hibernate.cfg.xml:
view plaincopy to clipboardprint?<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:zxy</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="org/zxy/model/Student.hbm.xml"/>
<mapping class="org.zxy.model.Teacher"/>
<mapping class="org.zxy.model.Person"/>
</session-factory>
</hibernate-configuration>
<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:zxy</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="org/zxy/model/Student.hbm.xml"/>
<mapping class="org.zxy.model.Teacher"/>
<mapping class="org.zxy.model.Person"/>
</session-factory>
</hibernate-configuration>
测试StudentTest时,会出现new Configuration()得不到值,出现空指针
改为AnnotationConfiguration()即刻解决问题
方案2 hibernate--拦截器
也就是在hibernate生成sql语句之后把我们要用的动太表名加入到sql中去.这个办法是可行的.用个字符串替换的办法就可以.很简
单吧.不过还有点麻烦,又要多写个类.不过总算是个办法.例子如下,也是找的.看着自己改到项目中去吧.
hibernate--拦截器
在Hibernate的拦截器要不要使用需要看你的需求..一般来说, 是在你操作某张表的时候附带要操作其他的表..而这个操作不是正常性操作,就是你平常不需要
执行这个操作.只是偶尔的操作..通俗点解释就是
比如,你有一个系统,是超市购物系统.这个系统是hibernate来做数据表的持久化.那么,如果你有一个需求,比如在节假日的时候,所有会员的购物积分翻三倍.
这个时候,当然你可以再写一个操作类,表示的是操作三倍积分的,但是你这样做很明显是不合理的,我们可以通过添加拦截器的方法解决这个问题.(这个例子可
能有些不合理,但是至少说明了问题)
看下面的步骤
1 创建一个工程,添加hibernate的支持...这个可以用myeclipse自动帮你完成.说了很多了,反正所以hibernate的操作都必须有这个步骤.
2 创建一个拦截器类...他继承了org.hibernate.Interceptor这个接口.看下面的代码
拦截器接口一共有十八个方法,对应了hibernate操作表的十八种状态,那些我知道的我都有打印注释了.
package com.test.interceptor;
import java.io.Serializable;
import java.util.Iterator;
import org.hibernate.CallbackException;
import org.hibernate.EntityMode;
import org.hibernate.Interceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;
/**
* @author 陈静波 E-mail:jingbo2759@163.com
* @version 创建时间:Sep 24, 2009 4:21:56 PM
* 类说明
*/
public class MyInterceptor implements Interceptor
{
@Override
public void afterTransactionBegin(Transaction arg0)
{
//开始事务之后被执行
System.out.println("事务开始了");
}
@Override
public void afterTransactionCompletion(Transaction arg0)
{
//结束事务的时候被执行
System.out.println("事务结束了");
}
@Override
public void beforeTransactionCompletion(Transaction arg0)
{
//事务完成之前
System.out.println("事务完成之前");
}
@Override
public int[] findDirty(Object arg0, Serializable arg1, Object[] arg2,
Object[] arg3, String[] arg4, Type[] arg5)
{
System.out.println("找到脏对象的时候");
return null;
}
@Override
public Object getEntity(String arg0, Serializable arg1)
throws CallbackException
{
System.out.println("获得对象的时候");
return null;
}
@Override
public String getEntityName(Object arg0) throws CallbackException
{
System.out.println("获得对象名的时候");
return null;
}
@Override
public Object instantiate(String arg0, EntityMode arg1, Serializable arg2)
throws CallbackException
{
System.out.println("初始化对象的时候");
return null;
}
@Override
public Boolean isTransient(Object arg0)
{
// TODO Auto-generated method stub
return null;
}
@Override
public void onCollectionRecreate(Object arg0, Serializable arg1)
throws CallbackException
{
}
@Override
public void onCollectionRemove(Object arg0, Serializable arg1)
throws CallbackException
{
System.out.println("容器被移除的时候,就是表中的set");
}
@Override
public void onCollectionUpdate(Object arg0, Serializable arg1)
throws CallbackException
{
System.out.println("容器被更新的时候");
}
@Override
public void onDelete(Object arg0, Serializable arg1, Object[] arg2,
String[] arg3, Type[] arg4) throws CallbackException
{
System.out.println("执行删除操作的时候");
}
@Override
public boolean onFlushDirty(Object arg0, Serializable arg1, Object[] arg2,
Object[] arg3, String[] arg4, Type[] arg5) throws CallbackException
{
return false;
}
@Override
public boolean onLoad(Object arg0, Serializable arg1, Object[] arg2,
String[] arg3, Type[] arg4) throws CallbackException
{
System.out.println("载入的时候");
return false;
}
@Override
public String onPrepareStatement(String arg0)
{
System.out.println("执行操作的时候.任何增删改查操作都可以");
return arg0;
}
@Override
public boolean onSave(Object arg0, Serializable arg1, Object[] arg2,
String[] arg3, Type[] arg4) throws CallbackException
{
System.out.println("执行保存操作的时候");
return false;
}
@Override
public void postFlush(Iterator arg0) throws CallbackException
{
}
@Override
public void preFlush(Iterator arg0) throws CallbackException
{
// TODO Auto-generated method stub
}
}
3 拦截器类创建好了以后,我们需要将拦截器添加到session里面.添加的办法修改HibernateSessionFactory类...下面红字的是Myeclipse自动生成的代码以后
添加的代码
package com.util;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import com.test.interceptor.MyInterceptor;
/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html }.
*/
public class HibernateSessionFactory {
/**
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
*/
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
private static MyInterceptor my = new MyInterceptor();
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession(my)
: null;
threadLocal.set(session);
}
return session;
}
/**
* Rebuild hibernate session factory
*
*/
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
/**
* return session factory
*
*/
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* return session factory
*
* session factory will be rebuilded in the next call
*/
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration() {
return configuration;
}
}
4 创建一个user表.
create table `user`.`user`(
`id` INT not null,
`username` CHAR(50) not null,
`age` INT not null,
primary key (`id`)
);
create unique index `PRIMARY` on `user`.`user`(`id`);
5 生成对应的实体类和hbm.xml文件(这个代码就不放上来了)
6 写测试代码
package com.test.main;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.test.model.User;
import com.util.HibernateSessionFactory;
/**
* @author 陈静波 E-mail:jingbo2759@163.com
* @version 创建时间:Sep 24, 2009 4:32:08 PM
* 类说明
*/
public class UserTest
{
public static void main(String[] args)
{
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setId(1);
user.setUsername("abc");
user.setAge(10);
session.saveOrUpdate(user);
tx.commit();
session.close();
}
}
可以看最后打印出来的内容是
事务开始了
获得对象名的时候
执行操作的时候.任何增删改查操作都可以
Hibernate: select user_.id, user_.username as username6_, user_.age as age6_ from user.user user_ where user_.id=?
获得对象名的时候
执行保存操作的时候
找到脏对象的时候
执行操作的时候.任何增删改查操作都可以
执行操作的时候.任何增删改查操作都可以
Hibernate: insert into user.user (username, age, id) values (?, ?, ?)
事务完成之前
事务结束了
方案3.
其实前面的方法用起来还是有那么点一点不爽,不过每个人的开发环境不一样,框架不一样,准就会用呢,呵呵.
所以又回到了hql上.还是这个办法最简单.
取得hibernate的session.然后调用createSQLQuery方法然后再把参数加进去.问题解决了...这个例子是我自己的.当然了这个简单一些.
例子如下
public List findList(){
Query query = this.getASession().createSQLQuery("select {SysUser.*} from sysuser123 {SysUser}").addEntity("SysUser", SysUser.class);
return query.list();
}
说明,{SysUser}是实体原形,也是动太表的原型了,后面就是参数了,用起来很容易不是么.我喜欢这个方案.getASession()得到一个hibernate下的session
最简单的方案了.哈哈.
方案4.
勤劳的人用的方法,自己写sql实现,当然了破坏了Hibernate千方百计实现的面向对向的数据库查询不是么,不过也算是一个最最灵活的方法了.
也算是个法子,网上找来的例子如下.
在实际项目的开发中,有时需要操作动态表的数据。假设当前所开发的系统需要通过数据库记录系统的日志信息,由于日志信息数据量庞大,所以为了高效了
记录和查询,每个月动态产生一个保存日志的信息表,表名包含表示年月的字符串。例如,2009年2月的日志信息保存在log200902这个表中,log200903表示
2009年3月的日志信息数据。以此类推,这些表均用于保存日志数据,其中表中的字段和结构是相同的,只是表名不同。
在Hibernate中提供的持久化类与数据表的映射基本都是一个持久化类映射一个表。程序运行的过程中很难动态修改一个映射文件中的表名,实现一个持久化
类动态地映射不同的表。通过SQLQuery对象即可以实现Hibernate对动态表的映射。
我在实际的项目应用中,有时会设计出这样的一种数据表,每个时间段产生一个新表,例如是按年或月或日。相同类型的表中,所有的字段结构都是一样的。
而 hibernate 提供的类与表的映射,是只能映射到一个具体表的,在程序的运行过程中,很难去动态修改一个 hbm 对应的表名。我在网上也有看到一实现,
但是很复杂,并且不符合我的要求。
因此我就想到直接用 jdbc 去操作数据库,这样的做法是绕过 hibernate 了。方法是从 hibernate 的 session 中,直接取得数据库 connection ,然后就
直接 jdbc 了。
后来在升级了 proxool 到 9.0RC3 后,发现居然出现了数据库连接无法释放的问题。为了解决这个问题,我查阅了 hibernate doc。我发现原来用 SQLQuery
可以更好的解决,并且可以重新用于 hibernate hbm 机制。以下举例说明。
例如我有一个 pojo 是 ReadInfo,用来记录阅读信息的。由于数据量宠大,所以我的思路是按月划分,每个月一张表。所以只是表名不同,而字段是完全相
同的。
ReadInfo.java 是这样的,其中 userId, year, month, day 是联合主键:
private Integer userId;
private Integer year;
private Integer month;
private Integer day;
private Integer point;
那么相应的 ReadInfo.hbm.xml 的片段是
<class name="ReadInfo" table="tblReadInfo" mutable="false">
<composite-id>
<key-property name="userId" column="userId" type="integer"/>
<key-property name="year" column="year" type="integer"/>
<key-property name="month" column="month" type="integer"/>
<key-property name="day" column="day" type="integer"/>
</composite-id>
<property name="point" column="point" type="integer"/>
</class>
上面的xml,注意 2 个细节
1. pojo 所映射的 table tblReadInfo 实际上是不存在的。实际的表是 tblRead200710 之类的;
2. mutable 要设置为 false,即是说,关闭 hibernate 对这个 pojo 的任何持久化操作,以避免 hibernate 把数据写到 tblReadInfo 中(这个表是不存在
的嘛)。因此,所有的持久化操作,都是需要自己通过 SQLQuery 来处理。
现在可以看一下 ado 中的操作了,先看一个 select 操作
public ReadInfo selectReadInfo(Integer userId, Integer year,
Integer month, Integer day) throws HibernateException
{
ReadInfo readInfo = null;
Session session = getSession();
Transaction tx = session.beginTransaction();
try
{
String sql = "select * from tblRead"
+ Misc.formatMoon(year, month)
+ " where userId=? and day=?";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(ReadInfo.class);
query.setLong(0, userId);
query.setInteger(1, day);
readInfo = (ReadInfo) query.uniqueResult();
tx.commit();
}
catch (HibernateException e)
{
log.error("catch exception:", e);
if (tx != null)
{
tx.rollback();
}
throw e;
}
return readInfo;
}
上面的代码,关键是以下几点:
1. 通过函数参数的 year, month 来确定要操作的表名,我自己写了一个 Misc.formatMoon(year, month) 来生成 "yyyyMM" 格式的字串;
2. 使用了 SQLQuery ,再通过 query.addEntity(ReadInfo.class); 建立与 ReadInfo 的映射关系;
3. query.setXxx() 与 PreparedStatement 的类似,不过索引是从 0 开始;
4. 其它的就跟一般的 Query 操作类似的了。
再看一个 insert 操作
public void insertReadInfo(ReadInfo readInfo) throws HibernateException
{
Session session = getSession();
Transaction tx = session.beginTransaction();
try
{
String sql = "insert into tblRead"
+ Misc.formatMoon(readInfo.getYear(), readInfo.getMonth())
+ " (userId, year, month, day, point) values (?, ?, ?, ?, ?)";
SQLQuery query = session.createSQLQuery(sql);
query.setLong(0, readInfo.getUserId());
query.setInteger(1, readInfo.getYear());
query.setInteger(2, readInfo.getMonth());
query.setInteger(3, readInfo.getDay());
query.setInteger(4, readInfo.getPoint());
query.executeUpdate();
tx.commit();
}
catch (HibernateException e)
{
log.error("catch exception:", e);
if (tx != null)
{
tx.rollback();
}
throw e;
}
}
同理,update, delete 等操作也是这样实现的。
hmm.. 这种处理方式的麻烦的地方是需要手工写 sql ,因此要尽量写通用的标准 sql,不然在数据库兼容方面会有问题。当然,有时是会出现无法兼容的情
况,那么可以考虑把 sql 写到配置文件中,根据不同的数据库,装载相应的配置文件咯。
方案1.就是写一个继承自NamingStrategy的类,然后把这个类加到hibernate的配制文件中去.
测试例子如下,很容易就成功了,关键在于把配制加到hibernate的配制文件的正确位置.有加载了就能正常运行.
但据试验,这个办法还存在一些问题.这个动态表不是真正的动态表,而是一个别名.因为在实践的运行中都有框架的么.总不可能为了实现一个动态表再重新初
始化一次,那个类这个方案用来做别名还是可以的,算不上真正的动态表.反正我没有找到比较成功的动态加载的办法.
有结论说:这个NamingStrategy类会在项目启动时加载.应该是spring 实例化bean时搞的,一次实例化,就不在创建新实例了,
好像spring的LocalSessionFactoryBean在创建时会将xml与pojo的映射关系放到map里面,在生成这种映射关系时会调tableName方法,此后再取表名的时候就
不用tableName方法了,至于表名具体怎么取的,我就不懂了,源码看着晕.
Teacher类:
view plaincopy to clipboardprint?package org.zxy.model;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
public class Teacher {
private int id;
private String name;
private String title;
private Date birthday;
@Basic
@Temporal(TemporalType.TIME)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
package org.zxy.model;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
public class Teacher {
private int id;
private String name;
private String title;
private Date birthday;
@Basic
@Temporal(TemporalType.TIME)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Student类:
view plaincopy to clipboardprint?package org.zxy.model;
import java.util.Date;
public class Student {
private String id;
private String name;
private int age;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Student() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package org.zxy.model;
import java.util.Date;
public class Student {
private String id;
private String name;
private int age;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Student() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
用JUnit测试:
TeacherTest:
view plaincopy to clipboardprint?package org.zxy.model;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class TeacherTest {
private static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new AnnotationConfiguration().configure().buildSessionFactory();
}
@Test
public void save(){
Teacher t = new Teacher();
t.setId(4);
t.setName("zhangsan");
t.setTitle("chuji");
t.setBirthday(new Date());
Session session = sf.openSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
package org.zxy.model;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class TeacherTest {
private static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new AnnotationConfiguration().configure().buildSessionFactory();
}
@Test
public void save(){
Teacher t = new Teacher();
t.setId(4);
t.setName("zhangsan");
t.setTitle("chuji");
t.setBirthday(new Date());
Session session = sf.openSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
StudentTest:
view plaincopy to clipboardprint?package org.zxy.model;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class StudentTest {
public static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new Configuration().configure().buildSessionFactory();
}
@Test
public void save() {
Student stu = new Student();
stu.setName("wangwu");
stu.setAge(4);
Session session = sf.openSession();
session.beginTransaction();
session.save(stu);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
package org.zxy.model;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class StudentTest {
public static SessionFactory sf = null;
@BeforeClass
public static void beforeClass() {
sf = new Configuration().configure().buildSessionFactory();
}
@Test
public void save() {
Student stu = new Student();
stu.setName("wangwu");
stu.setAge(4);
Session session = sf.openSession();
session.beginTransaction();
session.save(stu);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass() {
sf.close();
}
}
hibernate.cfg.xml:
view plaincopy to clipboardprint?<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:zxy</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="org/zxy/model/Student.hbm.xml"/>
<mapping class="org.zxy.model.Teacher"/>
<mapping class="org.zxy.model.Person"/>
</session-factory>
</hibernate-configuration>
<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:zxy</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="org/zxy/model/Student.hbm.xml"/>
<mapping class="org.zxy.model.Teacher"/>
<mapping class="org.zxy.model.Person"/>
</session-factory>
</hibernate-configuration>
测试StudentTest时,会出现new Configuration()得不到值,出现空指针
改为AnnotationConfiguration()即刻解决问题
方案2 hibernate--拦截器
也就是在hibernate生成sql语句之后把我们要用的动太表名加入到sql中去.这个办法是可行的.用个字符串替换的办法就可以.很简
单吧.不过还有点麻烦,又要多写个类.不过总算是个办法.例子如下,也是找的.看着自己改到项目中去吧.
hibernate--拦截器
在Hibernate的拦截器要不要使用需要看你的需求..一般来说, 是在你操作某张表的时候附带要操作其他的表..而这个操作不是正常性操作,就是你平常不需要
执行这个操作.只是偶尔的操作..通俗点解释就是
比如,你有一个系统,是超市购物系统.这个系统是hibernate来做数据表的持久化.那么,如果你有一个需求,比如在节假日的时候,所有会员的购物积分翻三倍.
这个时候,当然你可以再写一个操作类,表示的是操作三倍积分的,但是你这样做很明显是不合理的,我们可以通过添加拦截器的方法解决这个问题.(这个例子可
能有些不合理,但是至少说明了问题)
看下面的步骤
1 创建一个工程,添加hibernate的支持...这个可以用myeclipse自动帮你完成.说了很多了,反正所以hibernate的操作都必须有这个步骤.
2 创建一个拦截器类...他继承了org.hibernate.Interceptor这个接口.看下面的代码
拦截器接口一共有十八个方法,对应了hibernate操作表的十八种状态,那些我知道的我都有打印注释了.
package com.test.interceptor;
import java.io.Serializable;
import java.util.Iterator;
import org.hibernate.CallbackException;
import org.hibernate.EntityMode;
import org.hibernate.Interceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;
/**
* @author 陈静波 E-mail:jingbo2759@163.com
* @version 创建时间:Sep 24, 2009 4:21:56 PM
* 类说明
*/
public class MyInterceptor implements Interceptor
{
@Override
public void afterTransactionBegin(Transaction arg0)
{
//开始事务之后被执行
System.out.println("事务开始了");
}
@Override
public void afterTransactionCompletion(Transaction arg0)
{
//结束事务的时候被执行
System.out.println("事务结束了");
}
@Override
public void beforeTransactionCompletion(Transaction arg0)
{
//事务完成之前
System.out.println("事务完成之前");
}
@Override
public int[] findDirty(Object arg0, Serializable arg1, Object[] arg2,
Object[] arg3, String[] arg4, Type[] arg5)
{
System.out.println("找到脏对象的时候");
return null;
}
@Override
public Object getEntity(String arg0, Serializable arg1)
throws CallbackException
{
System.out.println("获得对象的时候");
return null;
}
@Override
public String getEntityName(Object arg0) throws CallbackException
{
System.out.println("获得对象名的时候");
return null;
}
@Override
public Object instantiate(String arg0, EntityMode arg1, Serializable arg2)
throws CallbackException
{
System.out.println("初始化对象的时候");
return null;
}
@Override
public Boolean isTransient(Object arg0)
{
// TODO Auto-generated method stub
return null;
}
@Override
public void onCollectionRecreate(Object arg0, Serializable arg1)
throws CallbackException
{
}
@Override
public void onCollectionRemove(Object arg0, Serializable arg1)
throws CallbackException
{
System.out.println("容器被移除的时候,就是表中的set");
}
@Override
public void onCollectionUpdate(Object arg0, Serializable arg1)
throws CallbackException
{
System.out.println("容器被更新的时候");
}
@Override
public void onDelete(Object arg0, Serializable arg1, Object[] arg2,
String[] arg3, Type[] arg4) throws CallbackException
{
System.out.println("执行删除操作的时候");
}
@Override
public boolean onFlushDirty(Object arg0, Serializable arg1, Object[] arg2,
Object[] arg3, String[] arg4, Type[] arg5) throws CallbackException
{
return false;
}
@Override
public boolean onLoad(Object arg0, Serializable arg1, Object[] arg2,
String[] arg3, Type[] arg4) throws CallbackException
{
System.out.println("载入的时候");
return false;
}
@Override
public String onPrepareStatement(String arg0)
{
System.out.println("执行操作的时候.任何增删改查操作都可以");
return arg0;
}
@Override
public boolean onSave(Object arg0, Serializable arg1, Object[] arg2,
String[] arg3, Type[] arg4) throws CallbackException
{
System.out.println("执行保存操作的时候");
return false;
}
@Override
public void postFlush(Iterator arg0) throws CallbackException
{
}
@Override
public void preFlush(Iterator arg0) throws CallbackException
{
// TODO Auto-generated method stub
}
}
3 拦截器类创建好了以后,我们需要将拦截器添加到session里面.添加的办法修改HibernateSessionFactory类...下面红字的是Myeclipse自动生成的代码以后
添加的代码
package com.util;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import com.test.interceptor.MyInterceptor;
/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html }.
*/
public class HibernateSessionFactory {
/**
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
*/
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
private static MyInterceptor my = new MyInterceptor();
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession(my)
: null;
threadLocal.set(session);
}
return session;
}
/**
* Rebuild hibernate session factory
*
*/
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
/**
* return session factory
*
*/
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* return session factory
*
* session factory will be rebuilded in the next call
*/
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration() {
return configuration;
}
}
4 创建一个user表.
create table `user`.`user`(
`id` INT not null,
`username` CHAR(50) not null,
`age` INT not null,
primary key (`id`)
);
create unique index `PRIMARY` on `user`.`user`(`id`);
5 生成对应的实体类和hbm.xml文件(这个代码就不放上来了)
6 写测试代码
package com.test.main;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.test.model.User;
import com.util.HibernateSessionFactory;
/**
* @author 陈静波 E-mail:jingbo2759@163.com
* @version 创建时间:Sep 24, 2009 4:32:08 PM
* 类说明
*/
public class UserTest
{
public static void main(String[] args)
{
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setId(1);
user.setUsername("abc");
user.setAge(10);
session.saveOrUpdate(user);
tx.commit();
session.close();
}
}
可以看最后打印出来的内容是
事务开始了
获得对象名的时候
执行操作的时候.任何增删改查操作都可以
Hibernate: select user_.id, user_.username as username6_, user_.age as age6_ from user.user user_ where user_.id=?
获得对象名的时候
执行保存操作的时候
找到脏对象的时候
执行操作的时候.任何增删改查操作都可以
执行操作的时候.任何增删改查操作都可以
Hibernate: insert into user.user (username, age, id) values (?, ?, ?)
事务完成之前
事务结束了
方案3.
其实前面的方法用起来还是有那么点一点不爽,不过每个人的开发环境不一样,框架不一样,准就会用呢,呵呵.
所以又回到了hql上.还是这个办法最简单.
取得hibernate的session.然后调用createSQLQuery方法然后再把参数加进去.问题解决了...这个例子是我自己的.当然了这个简单一些.
例子如下
public List findList(){
Query query = this.getASession().createSQLQuery("select {SysUser.*} from sysuser123 {SysUser}").addEntity("SysUser", SysUser.class);
return query.list();
}
说明,{SysUser}是实体原形,也是动太表的原型了,后面就是参数了,用起来很容易不是么.我喜欢这个方案.getASession()得到一个hibernate下的session
最简单的方案了.哈哈.
方案4.
勤劳的人用的方法,自己写sql实现,当然了破坏了Hibernate千方百计实现的面向对向的数据库查询不是么,不过也算是一个最最灵活的方法了.
也算是个法子,网上找来的例子如下.
在实际项目的开发中,有时需要操作动态表的数据。假设当前所开发的系统需要通过数据库记录系统的日志信息,由于日志信息数据量庞大,所以为了高效了
记录和查询,每个月动态产生一个保存日志的信息表,表名包含表示年月的字符串。例如,2009年2月的日志信息保存在log200902这个表中,log200903表示
2009年3月的日志信息数据。以此类推,这些表均用于保存日志数据,其中表中的字段和结构是相同的,只是表名不同。
在Hibernate中提供的持久化类与数据表的映射基本都是一个持久化类映射一个表。程序运行的过程中很难动态修改一个映射文件中的表名,实现一个持久化
类动态地映射不同的表。通过SQLQuery对象即可以实现Hibernate对动态表的映射。
我在实际的项目应用中,有时会设计出这样的一种数据表,每个时间段产生一个新表,例如是按年或月或日。相同类型的表中,所有的字段结构都是一样的。
而 hibernate 提供的类与表的映射,是只能映射到一个具体表的,在程序的运行过程中,很难去动态修改一个 hbm 对应的表名。我在网上也有看到一实现,
但是很复杂,并且不符合我的要求。
因此我就想到直接用 jdbc 去操作数据库,这样的做法是绕过 hibernate 了。方法是从 hibernate 的 session 中,直接取得数据库 connection ,然后就
直接 jdbc 了。
后来在升级了 proxool 到 9.0RC3 后,发现居然出现了数据库连接无法释放的问题。为了解决这个问题,我查阅了 hibernate doc。我发现原来用 SQLQuery
可以更好的解决,并且可以重新用于 hibernate hbm 机制。以下举例说明。
例如我有一个 pojo 是 ReadInfo,用来记录阅读信息的。由于数据量宠大,所以我的思路是按月划分,每个月一张表。所以只是表名不同,而字段是完全相
同的。
ReadInfo.java 是这样的,其中 userId, year, month, day 是联合主键:
private Integer userId;
private Integer year;
private Integer month;
private Integer day;
private Integer point;
那么相应的 ReadInfo.hbm.xml 的片段是
<class name="ReadInfo" table="tblReadInfo" mutable="false">
<composite-id>
<key-property name="userId" column="userId" type="integer"/>
<key-property name="year" column="year" type="integer"/>
<key-property name="month" column="month" type="integer"/>
<key-property name="day" column="day" type="integer"/>
</composite-id>
<property name="point" column="point" type="integer"/>
</class>
上面的xml,注意 2 个细节
1. pojo 所映射的 table tblReadInfo 实际上是不存在的。实际的表是 tblRead200710 之类的;
2. mutable 要设置为 false,即是说,关闭 hibernate 对这个 pojo 的任何持久化操作,以避免 hibernate 把数据写到 tblReadInfo 中(这个表是不存在
的嘛)。因此,所有的持久化操作,都是需要自己通过 SQLQuery 来处理。
现在可以看一下 ado 中的操作了,先看一个 select 操作
public ReadInfo selectReadInfo(Integer userId, Integer year,
Integer month, Integer day) throws HibernateException
{
ReadInfo readInfo = null;
Session session = getSession();
Transaction tx = session.beginTransaction();
try
{
String sql = "select * from tblRead"
+ Misc.formatMoon(year, month)
+ " where userId=? and day=?";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(ReadInfo.class);
query.setLong(0, userId);
query.setInteger(1, day);
readInfo = (ReadInfo) query.uniqueResult();
tx.commit();
}
catch (HibernateException e)
{
log.error("catch exception:", e);
if (tx != null)
{
tx.rollback();
}
throw e;
}
return readInfo;
}
上面的代码,关键是以下几点:
1. 通过函数参数的 year, month 来确定要操作的表名,我自己写了一个 Misc.formatMoon(year, month) 来生成 "yyyyMM" 格式的字串;
2. 使用了 SQLQuery ,再通过 query.addEntity(ReadInfo.class); 建立与 ReadInfo 的映射关系;
3. query.setXxx() 与 PreparedStatement 的类似,不过索引是从 0 开始;
4. 其它的就跟一般的 Query 操作类似的了。
再看一个 insert 操作
public void insertReadInfo(ReadInfo readInfo) throws HibernateException
{
Session session = getSession();
Transaction tx = session.beginTransaction();
try
{
String sql = "insert into tblRead"
+ Misc.formatMoon(readInfo.getYear(), readInfo.getMonth())
+ " (userId, year, month, day, point) values (?, ?, ?, ?, ?)";
SQLQuery query = session.createSQLQuery(sql);
query.setLong(0, readInfo.getUserId());
query.setInteger(1, readInfo.getYear());
query.setInteger(2, readInfo.getMonth());
query.setInteger(3, readInfo.getDay());
query.setInteger(4, readInfo.getPoint());
query.executeUpdate();
tx.commit();
}
catch (HibernateException e)
{
log.error("catch exception:", e);
if (tx != null)
{
tx.rollback();
}
throw e;
}
}
同理,update, delete 等操作也是这样实现的。
hmm.. 这种处理方式的麻烦的地方是需要手工写 sql ,因此要尽量写通用的标准 sql,不然在数据库兼容方面会有问题。当然,有时是会出现无法兼容的情
况,那么可以考虑把 sql 写到配置文件中,根据不同的数据库,装载相应的配置文件咯。
相关推荐
### Hibernate查询解决方案详解 #### 一、概述 Hibernate 是一个开放源代码的 ORM(对象关系映射)框架,它提供了从 Java 类到数据库表的映射机制,以及数据的查询和获取方式。Hibernate 的核心功能之一是提供了...
未来 Hibernate是一个强大的Java持久化框架...以上各点提供了实现这一目标的基础,但实际项目中可能还需要解决更多特定于数据库的问题。通过良好的设计和测试,可以确保Hibernate应用程序在多种数据库环境下稳定运行。
Spring Hibernate 实现动态替换表名(分表)的方法 随着数据库的发展,分表操作变得越来越重要。今天,我们将讨论如何使用 Spring Hibernate 实现动态替换表名(分表)。 概述 ---- 在实现动态替换表名时,我们...
Hibernate 是一个流行的 Java 应用程序开发框架,它提供了一个持久层解决方案,简化了数据库操作。对于初学者来说,理解 Hibernate 的映射和查询机制是至关重要的,因为它们构成了 Hibernate 核心功能的基础。 **一...
博主可能通过具体的例子展示了如何配置和使用级联查询,以及可能遇到的问题和解决方案。 **标签解析:** 1. **源码** - 暗示内容可能涉及Hibernate框架的内部实现,可能会讲解到相关的Java代码或者XML配置文件,...
而其中的`Criteria`接口更是为复杂的查询需求提供了一种灵活且功能强大的解决方案。本文将深入探讨`Hibernate-Criteria`模糊查询的实现方式,以及其背后的原理。 #### Criteria接口简介 `Criteria`是Hibernate提供...
无论是基本的全表扫描还是复杂的条件查询,HQL都能够提供一种面向对象的解决方案,从而提高开发效率和代码可读性。 #### 扩展阅读 为了更深入地学习Hibernate和HQL,建议阅读以下资源: - Hibernate官方文档:...
**Hibernate 框架详解** Hibernate 是一个开源的Java持久...无论是简单的CRUD操作,还是复杂的对象关系映射,Hibernate都能提供优雅的解决方案。记得在实际使用时,根据项目需求调整配置和优化性能,以获得最佳效果。
综上所述,Hibernate、Struts2和Spring的集成使用,为Java Web应用开发提供了强大而灵活的解决方案。通过深入理解这三个框架的核心原理和最佳实践,开发者可以构建出高效、高质量的企业级应用。在实际项目中,合理...
在使用Hibernate进行web后端开发时,除了核心jar包,可能还需要其他依赖,如数据库驱动包(如mysql-connector-java)、日志库(如log4j)、Spring框架等,以实现完整的ORM解决方案。掌握并合理运用Hibernate框架,...
总结来说,"hibernate4.3.11所需jar包"不仅包含Hibernate的核心库,还涉及到一系列依赖的第三方库,这些库共同构成了一个完整的ORM解决方案,使开发者能够高效地管理和操作数据库。在实际开发中,理解并熟练运用这些...
对于更复杂的关系,例如一对一、一对多、多对一、多对多的关联,Hibernate提供了多种解决方案。例如,`Class1`和`Class2`的一对一双向关联,可以在两个类中都添加对方的引用,并在数据库中通过外键关联两个表的主键...
综上所述,"Spring+Struts2+Hibernate实现的客户关系管理CRM系统"是一个综合运用多种技术的项目,它涉及了Java Web开发的多个核心层面,包括业务逻辑处理、用户界面展示和数据持久化。通过熟练掌握这些框架,开发者...
Hibernate 是一个流行的 ORM 解决方案,将 Java 对象与关系数据库进行映射,简化了数据库操作。通过阅读 Hibernate 的源代码,我们可以学习到: 1. **对象关系映射**:Hibernate 的核心是 ORM,它将 Java 类与 SQL ...
这个API提供了一种更面向对象的方式来构建动态查询,允许在运行时构建查询条件,增加了代码的灵活性。在3.3.2版本中,Criteria API更加成熟,支持更多的查询操作和关联检索。 在事务管理方面,Hibernate 3.3.2 支持...
通过提供数据持久化的解决方案,Hibernate提高了开发效率,降低了数据库访问的复杂性。 ### 2. 安装与配置 在开始使用Hibernate之前,需要将其库文件添加到项目的类路径中。`Hibernate3.1_DOC_CN.chm`文件包含的是...
《构建网上论坛系统:Struts 2、Hibernate与Spring的集成...它们各自承担着不同的职责,共同构成了一个完整的解决方案。掌握这些技术,不仅可以提升我们的开发能力,也为构建其他类型的Web应用程序打下了坚实的基础。
与传统的JDBC(Java Database Connectivity)相比,Hibernate提供了一种对象关系映射(ORM,Object-Relational Mapping)的解决方案,将Java对象与数据库表之间的关系进行了抽象,使得开发者可以更专注于业务逻辑,...