Spring+Hibernate+Struts2

JDBC和Hibernate两个不同点
(1)操作的对象不同:JDBC操作的是数据,将数据通过SQL语句直接传送到数据库中执行,Hibernate操作的是持久化对象,由底层持久化对象的数据更新到数据库中。
(2)数据状态不同:JDBC操作的数据是“瞬时”的,变量的值无法与数据库中的值保持一致,而Hibernate操作的数据是可持久的,即持久化对象的数据属性的值是可以跟数据库中的值保持一致的。

hibernate方言是要把Java对象转换成关系数据库来描述的,而关系数据库虽然有一些统一的标准,如SQL-92等,但是实际上各数据库如Oracle, MySQL, MS SQL Server等等为了提高性能或增加功能都提供了一些额外的标准或语法,因此,hibernate为了更好适配各种关系数据库,针对每种数据库都指定了一个方言dialect。hibernate里面实际上方言只是一个类,它里面将不同数据类型、SQL语法转换成hibernate能理解的统一的格式。但注意,如果没有对应的dialect,Hibernate是无法使用这种数据库进行对象关系转换的。

hibernate.hbm2ddl.aut o 的参数说明
主要用于:自动创建|更新|验证数据库表结构。如果不是此方面的需求建议set value=”none”。
create:
每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop :
每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
update:
最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
validate :
每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。

1.在hibernate里面写sql执行时候不要用session.createQuery(sql); 需要用session.createSQLQuery(sql);

2.在hibernate里面写hql执行是误把hql写成了sql,比如说:select * , from 表名,hibernate框架操作数据库的核心就是:用操作数据对象代替操作表,给程序员的感觉是面向对象操作数据库。所以查询语句from后面接的不是表名称,而是javabean数据对象名。

关于主键配置的问题

在hibernate中一个数据模型的主键常用有三种形式:uuid、native、assigned,分别是通用唯一标识、自增、自定义。
1、uuid是系统产生的,insert数据库时相比native要快很多,但是uuid是一长串无序字符串,理论上讲查找起来会慢一点,但是不太会影响开发的。而native是数据库生成,在insert时会先计算所以会比uuid慢一点,但是在查找和删除数据时,会比较方便。
2、uuid和assigned的生成是在程序中完成的,一个是自动,一个是手动。所以在进行session.save()时,不会产生sql语句,数据库中也不会有数据。而native需要读取数据库数据才能完成自动递增,所以在执行session.save()时,就会产生相应的sql语句,数据库中就会有数据(缓存中id是有值的)。

Cascade 级联操作 
CascadeType. PERSIST 级联持久化 ( 保存 ) 操作 
CascadeType. MERGE 级联更新 ( 合并 ) 操作 
CascadeType. REFRESH 级联刷新操作,只会查询获取操作 
CascadeType. REMOVE 级联删除操作 
CascadeType. ALL 级联以上全部操作 

Fetch 抓取是否延迟加载,默认情况一的方为立即加载,多的一方为延迟加载 .
FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载。
FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。

mappedBy= "exam" 表示在ExamUserAns 类中的 exam 属性来维护关系,这个名称必须和ExamUserAns中的exam属性名称完全一致才行。另外需要注意,Exam类中的集合类型必须是List或者Set,不能设置为ArrayList,否则会报错.

一对多:
private GhfcMailclassify ghfcmailclassify;
@ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "CID")
    public GhfcColleges getGhfccolleges() {
        return ghfccolleges;
    }
private Set<GhfcMailbox> ghfcmailbox=new HashSet<GhfcMailbox>(0);
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "ghfcmailclassify")
    public Set<GhfcMailbox> getGhfcmailbox() {
        return ghfcmailbox;
    }

applicationContext.xml无错有红叉,虽然挂红叉能运行,但有个严重的问题是Hibernate逆向生成model和dao层的时候如果使用spirng来管理,则SessionFactoryId很可能是空的,就不能继续往下生成了。这很可能是因为spket插件冲突导致的。

Spring配置文件说明

<?xml version="1.0" encoding="GBK"?>
<!-- 指定Spring配置文件的Schema信息 -->
<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:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/tx 
 http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
 http://www.springframework.org/schema/aop 
 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

 <!-- 定义数据源Bean,使用C3P0数据源实现 -->
 <bean id="dataSource" destroy-method="close"
  class="com.mchange.v2.c3p0.ComboPooledDataSource">
  <!-- 指定连接数据库的驱动 -->
  <!-- 指定连接数据库的URL -->
  <!-- 指定连接数据库的用户名 -->
  <!-- 指定连接数据库的密码 -->
  <!-- 指定连接数据库连接池的最大连接数 -->
  <!-- 指定连接数据库连接池的最小连接数 -->
  <!-- 指定连接数据库连接池的初始化连接数 -->
  <!-- 指定连接数据库连接池的连接的最大空闲时间 -->

