笔记

本文详细介绍了Struts2与Spring框架的整合方法,包括配置步骤及注意事项。同时深入探讨了Spring与Hibernate整合的优势,以及Hibernate实现继承数据库设计的不同策略,并对Hibernate缓存机制、批量处理、查询抓取策略等方面进行了讲解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Struts2整合spring

1.web.xml文件中配置   

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/classes/applicationContext-*.xml</param-value>

  </context-param>

*表示通配符只有这里自己可以改其余的都是固定的。

 

Spring的监听器

<servlet>

    <servlet-name>SpringContextServlet</servlet-name>

    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>

    <load-on-startup>1</load-on-startup>

  </servlet>

 

 

然后在类里面写WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

 

ctx.getBean(“”)ok

 

 

 

 

*******************************************************************************spring整合hibernate

好处:1、通用的资源管理

      2、基于依赖注入的sessionFactory管理机制。

      3、优秀的管理机制

      4、统一的事务管理

      5、统一的异常管理

 

 

继承映射:

比如:person类中有personidnameage三个属性。

Student继承了person类,自己又有studentidno(学号)属性。

Techer也继承了person类,自己又有techeridmoney(工资)属性。

表一共有三种情况:

1.       所以的类共用一张表

配置如下:

<class name="extendsrelation.Person" table="extendsrelation" discriminator-value="3">

       <id name="peronsid" type="string" column="personid">

           <generator class="uuid.hex" />

       </id>

        <discriminator column="tag" type="string" />这个表示一个标记

       <property name="name" column="name" type="string"></property>

       <property name="age" column="age" type="int"></property>

      

       <subclass name="extendsrelation.Student" discriminator-value="1">

           <property name="number"  />

        </subclass>

       

       <subclass name="extendsrelation.Teacher" discriminator-value="2">

           <property name="money"  />

        </subclass>

    </class>

 

   从上可以看出在extendsrelation表中3表示person数据、1表示student数据、2表示teacher数据

但是查询person数据是会把所有的数据都查询出来,因为继承关系。但是只能查询student、和teacher中父类没有的数据,person中的数据都能查的出来

2.       每个子类都有一张表。

配置如下:

<class name="extendsrelation.Person" abstract="true">

       <id name="peronsid" type="string" column="id">

           <generator class="uuid.hex" />

       </id>

       <property name="name" column="name" type="string"></property>

       <property name="age" column="age" type="int"></property>

      

        <union-subclass name="extendsrelation.Student" table="extendsStudent">

           <property name="number"  />

        </union-subclass>

 

        <union-subclass name="extendsrelation.Teacher" table="extendsteacher">

           <property name="money"  />

        </union-subclass>

</class>

查询的父类的时候都可以把子类的数据查询出来,但是不在子类里写id,它会自动的生成id,但是子类的的id各不相同,主要父类不要sava,会报错的,因为没有表。

3.       每个类一张表。

配置如下:

<class name="extendsrelation.Person" table="extendsmanyperson">

       <id name="peronsid" type="string" column="id">

           <generator class="uuid.hex" />

       </id>

       <property name="name" column="name" type="string"></property>

       <property name="age" column="age" type="int"></property>

      

         <joined-subclass name="extendsrelation.Student" table="extendssstudent">

             <key column="id"/>

            <property name="number"/>

         </joined-subclass>

       

        <joined-subclass name="extendsrelation.Teacher" table="extendsteacher">

             <key column="id"/>

            <property name="money"/>

         </joined-subclass>

</class>

 

hibernate实现继承数据库设计的三种方式

1、继承关系中每个类都映射成一个数据库表基类和子类共用一个id来标识。

   优点就是完全符合面向对象思想,缺点是查询子类要级联查询多个表,效率低。

2、将整个类层次映射为单个数据库表。即所有的类都在一个数据库表中存储。

   很显然,这种方法的缺点是浪费存储空间,每条数据都会有null的字段存在,优点就是增删查改的效率比较高。

