最近在做OA系统(ssh),一直在想如何把框架架得更完善,此前已经在框架里集成springMVC,读写分离(这个在另一篇文章里会有说明怎么做),这几天在想如果是大数据,要分表要怎么来弄,不可能每一个表都写一个实体来映射,这样太不灵活,也不现实!
oa考勤本来数据不多,如果分表一般以年份来分表。今天研究的是以用户来分表。
网上找了些资料,说是可以用NamingStrategy来实现动态映射表名。
发现sessionFactory里面有个namingStrategy属性可以注入,这个东东就是hibernate在表映射时要用的,关系啥的都放在这个里面,只要重写它就行。不过只有在容器启动时才会加载这个,也就是只会执行一次,以后就算动态设置了namingStrategy也不会再加载改变映射关系了,那会就是一个sessionFactory只能在启动时对应一个namingStrategy;如此要想对应多个相同表映射就须得要有多个sessionFactory才行;
可是spring并没有提供像AbstractRoutingDataSource动态数据源这样的接口给我们用,那怎么办,只能自己写一个了,既然我们要多个sessionFactory,但我们的底层dao里是只注入一个sessionFactory,那么我们就模仿动态数据源一样写个路由DynamicSessionFactory继承sessionFactory,并且提供一个动态getHibernateSessionFactory的方法,然后写个实现DynamicSessionFactoryImpl重写sessionFactory里面的方法,让里面的方法在取sessionFactory时全部通过getHibernateSessionFactory得到,而getHibernateSessionFactory就是动态根据我们的设置来取sessionFactory的了,这样就实现动态取不同的sessionFactory了。
getHibernateSessionFactory靠ThreadLocal的特性,给当前线程设置sessionFactory的bean名称,然后在取时就拿这个bean名称取对应的bean就行了。
在配好这些后,当时想的是用spring的aop来拦截service层的方法来进行动态设置bean名称,在实践后发现这样做在单表或者说是在一次请求只调一个service方法时且不懒加载时才可以,当一个action请求有两个以上service方法时,就完了,每调一个方法sessionFactory就会重新设置一下,这样session就一定会关闭了,这样在调完方法查出数据后如果去懒加载get数据就会发现没有session,就报错了(collection is not associated with any session)。所以我们不能在service层做文章,得在action层甚至是filter里做动态设置才行。
发现在web.xml里有个org.springframework.orm.hibernate4.support.OpenSessionInViewFilter,这个的用处就是为了解决一个请求里session统一的问题的,不过这里虽然配置了,但一在service层动态设置sessionFactory后,每次都给改变了。所以我们只要在这个filter里来动态设置sessionFactory就行了,这样每次一个请求就设置一个sessionFactory,直到完成。实现:就是写一个MyOpenSessionInViewFilter去继承OpenSessionInViewFilter然后重写它的lookupSessionFactory方法,在每次请求lookupSessionFactory动态设上自己要的sessionFactory就行了。
这样设置完成后测试发现可以达到效果,可点着点着就发现问题了,一到使用多线程(在生成多人的排班考勤时我都是使用多线程来生成的)时,就会报当前线程的session为空。仔细想想也不难理解,每次设置时我都是只设置了请求的这条线程的话,也就是只有主线程是有了的长时间session存在的,当用多线程时,每一条新线程都在拿sessionFactory时都会调ThreadLocal当前线程的存的sessionFactory的名称来取,这样当然就取不到了,想着就把主线程的sessionFactory的名称也传进子线程设置在子线程这样就有了吧,结果发现是有了,sessionFactory取对了,可是在取当前session时又报错取不到了。这又是怎么回事呢,于是又想着把主线程那个session也传进去试试,发现传进去,哎,不报错了,是取得到了,我去,却发现它不在事务里了。至此得整理下思路,一个线程一个session的话,那多线程中的子线程就不能再用那个session了,得是它自己启动一个session事务,可想着那些service方法本来我就是有设置事务的呀!然后去看看事务的配置文件,哎哟喂,事务配的是org.springframework.orm.hibernate4.HibernateTransactionManager,里面配的是路由sessionFactory,原来是事务没有动态呀,这样每次调用时都是同一个,没有动态给多个sessionFactory都设置事务。于是写一个动态事务DynamicTransactionManager去继承HibernateTransactionManager,并重写getSessionFactory和getDataSource方法,这样就实现了动态事务的动态sessionFactory了。然后再测试下多线程的,搞定!
历时两天多,终于搞定了!
平时没怎么写文章,文字表达能力不好,凑合着看吧,以后得多练练
下面上一下代码吧!
动态表名实现类:
/** * 动态表名 */ import java.text.DecimalFormat; import java.util.ArrayList; import org.hibernate.cfg.DefaultNamingStrategy; public class TNamingStrategy extends DefaultNamingStrategy { /** * */ private static final long serialVersionUID = 1L; private static final DecimalFormat df = new DecimalFormat(); private static ArrayList<String> rollingTables = new ArrayList<String>(); private String suffix;//表后缀 static { rollingTables.add("KQ_ATTENDANCE");//有哪些表需要多个映射的就在这里add进去 rollingTables.add("KQ_DUTY_ROSTER"); df.applyPattern("00"); } /* @Override public String classToTableName(String className) { // TODO Auto-generated method stub return tableName(StringHelper.unqualify(className).toUpperCase()); } */ /** * * * class里显式设置了表名,就调用 tableName * 没有显示就调用 classToTableName */ public String tableName(String tableName) { String stroeTable = tableName; // 对指定的表名计算实际存储表名 if (rollingTables.contains(tableName.toUpperCase())&&suffix!=null) { stroeTable += "_" + suffix; System.out.println("store record into [" + stroeTable + "]"); } return stroeTable; } public String getSuffix() { return suffix; } public void setSuffix(String suffix) { this.suffix = suffix; } }
当前线程保存sessonFactory bean名称:
public abstract class CustomerContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { if(contextHolder.get()==null) { System.out.println("空啦"); setCustomerType("master"); } return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }
路由sessionFactory:
import org.hibernate.SessionFactory; public interface DynamicSessionFactory extends SessionFactory { public SessionFactory getHibernateSessionFactory(); }
路由sessionFactory实现:
import java.io.Serializable; import java.sql.Connection; import java.util.Map; import java.util.Set; import javax.naming.NamingException; import javax.naming.Reference; import org.hibernate.Cache; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionBuilder; import org.hibernate.SessionFactory; import org.hibernate.StatelessSession; import org.hibernate.StatelessSessionBuilder; import org.hibernate.TypeHelper; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.metadata.ClassMetadata; import org.hibernate.metadata.CollectionMetadata; import org.hibernate.stat.Statistics; /** * <b>function:</b> 动态sessionFactory实现 * @version 1.0 */ @SuppressWarnings({ "unchecked", "deprecation" }) public class DynamicSessionFactoryImpl implements DynamicSessionFactory { private static final long serialVersionUID = 5384069312247414885L; private Map<Object, SessionFactory> targetSessionFactorys; private SessionFactory defaultTargetSessionFactory; /** * * <b>function:</b> 重写这个方法,这里最关键 */ @Override public SessionFactory getHibernateSessionFactory() { SessionFactory targetSessionFactory = targetSessionFactorys.get(CustomerContextHolder.getCustomerType()); // System.out.println("CustomerContextHolder.getCustomerType():"+CustomerContextHolder.getCustomerType()); // System.out.println("targetSessionFactory:"+targetSessionFactory); if (targetSessionFactory != null) { return targetSessionFactory; } else if (defaultTargetSessionFactory != null) { return defaultTargetSessionFactory; } return null; } public SessionFactory getObject() { return this.getHibernateSessionFactory(); } @Override public void close() throws HibernateException { this.getHibernateSessionFactory().close(); } @Override public boolean containsFetchProfileDefinition(String s) { return this.getHibernateSessionFactory().containsFetchProfileDefinition(s); } @Override public void evict(Class clazz) throws HibernateException { this.getHibernateSessionFactory().evict(clazz); } @Override public void evict(Class clazz, Serializable serializable) throws HibernateException { this.getHibernateSessionFactory().evict(clazz, serializable); } @Override public void evictCollection(String s) throws HibernateException { this.getHibernateSessionFactory().evictCollection(s); } @Override public void evictCollection(String s, Serializable serializable) throws HibernateException { this.getHibernateSessionFactory().evictCollection(s, serializable); } @Override public void evictEntity(String entity) throws HibernateException { this.getHibernateSessionFactory().evictEntity(entity); } @Override public void evictEntity(String entity, Serializable serializable) throws HibernateException { this.getHibernateSessionFactory().evictEntity(entity, serializable); } @Override public void evictQueries() throws HibernateException { this.getHibernateSessionFactory().evictQueries(); } @Override public void evictQueries(String queries) throws HibernateException { this.getHibernateSessionFactory().evictQueries(queries); } @Override public Map<String, ClassMetadata> getAllClassMetadata() { return this.getHibernateSessionFactory().getAllClassMetadata(); } @Override public Map getAllCollectionMetadata() { return this.getHibernateSessionFactory().getAllClassMetadata(); } @Override public Cache getCache() { return this.getHibernateSessionFactory().getCache(); } @Override public ClassMetadata getClassMetadata(Class clazz) { return this.getHibernateSessionFactory().getClassMetadata(clazz); } @Override public ClassMetadata getClassMetadata(String classMetadata) { return this.getHibernateSessionFactory().getClassMetadata(classMetadata); } @Override public CollectionMetadata getCollectionMetadata(String collectionMetadata) { return this.getHibernateSessionFactory().getCollectionMetadata(collectionMetadata); } @Override public Session getCurrentSession() throws HibernateException { return this.getHibernateSessionFactory().getCurrentSession(); } @Override public Set getDefinedFilterNames() { return this.getHibernateSessionFactory().getDefinedFilterNames(); } @Override public FilterDefinition getFilterDefinition(String definition) throws HibernateException { return this.getHibernateSessionFactory().getFilterDefinition(definition); } @Override public Statistics getStatistics() { return this.getHibernateSessionFactory().getStatistics(); } @Override public TypeHelper getTypeHelper() { return this.getHibernateSessionFactory().getTypeHelper(); } @Override public boolean isClosed() { return this.getHibernateSessionFactory().isClosed(); } @Override public Session openSession() throws HibernateException { return this.getHibernateSessionFactory().openSession(); } @Override public StatelessSession openStatelessSession() { return this.getHibernateSessionFactory().openStatelessSession(); } @Override public StatelessSession openStatelessSession(Connection connection) { return this.getHibernateSessionFactory().openStatelessSession(connection); } @Override public Reference getReference() throws NamingException { return this.getHibernateSessionFactory().getReference(); } public void setTargetSessionFactorys(Map<Object, SessionFactory> targetSessionFactorys) { this.targetSessionFactorys = targetSessionFactorys; } public void setDefaultTargetSessionFactory(SessionFactory defaultTargetSessionFactory) { this.defaultTargetSessionFactory = defaultTargetSessionFactory; } @Override public SessionFactoryOptions getSessionFactoryOptions() { return this.getHibernateSessionFactory().getSessionFactoryOptions(); } @Override public SessionBuilder withOptions() { return this.getHibernateSessionFactory().withOptions(); } @Override public StatelessSessionBuilder withStatelessOptions() { return this.getHibernateSessionFactory().withStatelessOptions(); } }
动态的事务管理器:
import javax.sql.DataSource; import org.hibernate.SessionFactory; import org.springframework.orm.hibernate4.HibernateTransactionManager; import org.springframework.orm.hibernate4.SessionFactoryUtils; /** * <b>function:</b> 重写HibernateTransactionManager事务管理器,实现自己的动态的事务管理器 * @version 1.0 */ public class DynamicTransactionManager extends HibernateTransactionManager { private static final long serialVersionUID = -4655721479296819154L; /** * @see org.springframework.orm.hibernate4.HibernateTransactionManager#getDataSource() * <b>function:</b> 重写 */ @Override public DataSource getDataSource() { return SessionFactoryUtils.getDataSource(getSessionFactory()); } /** * @see org.springframework.orm.hibernate4.HibernateTransactionManager#getSessionFactory() * <b>function:</b> 重写 */ @Override public SessionFactory getSessionFactory() { DynamicSessionFactory dynamicSessionFactory = (DynamicSessionFactory) super.getSessionFactory(); SessionFactory hibernateSessionFactory = dynamicSessionFactory.getHibernateSessionFactory(); return hibernateSessionFactory; } }
自己的OpenSessionInViewFilter,为的是一个请求一个session并且有选择的设定sessionFactory:
import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.orm.hibernate4.SessionFactoryUtils; import org.springframework.orm.hibernate4.SessionHolder; import org.springframework.orm.hibernate4.support.AsyncRequestInterceptor; import org.springframework.orm.hibernate4.support.OpenSessionInViewFilter; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.async.WebAsyncManager; import org.springframework.web.context.request.async.WebAsyncUtils; import org.springframework.web.context.support.WebApplicationContextUtils; import sy.model.base.frame.SessionInfo; import sy.model.base.frame.Syuser; import sy.util.base.ConfigUtil; /** * 自己的OpenSessionInViewFilter,为的是一个请求一个session并且有选择的设定sessionFactory * @author miraclerz * */ public class MyOpenSessionInViewFilter extends OpenSessionInViewFilter { private HttpServletRequest request; @Override protected SessionFactory lookupSessionFactory() { WebApplicationContext wac = WebApplicationContextUtils .getRequiredWebApplicationContext(getServletContext()); String sessionFactoryName = getSessionFactoryBeanName(); //动态设置sessionFactory名称了 CustomerContextHolder.setCustomerType("master"); DynamicSessionFactoryImpl dynamicSessionFactoryImpl = wac.getBean( sessionFactoryName, DynamicSessionFactoryImpl.class); return dynamicSessionFactoryImpl.getObject(); } }
上一下配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:c="http://www.springframework.org/schema/c" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!--配置 --> <!-- 加载properties配置文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:switchSessionFactory/sessionFactoryJdbc.properties</value> </list> </property> </bean> <bean id="sessionFactoryDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="${sessionFactory.jdbc.driverClassName}" /> <property name="url" value="${sessionFactory.jdbc.url}" /> <property name="username" value="${sessionFactory.jdbc.username}" /> <property name="password" value="${sessionFactory.jdbc.password}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="1" /> <!-- 连接池最大使用连接数量 --> <property name="maxActive" value="300" /> <!-- 连接池最小空闲 --> <property name="minIdle" value="0" /> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="60000" /> <!-- <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> --> <property name="validationQuery" value="${sessionFactory.hibernate.validationQuery}" /> <!-- 检测有效性 --> <property name="testOnBorrow" value="true" /> <property name="testOnReturn" value="false" /> <property name="testWhileIdle" value="true" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="19000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="19000" /> <!-- 打开removeAbandoned功能 --> <property name="removeAbandoned" value="true" /> <!-- 1800秒,也就是30分钟 --> <property name="removeAbandonedTimeout" value="1800" /> <!-- 关闭abanded连接时输出错误日志 --> <property name="logAbandoned" value="true" /> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --> <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> <!-- 监控数据库 --> <!-- <property name="filters" value="mergeStat" /> --> <property name="filters" value="stat" /> </bean> <!-- 配置sessionFactory --> <bean id="masterSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="sessionFactoryDataSource"></property> <property name="hibernateProperties"> <props> <prop key="hibernate.hbm2ddl.auto">${switch_session_factory_hibernate.hbm2ddl.auto}</prop> <prop key="hibernate.dialect">${switch_session_factory_hibernate.dialect}</prop> <prop key="hibernate.show_sql">${switch_session_factory_hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${switch_session_factory_hibernate.format_sql}</prop> <prop key="hibernate.use_sql_comments">${switch_session_factory_hibernate.use_sql_comments}</prop> <prop key="current_session_context_class">thread</prop> </props> </property> <!-- 自动扫描注解方式配置的hibernate类文件 --> <property name="packagesToScan"> <list> <value>sy.model.base</value> </list> </property> </bean> <import resource="classpath:switchSessionFactory/moreSessionFactory/*.xml" /> <!-- 配置sessionFactory 多个的实现--> <bean id="sessionFactory" class="sy.datasource.sessionFactory.DynamicSessionFactoryImpl"> <property name="targetSessionFactorys"> <map> <entry value-ref="masterSessionFactory" key="master"/> <entry value-ref="s_adminSessionFactory" key="s_admin"/> </map> </property> <property name="defaultTargetSessionFactory" ref="masterSessionFactory"/> </bean> <!-- 配置事务管理器 --> <bean id="switch_session_factory_transactionManager" class="sy.datasource.sessionFactory.DynamicTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 拦截器方式配置事物 --> <tx:advice id="switch_session_factory_txAdvice" transaction-manager="switch_session_factory_transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="saveOrUpdate*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="grant*" propagation="REQUIRED" /> <tx:method name="init*" propagation="REQUIRED" /> <tx:method name="*" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <aop:config> <!-- 第一个*代表所有的返回值类型;第二个*代表所有的类;第三个*代表类所有方法;..代表子或者孙子包;最后一个..代表所有的参数 --> <aop:pointcut id="switch_session_factory_transactionPointcut" expression="(execution(* sy.service.base..*Impl.*(..)))" /> <aop:advisor pointcut-ref="switch_session_factory_transactionPointcut" advice-ref="switch_session_factory_txAdvice" /> </aop:config> </beans>
每一个sessionFactory就加一个这个配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:c="http://www.springframework.org/schema/c" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!--自定义表命名 多表映射 admin --> <bean id="s_adminNamingStrategy" class="sy.datasource.sessionFactory.strategy.TNamingStrategy"> <property name="suffix" value="s_admin" /> </bean> <bean id="s_adminSessionFactory" parent="masterSessionFactory"> <property name="namingStrategy" ref="s_adminNamingStrategy"/> </bean> </beans>
最后在web.xml加上
<filter> <filter-name>openSessionInView</filter-name> <!-- <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> --> <filter-class>sy.datasource.sessionFactory.MyOpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter>
到此,spring下的hibernate多表映射就大功造成了!
相关推荐
在Java的持久化框架Hibernate中,关联映射是至关重要的概念,它允许我们将数据库中的表关系映射到对象之间的关系。SSH(Struts、Spring、Hibernate)是经典的Java Web开发框架,其中Hibernate负责数据访问层,提供了...
本文将深入探讨“hibernate关联映射实例”中的关键知识点,包括一对多、多对多和继承映射,这些都是Hibernate中至关重要的概念。 1. **一对多关联映射**: 在现实世界中,一个实体可能会与多个其他实体相关联,...
本笔记将详细介绍SSH映射文件配置的三个核心部分:基础配置参数使用、多对一映射以及一对多映射。 **基础配置参数使用** SSH的基础配置通常位于`~/.ssh/config`文件中,此文件可以定义不同的主机别名和相关设置。...
其中,Hibernate是一个对象关系映射(ORM)框架,它简化了数据库与Java对象之间的交互。在SSH项目中,正确配置Hibernate的jar包是确保数据库操作顺利进行的关键步骤。 该压缩包“SSH中Hibernate所需基本jar包”包含...
SSH整合指的是将Spring、Struts2和Hibernate5这三大开源框架进行集成,以构建高效、模块化的Java Web应用程序。在本教程中,我们将探讨如何将Hibernate5与Spring框架结合使用,实现数据持久化功能。 首先,...
Hibernate通过映射文件将Java类和数据库表进行绑定,使得对象可以直接持久化到数据库中。 2. **Hibernate核心包**:在SSH框架中,构建Hibernate所需的最基础包包括`hibernate-core`。这个包包含了Hibernate的主要...
**Hibernate4** 是一个对象关系映射(Object-Relational Mapping,ORM)框架,它可以将Java对象与数据库中的记录进行映射,从而避免了传统的SQL操作。Hibernate4提供了强大的查询语言HQL和Criteria API,使得开发者...
在Hibernate中,每个Java类都可以映射到数据库中的一个表,这通过创建一个XML映射文件(如:`User.hbm.xml`)来实现。映射文件定义了类的属性与数据库字段的对应关系,以及主键生成策略等。例如: ```xml ...
在SSH2中,Hibernate作为持久层框架,负责对象关系映射(ORM),使得Java对象可以直接与数据库进行交互。 **Hibernate ORM框架** Hibernate是一个强大的ORM框架,它消除了传统的JDBC繁琐的代码,提供了对数据库操作...
Hibernate通过XML配置或注解将Java对象与数据库表对应,实现了数据的透明持久化。它支持懒加载、级联操作、缓存策略等功能,使得数据库操作更加便捷高效。 4. 数据库:SSH整合中的“database”标签可能涉及到数据库...
除了上述内容,还有更多高级特性如JPA支持、Hibernate Search、CGLIB动态代理等,可以进一步探索学习。 学习风格: 1. 先脉络,后细节:先理解整体框架和核心概念,再深入细节。 2. 先操作,后原理:通过实践来...
通过Hibernate,Java对象可以直接映射到数据库表,极大地提高了开发效率。在电商系统中,如当当网, Hibernate能够便捷地处理商品信息、订单、用户数据等复杂的数据操作。 当当网采用SSH框架进行开发,这表明他们在...
它允许开发者用Java对象来表示数据库中的表,通过HQL(Hibernate Query Language)或JPQL(Java Persistence Query Language)进行查询,降低了SQL操作的复杂性。Hibernate支持实体的生命周期管理,包括持久化、检索...
Hibernate是一个强大的ORM框架,它将Java对象与数据库表进行映射,让开发者可以使用面向对象的方式来操作数据库,降低了对SQL的依赖。Hibernate通过配置文件定义实体类与数据库表的关系,提供了一套CRUD(创建、读取...
Java SSH项目是基于三个主要框架——Struts、Spring和Hibernate构建的企业级Web应用程序。这个项目中,Hibernate作为ORM(对象关系映射)工具被用来处理数据库操作,而使用了注解方式来配置Hibernate,这是一种更加...
在火车订票系统中,Hibernate负责数据持久化,将Java对象映射到数据库表,通过ORM机制实现了对数据库的CRUD(创建、读取、更新、删除)操作,使得开发者无需编写大量SQL代码,提高了开发效率。 项目中可能包含以下...
以上就是SSH框架中使用Struts2和Hibernate实现图片上传的主要知识点,涵盖了Web请求处理、ORM框架、文件上传、数据库操作以及前端交互等多个方面。实际项目开发时,还需要结合具体的业务需求和安全规范进行详细设计...
Hibernate通过映射文件(hbm.xml)将Java类和数据库表关联起来,提供了透明的数据库访问。它简化了SQL操作,使得开发者无需编写大量数据库操作代码,只需关注业务逻辑。同时,Hibernate3.1引入了Criteria查询和HQL...
此外,Spring的事务管理能确保数据库操作的一致性和可靠性,对于多表操作如联表查询尤其重要。在SSH部门员工管理中,Spring可以帮助我们实现跨多个表的操作,例如查询某个部门的所有员工,或者根据员工ID获取其所在...
在Hibernate3.0版本中,通过配置hibernate.cfg.xml文件,你可以定义实体类和数据库表的映射关系,使用HQL(Hibernate Query Language)进行查询。Hibernate还提供了Session接口,用于与数据库交互,实现CRUD操作。 ...