数据库连接数:最多能够同时接受多少个客户的连接.
在没有数据库连接池的情况下,一个客户,每次访问,就要创建一个 数据库连接,执行 SQL,获取结果,然后关闭、释放掉数据库连接。问题就在于创建一个数据库连接,是一个很消耗资源,花费很多时间的操作。于是,数据库连接池产生了。数据库连接池预先打开一定数量的数据库连接并维持着连接。当客户要执行SQL语句的时候,从 数据库连接池里面,获取一个连接,执行SQL, 获取结果,然后把数据库连接,交还给数据库连接池。
目的: 消除数据库频繁连接带来的开销和瓶颈。解决办法就是使用代理类,来中间解决。
数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回方法。如: 外部使用者可通过getConnection 方法获取连接,使用完毕后再通过releaseConnection 方法将连接返回,注意此时连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。 
数据库连接池技术带来的优势: **资源重用  更快的系统响应速度 新的资源分配手段  统一的连接管理,避免数据库连接泄漏** 

  <!-- mysql -->
  <property name="driverClass" value="com.mysql.jdbc.Driver"/>
  <property name="jdbcUrl"
   value="jdbc:mysql://localhost:3306/auction"/>
  <property name="user" value="root"/>
  <property name="password" value="mysql"/>
  <property name="maxPoolSize" value="40"/>
  <property name="minPoolSize" value="1"/>
  <property name="initialPoolSize" value="1"/>
  <property name="maxIdleTime" value="20"/>

  <!--MSSQL-->
   <property name="driverClassName"
   value="net.sourceforge.jtds.jdbc.Driver"></property> <property
   name="url"   value="jdbc:jtds:sqlserver://localhost:1433;DatabaseName=txDB"></property>
   <property name="username" value="sa"></property> 
   <property name="password" value="123456"></property>

  <!-- Oracle -->
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
  <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property>
  <property name="username" value="orcl"></property>
  <property name="password" value="orcl"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>

 </bean>

 <!-- 定义Hibernate的SessionFactory -->
 <bean id="sessionFactory"  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  <!-- 依赖注入数据源,注入上面定义的dataSource -->
  <property name="dataSource" ref="dataSource"/>
  <!-- mappingResouces属性用来列出全部映射文件 -->
  <property name="mappingResources">
   <list>
<!-- 以下用来列出Hibernate映射文件 -->                
    <value>com/model/A.hbm.xml</value>
    <value>com/model/B.hbm.xml</value>
    <value>com/model/C.hbm.xml</value>
    <value>com/model/D.hbm.xml</value>
   <value>com/model/E.hbm.xml</value>
   </list>
  </property>
  <!-- 定义Hibernate的SessionFactory的属性 -->
  <property name="hibernateProperties">
   <props>
    <!-- 指定数据库方言 -->
    <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
    <!-- 
    <prop key="hibernate.dialect">
     org.hibernate.dialect.MySQLInnoDBDialect</prop>
     -->
    <!-- 是否根据需要每次自动创建数据库 -->
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    <!-- 显示Hibernate持久化操作所生成的SQL -->
    <prop key="hibernate.show_sql">true</prop>
    <!-- 将SQL脚本进行格式化后再输出 -->
    <prop key="hibernate.format_sql">true</prop>
   </props>
  </property>
 </bean>

 <!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 -->
 <!-- 该类实现PlatformTransactionManager接口,是针对Hibernate的特定实现-->
 <bean id="transactionManager" 
 class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <!-- 配置HibernateTransactionManager时需要依注入SessionFactory的引用 -->
  <property name="sessionFactory" ref="sessionFactory"/>
 </bean>

 <!-- 配置事务切面Bean,指定事务管理器 -->
 <tx:advice id="txAdvice" transaction-manager="transactionManager">
  <!-- 用于配置详细的事务语义 -->
  <tx:attributes>
   <!-- 所有以'get'开头的方法是read-only的 -->
   <tx:method name="get*" read-only="true"/>
   <!-- 其他方法使用默认的事务设置 -->
   <tx:method name="*"/>
  </tx:attributes>
 </tx:advice>
 <aop:config>
  <!-- 配置一个切入点,匹配指定包下所有以Impl结尾的类执行的所有方法 -->
  <aop:pointcut id="myService"
   expression="execution(* com.service.impl.*Impl.*(..))"/>
  <!-- 指定在leeService切入点应用txAdvice事务切面 -->
  <aop:advisor advice-ref="txAdvice" 
   pointcut-ref="myService"/>
 </aop:config>

 <!-- 定义JavaMailSenderImpl,它用于发送邮件 -->
 <bean id="mailSender"
 class="org.springframework.mail.javamail.JavaMailSenderImpl">
  <!-- 指定发送邮件的SMTP服务器地址 -->
  <property name="host" value="smtp.163.com"/>
  <property name="javaMailProperties">
   <props>
    <prop key="mail.smtp.auth">true</prop>
    <prop key="mail.smtp.timeout">25000</prop>
   </props>
  </property>
  <!-- 指定登录邮箱的用户名、密码 -->
  <property name="username" value="263"/>
  <property name="password" value="263"/>
 </bean>
 <!-- 定义SimpleMailMessage Bean,它代表了一份邮件 -->
 <bean id="mailMessage"
  class="org.springframework.mail.SimpleMailMessage">
  <property name="from" value="XXXt@163.com"/>
  <!-- 指定邮件标题 -->
  <property name="subject" value="title"/>
 </bean>

 <!-- 配置业务逻辑组件 -->
 <bean id="mgr"
 class="com.service.impl.AuctionManagerImpl">
  <!-- 为业务逻辑组件注入所需的DAO组件 -->
  <property name="aDao" ref="aDao"/>
 </bean>
 <!-- 配置一个TimerTask Bean -->
 <bean id="checkWiner" class="org.crazyjava.auction.schedule.CheckWiner">
  <!-- 依赖注入业务逻辑组件 -->
  <property name="mgr" ref="mgr"/>
 </bean>
 <!-- 将TimerTask Bean:checkWiner包装成可周期性执行的任务调度Bean -->
 <bean id="scheduledTask"
 class="org.springframework.scheduling.timer.ScheduledTimerTask">
  <!-- 指定调度频率和延迟 -->
  <property name="delay" value="0"/>
  <property name="period" value="86400000"/>
  <property name="timerTask" ref="checkWiner"/>
 </bean>
 <!-- 启动实际调度 -->
 <bean id="timerFactory" 
 class="org.springframework.scheduling.timer.TimerFactoryBean">
  <!-- 下面列出所有需要调用的任务调度Bean -->
  <property name="scheduledTimerTasks">
   <list>
    <ref bean="scheduledTask"/>
   </list>
  </property>
 </bean>