3、将每个子类分别映射成数据库表,基类不参与映射。

   优点是操作的单个表,效率高。缺点是修改基类的时候每个子类的数据库表都要修改,不支持多态查询。

 

现在常用的javaEE的ssh开发框架中,一般都采用第一种方法,完全面向对象的思想,易于理解开发维护。

 

  Hibernate中对继承关系的映射有三种方法:

1、每一个具体子类映射成单个数据库表,而抽象基类不参与映射。

 

优点:数据操作实现简单,每个表中都包含自己所需要的具体子类的所有信息,减少了多表关联操作时的性能消耗。

 

缺点:

类的修改会导致相对应的表及其子类所对应表的更改。不支持多态查询。

 

应用:

适合在类层次结构上有一定数量的抽象类的情况下使用。

 

2、将整个类层次映射为单个数据库表。

这对于子类属性不多的情况非常有效。每个子类由识别列(discriminator column)区分。

 

优点:

实现简单,并支持多态。同时数据访问也比较简单,因为数据库表中包含了所有需要的信息。

 

缺点:

增加类层次中的耦合,类层次中任何类的属性的增加都有会导致表的变更。另外,对子类属性的修改错误将会影响到整个类的层次结构。当然也浪费了大量的数据库空间。表中引入区分子类的字段,子类的字段不能创建为空。

 

3、继承关系中每个类均映射为一个数据库表

优点:

此时,与面向对象的概念是一致的,这种映射实现策略的最大好处就是关系模型完全标准化,关系模型和领域模型完全一致,易于修改基类和增加新的子类。

 

缺点:

数据库中存在大量的表,为细粒度级的数据模型,访问数据时将存在大量的关联表的操作,效率较低。

 

select a.c_activities_name,a.c_activities_address,a.c_activities_introduction,a.c_activities_Date,

 

 

 

12.7

hibernate的批量处理:

1.       批量增加

<hibernate-mapping>

    <class name="batch.BatchPerson" batch-size="200" table="batchPerson">

Batch-size=200表示没200条记录就释放内存,更新数据库

       <id name="id" type="java.lang.String" column="id">

           <generator class="uuid.hex" />

       </id>

    <property name="name" type="java.lang.String" />

</class>

</hibernate-mapping>

 

 

public class MyBatch {

    public static void main(String[] args) {

       long l = System.currentTimeMillis();

       SessionFactory sf = new Configuration().configure()

       .buildSessionFactory();

       Session session = sf.openSession();

       Transaction tr = session.beginTransaction();

       BatchPerson batchPerson;

   

       for(int i = 0; i < 100000; i++){

           batchPerson = new BatchPerson();

           batchPerson.setName(""+i);

           session.save(batchPerson);

           if(i % 200 == 0){

              session.flush();

              session.clear();

              //session.evict(batchPerson);这个太慢了

           }

       }

   

       tr.commit();

       session.close();

       System.out.println(System.currentTimeMillis()-l);

    }

}

2.  批量修改

public class MyBatch {

    public static void main(String[] args) {

    long l = System.currentTimeMillis();      SessionFactory sf = new Configuration().configure()

       .buildSessionFactory();

       Session session = sf.openSession();

       Transaction tr = session.beginTransaction();

       BatchPerson batchPerson;

       Query query = session.createQuery("update BatchPerson set name=:name");

       query.setString("name", "huzhihua4");

       System.out.println(query.executeUpdate());

      

    tr.commit();

    session.close();

    System.out.println(System.currentTimeMillis()-l);

}

}以上这种效率最高

 

public class MyBatch {

    public static void main(String[] args) {

    long l = System.currentTimeMillis();  

   SessionFactory sf = new Configuration().configure()

       .buildSessionFactory();

       Session session = sf.openSession();

       Transaction tr = session.beginTransaction();

       BatchPerson batchPerson;

       Query query = session.createQuery("update BatchPerson set name=?");

       query.setString(0, "huzhihua4");

       System.out.println(query.executeUpdate());

      

    tr.commit();

    session.close();

    System.out.println(System.currentTimeMillis()-l);

}

}以上这个效率最低

 

public class MyBatch {