</beans>

struts constant详解

<!-- 指定Web应用的默认编码集,相当于调用 HttpServletRequest的setCharacterEncoding方法 -->   
<constant name="struts.i18n.encoding" value="UTF-8" />   
<!-- 该属性指定需要Struts2处理的请求后缀,该属性的默认值是action,即 所有匹配*.action的请求都由Struts 2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开 -->   
<constant name="struts.action.extension" value="do" />   
<!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->   
<constant name="struts.serve.static.browserCache "value="false" />   
<!-- 当 struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 -->   
<constant name="struts.configuration.xml.reload" value="true" />   
<!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->   
<constant name="struts.devMode" value="true" />   
<!-- 默认的视图主题 -->   
<constant name="struts.ui.theme" value="simple" />   
<!-- 该属性指定Struts2中的action由Spring容器创建 -->   
<constant name="struts.objectFactory" value="spring" />
**其他常量**
<constant name="struts.action.excludePattern"value="/ShitServlet"/>
<constant name="struts.enable.DynamicMethodInvocation"value="false"/>
<constant name="struts.multipart.maxSize"value="1024000"/>
<!--最大上传1M的图片-->
<constantname="struts.multipart.saveDir"value="D:/temp"/>
<!--临时目录->
<constantname="struts.convention.result.path"value="/"/>
<constantname="struts.convention.classes.reload"value="true"/>
<constantname="struts.devMode"value="true"/>
<constantname="struts.ui.theme"value="simple"/>
<constantname="struts.i18n.encoding"value="UTF-8"/>
<constantname="struts.custom.i18n.resources"value="message"/>
<constantname="struts.locale"value="zh-cn"/>
<!--可上传的图片后缀-->
<constantname="com.chinacnd.allowed.images"value="gif,jpeg,jpg,png,bmp"/>

struts2报错:ognl.InappropriateExpressionException:0.3203350929900053
这个问题就是你提交的请求参数里面存在变量名为数字的参数或为空,这样肯定不合法的,在后台类action里面你不可能会定义变量名为数字的变量。

实现

一、
1.在spring中初始化hibernatetemplate,注入sessionfactory
2.dao里注入hibernatetemplate
    HibernateTemplate hibernateTemplate;    
    /**
     * 需要对应的get和set
     */
    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
    hibernateTemplate.save(obj);
    hibernateTemplate.flush();
二、
1.从HibernateDaoSupport继承
2.必须在xml文件中定义。
    <!-- BaseDao -->
    <bean id="baseDao" class="com.dao.BaseDao">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

public class BaseDao extends HibernateDaoSupport{
    public void save(Object o) {
        this.getHibernateTemplate().save(obj);
        this.getHibernateTemplate().flush();}
}

Transaction 事物开始,结束。定义在service层。AOP思想。
在方法前加   @Transactional(propagation=Propagation.REQUIRED)
<bean id="txManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="txManager" />
之前用的是try catch s.getTransaction().rollback();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值