    public static void main(String[] args) {

    long l = System.currentTimeMillis();  

   SessionFactory sf = new Configuration().configure()

       .buildSessionFactory();

       Session session = sf.openSession();

       Transaction tr = session.beginTransaction();

       BatchPerson batchPerson;

       Query query = session.createQuery("update BatchPerson set name=’huzhihua’");

       System.out.println(query.executeUpdate());

      

    tr.commit();

    session.close();

    System.out.println(System.currentTimeMillis()-l);

}

}以上这种删除很高

3.  批量删除

session.createQuery("delete BatchPerson").executeUpdate()

 

每个Session内部会存在一个数据缓存,它随着 Session的创建而存在,随着Session的销毁而灭亡,因此也称为Session Level Cache.

hibernate的缓存:一级缓存(内置缓存)session缓存  数据--à缓存(session缓存)--à数据库

session.flush()把缓存中的数据放到数据库中,缓存的数据就没有了

session.clear()把缓存清掉,

session.sava(Object);object放到缓存中

clear缓存就没有数据了。

所以commit()就插不进数据。commit其实就是flush()但是要在hibernate.cfg.xml文件中加一句<property name="connection.autocommit">true</property>flush()就相当commit了,记住要把事务去掉

 

应用级缓存:即在某个应用中或应用中某个独立数据库访问子集中的共享缓存,此缓存可由多个事务共享(数据库事务或应用事务),事务之间的缓存共享策略与应 用的事务隔离机制密切相关.Hibernate,应用级缓存由SessionFactory实现,所有由一个SessionFactory创建的 Session实例共享此缓存,因此也称为SessionFactory Level Cache.

结论:Hibernate进行查询时总是先在缓存中进行查询,如缓存 中没有所需数据才进行数据库的查询.Hibernate的内部缓存是基于Session的生命周期的,也就是说存在于每个Session内部,它随着 Session的创建而存在,随着Session的销毁而灭亡,内部缓存一般由Hibernate自动维护,不需要人为干预,当然我们也可以根据需要进行 相应操作:Session.evict(Object)(将指定对象从内部缓存清除),Session.clear()(清空内部缓存).(如在两次查询 间加入Session.clear()将会清空内部缓存,使得一个Sesion内部的两次相同的查询要对数据库进行两次操作).

 

二级缓存:叫应用级缓存也叫sessionFactory缓存

Hibernate加载对象用二种方式:loadget方法

load

get的区别

1.       当数据库中没有加载的数据时,load则会抛出异常

“org.hibernate.ObjectNotFoundException:No row with the given identifies exist....”

get的到null

2.       load支持延迟加载,get不支持.

   

   loadget都支持一级缓存。(你看下控制台的sql语句,用loadget查询二条相同的数据时,只会有一条sql语句或者用loadget查询相同的数据。记住是同一个session

 

 

 

1.读取时机不同(当lazy=true的时候)

    load是采用延迟机制(load语句不读库,等使用非主键时才去读库),而get不采用延迟机制(get语句时马上读库)

 

2.搜索不到数据时的情况

    当搜索的数据不存在的时候,load依然会返回一个对象,在你使用该对象的非主键数据时,会抛出异常;

    当搜索的数据不存在的时候,get会返回一个null

 

备注:网上看来说loadget更节省资源;

  

 

使用二级缓存就可以多个session共享了(使用一级缓存多个不同的session是不共享缓存的)

使用二级缓存的步骤:

1. 开启二级缓存

    <property name="hibernate.cache.use_second_level_cache">true</property>

2. 指定缓存产品提供商

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

3.指定那个类用缓存

<class-cache class="batch.BatchPerson" usage="read-only"/>

这句话必须放到hibernata.cfg.xml配置文件中的</session-factory>上面,不然报错

 

清除二级缓存:sf.evict(BatchPerson.class);sf是指sessionFactory的对象,BatchPerson是要清除的对象

 

Hibernate本身并未提供二级缓存的产品化实现(只提供了一个基于HashTable的简单缓存以供调试),这里我使用的是第三方缓存组件:EHcache.Hibernate的二级缓存实现需要进行以下配置(Hibernate3):

首先在hibernate.cfg.xml内添加:
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>  
<property name="hibernate.cache.use_query_cache">true</property>  

Hibernate二级缓存是SessionFactory级的缓存,它允许多个Session间共享,使用时需要使用第三方的缓存组件,新版HibernateEHcache作为默认的二级缓存实现.

缓存同步策略:缓存同步策略决定了数据对象在缓存中的存取规则,我们必须为每个实体类指定相应的缓存同步策略.Hibernate中提供了4种不同的缓存同步策略:(暂时只记个概念吧)

       1.read-only:
只读.对于不会发生改变的数据可使用
.

       2.nonstrict-read-write:
如果程序对并发访问下的数据同步要求不严格,且数据更新频率较低,采用本缓存同步策略可获得较好性能
.

       3.read-write:
严格的读写缓存.基于时间戳判定机制,实现了"read committed"事务隔离等级.用于对数据同步要求的情况,但不支持分布式缓存,实际应用中使用最多的缓存同步策略
.

       4.transactional:
事务型缓存,必须运行在JTA事务环境中.此缓存中,缓存的相关操作被添加到事务中(此缓存类似于一个内存数据库),如事务失败,则缓冲池的数据会一同回 滚到事务的开始之前的状态.事务型缓存实现了"Repeatable read"事务隔离等级,有效保证了数据的合法性,适应于对关键数据的缓存,Hibernate内置缓存中,只有JBossCache支持事务型缓存.

以上红色是从网上copy下来的

 

CacheMode参数用于控制具体的Session如何与二级缓存进行交互。

·  CacheMode.NORMAL - 从二级缓存中读、写数据。

·  CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。(查询不会进缓存)

·  CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。(查询的时候进缓存)

·  CacheMode.REFRESH - 仅向二级缓存写数据,但不从二级缓存中读数据。通过 hibernate.cache.use_minimal_puts的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。

 

 

 

启动hibernate的查询缓存:<!-- 启用查询缓存 -->

        <property name="hibernate.cache.use_query_cache">true</property>

//启用查询查询缓存

            query.setCacheable(true);

 

 

hibernate的延迟加载,也叫懒加载。

延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。

Hibernate默认为延迟加载,就是lazy=”true”,把它设为false就是立即加载。

重要的概念 1lazy的概念指在需要的时候才发出sql 2lazy策略只是在session打开期间才是有效的

 

在影射文件中的class中配置的

例子:

session.load(BatchPerson.class,"402881ab2568bb75012568bb77ae0001");不打印sql语句,设为false就打印。使用数据比如System.out.println(session.load(BatchPerson.class,"402881ab2568bb75012568bb77ae0001"));使用的数据会打印sql语句

属性(对象属性)、集合都有lazy设置。就是有关联的时候。

 

listiterate的区别(用到的缓存是二级的)

  获取数据的方式不一样,list()会直接查数据库, iterate()会先到数据库中把id都取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1。

list它把查询出来的数据放到缓存中,但它不会从缓存中查,直接查询数据库。iterate它不会把查询的数据放到缓存中,但它会从缓存中查询数据。

 

1.    使用list方法获取查询结果:
  
每次发出一条查询语句,查询所有对象;
2.
使用iterate方法获取查询结果:
  
首先发出一条查询语句,查询对象的id列表,然后检查缓存,只查找缓存中没有的数据。

 

Hibernate的抓取策略:

1.  连接抓取

2.  查询抓取

3.  子查询抓取

4.  批量抓取

Hibernate抓取策略

抓取策略(fetching strategy 是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对象的策略。抓取策略可以在O/R映射的元数据中声明,也可以在特定的HQL 或条件查询(Criteria Query)中重载声明。

 

Hibernate3 定义了如下几种抓取策略:

 

* 连接抓取Join fetching - Hibernate通过 SELECT语句使用OUTER JOIN(外连接)来 获得对象的关联实例或者关联集合。

 

*查询抓取Select fetching - 另外发送一条 SELECT 语句抓取当前对象的关联实体或集合。除非你显式的指定lazy="false"禁止 延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条select语句。

 

*子查询抓取Subselect fetching - 另外发送一条SELECT 语句抓取在前面查询到(或者抓取到)的所有实体对象的关联集合。除非你显式的指定lazy="false" 禁止延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条select语句。

 

*批量抓取Batch fetching - 对查询抓取的优化方案, 通过指定一个主键或外键列表,Hibernate使用单条SELECT语句获取一批对象实例或集合。

 

<set name="personSet" inverse="true" cascade="all" fetch="select" batch-size="2">  batch-size=”2”表示批量一次性抓二条,默认表示一条一条的抓

    <key column="addressid"/>

    <one-to-many class="com.zhuaqu.Person"/>

</set>

 

Hibernate的查询分为:hqlQBCQuery By Criteria)、sqlQBE(Query By Example 样板查询:一个一个属性去匹配,除了id)

createCriteria.add(Example.create(student))

 

 

hibernate的事务:

hibernate的局部事务就是jdbc轻量级的封装。

Transaction t = session.beginTransaction();

CRUD操作

t.commit()

connection.setAutoCommit(false);

CRUD操作

Connection.commit();一样

 

Hibernate的全局事务(JTA)(JTA横跨多个数据库和daoTamcat不支持全局事务,要用WebLogic

横跨多个session

 

Hibernate支持二种锁:一种是悲观锁,另一种是乐观锁

悲观锁是基于数据库的锁机制实现的:只支持单个事务的操作,通过LockMode对象来实现

乐观锁是采用数据库版本机制来实现的:<class name="com.suo.Teacher" table="teacher" optimistic-lock="version">

Optimistic-lock=”version”表示配置乐观锁,然后在对象中添加一个int类型的属性,然后配置文件下面的id下面写上

<version name="count" type="int"/>

没使用一次都会自动的加加

 

 

 

系统管理:1.用户、2.角色、3.权限、4.

用户表:idname              角色表:idname

用户角色表:userid roleid

 

 

权限表: id  功能模块名称  操作    url

角色权限表

roleid  权限id

 

 

 

Oracle的一些用户信息:

用户名: system       manager

         sys           c

         scott        tiger

创建用户:

CREATE USER "0802.HUZHIHUA" PROFILE "DEFAULT" IDENTIFIED BY "*******" DEFAULT TABLESPACE "USERS" TEMPORARY TABLESPACE "TEMP" ACCOUNT UNLOCK
GRANT "CONNECT" TO "0802.HUZHIHUA"

 

锁住用户:

ALTER USER "0802.HUZHIHUA" ACCOUNT LOCK

 

角色分配:

GRANT "DBA" TO "0802.HUZHIHUA"
ALTER USER "0802.HUZHIHUA" DEFAULT ROLE ALL

删除角色:

REVOKE "DBA" FROM "0802.HUZHIHUA"

 

删除系统权限:

REVOKE UNLIMITED TABLESPACE FROM "0802.HUZHIHUA"  UNLIMITED TABLESPACE是指系统权限名称

创建系统权限:GRANT ALTER ANY INDEX TO "0802.HUZHIHUA"  ALTER ANY INDEX是指系统权限名称

 

添加对象表的角色:

GRANT ALTER ON "SYSTEM"."STUDENT" TO "0802.HUZHIHUA" WITH GRANT OPTION
GRANT DELETE ON "SYSTEM"."STUDENT" TO "0802.HUZHIHUA"
GRANT INDEX ON "SYSTEM"."STUDENT" TO "0802.HUZHIHUA"
GRANT INSERT ON "SYSTEM"."STUDENT" TO "0802.HUZHIHUA"
GRANT REFERENCES ON "SYSTEM"."STUDENT" TO "0802.HUZHIHUA"
GRANT SELECT ON "SYSTEM"."STUDENT" TO "0802.HUZHIHUA"
GRANT UPDATE ON "SYSTEM"."STUDENT" TO "0802.HUZHIHUA"

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值