SSH三大框架知识点
Hibernate
****************************************************************************************************
Hibernate工作原理流程?
原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Session 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Session 8.关闭SesstionFactory
为什么要用Hibernate
为什么要用: 1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。 2.hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM(对象关系映射)实现。他很大程度的简化DAO层的编码工作 3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。 4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
使用Hibernate之前要配置什么
.使用Hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件中需要登记每个hbm.xml文件。
使用Hibernate的基本流程是:
配置Configuration对象、产生SessionFactory、创建session对象,启动事务,完成CRUD操作,提交事务,关闭session。
相对于SQL,HQL查询语言有什么特点,什么是方言?
答:sql是关系数据库查询语言,面对的数据库;而hql是Hibernate这样的数据库持久化框架提供的内置查询语言,虽然他们的目的都是为了从数据库查询需要的数据,但sql操作的是数据库表和字段,而作为面向对象的hql操作的则是持久化类及其属性,
****************************************************************************************************
Hibernate架构,对象有三种状态,分别是什么,怎样区分?
答:Hibernate三种状态的区分,以及save,update,saveOrUpdHibernate的对象有3种状态,
分别为:瞬时态(Transient)、持久态(Persistent)、脱管态(Detached)。
1.瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
2.持久对象具有如下特点: 1. 和session实例关联; 2. 在数据库中有与之关联的记录。 3. 比瞬时对象多了一个数据库记录标识值。
3.托管态,也叫游离态等,持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象。
****************************************************************************************************
Hibernate中什么是延迟加载,延迟的作用是什么?
答:延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。
hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决;
解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1filed1,type2
field2),然后在hql里面就可以直接生成这个bean了。
第一个:查询出来的list 转换为一个数组
也就是说 Object[] objects=(Object[]) list -- 你查询出来的list 集合
for(object item :objects ){}进行自行封装处理
第二个说白了就是写个构造函数让他自己封装省了自己处理过程了
但是如果是查询出来的多张表数据 还是得按第一种方式自己处理的。。。
介绍一下Hibernate的二级缓存
(1)缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。
(2)Hibernate的Session就是一种缓存,我们通常将之称为Hibernate的一级缓存,当想使用session从数据库中查询出一个对象时,Session也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session代表一次会话过程,一个Session与一个数据库连接相关连,所以Session最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。并且Session是线程不安全的,被多个线程共享时容易出现问题。通常只有那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值,因此,Hibernate的Session这一级缓存的缓存作用并不明显,应用价值不大。Hibernate的二级缓存就是要为Hibernate配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存。我们希望的是一个人使用过,其他人也可以使用,session没有这种效果。
(3)二级缓存是独立于Hibernate的软件部件,属于第三方的产品,多个厂商和组织都提供有缓存产品,例如,EHCache和OSCache等等。在Hibernate中使用二级缓存,首先就要在hibernate.cfg.xml配置文件中配置使用哪个厂家的缓存产品,接着需要配置该缓存产品自己的配置文件,最后要配置Hibernate中的哪些实体对象要纳入到二级缓存的管理中。明白了二级缓存原理和有了这个思路后,很容易配置起Hibernate的二级缓存。扩展知识:一个SessionFactory可以关联一个二级缓存,也即一个二级缓存只能负责缓存一个数据库中的数据,当使用Hibernate的二级缓存后,注意不要有其他的应用或SessionFactory来更改当前数据库中的数据,这样缓存的数据就会与数据库中的实际数据不一致。
简述 Hibernate 和 JDBC 的优缺点? 如何书写一个 one to many 配置文件.
Hibernate就是封装了JDBC,他可以写一条hql语句,可以再不同数据库中使用,不用修改hql语句,但是关联查询效率低。 JDBC是基础的链接数据库的框架,效率高,但是mysql、oracle、sql service等不同的数据库要写不同的sql语句。 one to many比如Class和Student吧就是一个班级对应多个学生 在Class类中追加集合属性 Set<Student> students; 在Class的配置文件中追加(Class.hbm.xml) <!-- 追加集合属性的配置 --> <!-- 设置集合属性 --> <set name="students" lazy="false" fetch="join" cascade="all" inverse="true"> <!-- 设置关联字段 --> <key column="classId" /> <!-- 设置关联关系 --> <one-to-many class="Studnet" /> </set> 将Studnet中的classId属性去掉换成 Class class; 在Student的配置文件中(Student.hbm.xml) <many-to-one name="class" column="classId" lazy="false" fetch="join" class="Class"> </many-to-one>
三大框架各起的作用
struts 在 SSH 框架中起控制的作用 , 其核心是 (控制器)Controller, 即ActionServlet, 而 ActionServlet 的核心就是 Struts-config.xml. 主要控制逻辑关系的处理 . hibernate 是数据持久化层 , 是一种新的对象、关系的映射工具 , 提供了从 Java 类到数据表的映射,也提供了数据查询和恢复等机制 , 大大减少数据访问的复杂度。把对数据库的直接操作 , 转换为对持久对象的操作 .
spring 是一个轻量级的控制反转 (IoC) 和面向切面 (AOP) 的容器框架 , 面向接口的编程 , 由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。这也就是所谓“ 控制反转 ” 的概念所在:(依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中 起到的主要作用是解耦
****************************************************************************************************
整合SSH
把hibernate的配置写到spring的配置中,用spring管理和调用hibernate的工厂和session等。
struts的话,通常有2中。一种是用spring中的一个工厂类代替struts的工厂类去生成action,并且用spring管理。 另一种是,struts 用自己的工厂生成action,但是由spring管理。这样耦合低一些。
大概就是这样,hibernate负责它最擅长的数据库管理。 struts页面的请求处理调用相应的底层数据库等。spring负责管理他们两个。
****************************************************************************************************
整合SSH的三种方法
方法一:直接获得ApplicationContext对象
这种方法通过spring获取与Hibernate相关联的对象。
关键是在Action类中获得ApplicationContext对象,然后通过getBean方法获得JavaBean对象。
(1)在hibernate.cfg.xml文件中配置session-factory
<session-factory>
<property name="connection.url">
jdbc:MySQL://localhost/test?characterEncoding=UTF8
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<propertyname="connection.username">root</property>
<propertyname="connection.password">123</property>
<property name="show_sql">true</property>
<propertyname="hibernate.hbm2ddl.auto">update</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!—数据库的实体类映射文件-->
<mapping resource="User.hbm.xml" />
</session-factory>
(2)在applicationContext.xml文件中对hibernate相关联的对象使用依赖注入,使用Spring的HibernateTemplate类来对Hibernate的Session进行操作
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"value="classpath:hibernate.cfg.xml">
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory"ref="sessionFactory" />
</bean>
<!-- 事务拦截器bean需要依赖注入一个事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 设置事务传播特性,对应于AOP中的 <tx:advice /> -->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<propkey="get*">PROPAGATION_REQUIRED, readOnly
</prop>
<propkey="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定义BeanNameAutoProxyCreator,配置哪些类和哪些方法使用事务对应于AOP中的 <aop:pointcut/> -->
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 指定对满足哪些bean name的bean自动生成业务代理 -->
<property name="beanNames">
<!-- 下面是所有需要自动创建事务代理的bean-->
<list>
<value>userDAO</value>
</list>
<!-- 此处可增加其他需要自动创建事务代理的bean-->
</property>
<property name="interceptorNames">
<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<list>
<value>transactionInterceptor</value>
<!-- 此处可增加其他新的Interceptor-->
</list>
</property>
</bean>
<!--配置数据访问层对象-->
<bean id="userDAO"class="com.dao.UserDAOImpl">
<constructor-arg>
<ref bean="hibernateTemplate" />
</constructor-arg>
</bean>
<!--配置业务逻辑层对象-->
<bean id="userService"class="com.service.UserServiceImpl">
<constructor-arg>
<ref bean="userDAO" />
</constructor-arg>
</bean>
(3)配置struts.xml文件
<action name="loginAction"class="com.test.LoginAction">
<result name="result">/WEB-INF/result.jsp
</result>
</action>
(4)在Action中获取userService并使用
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
UserService userService = (UserServiceImpl) applicationContext.getBean("userService");
userService.addUser(user);
第一种方法的缺点:将Action类鱼Spring的装配JavaBean绑定的过紧,增加了其耦合度,不适合装配文件有变化的情况。
方法二:由Spring创建Action类的对象
在方法一的基础之上需要做如下几步修改
(1)在Action方法中增加setUserService的方法,把UserService交给spring处理
private UserService userService;
public void setUserService(UserServiceuserService) {
this.userService = userService;
}
(2)在application.xml文件中对action进行配置
<bean id=”loginAction”class=”com.test.LoginAction” scope=”prototype”>
<property name=” userService”>
<ref bean=” userService”>
</property>
</bean>
(3)在struts.xml文件中配置action
<action name=”LoginAction”class=”loginAction”/>
<!—注意这里class指向的是上面配置的bean对象-->
第二种方法的缺点:虽然使用了Spring的IOC特性,对Action和ApplicationContext对象进行了解耦,但配置一个Action需要同时维护两份文件:struts.xml和application.xml,比较难维护。
方法三:直接使用Spring的自动装配JavaBean的特性进行整合
在方法一的配置基础上进行如下修改
(1)编写UserAction类,在UserAction中添加setUserService方法,让spring自动装配
private UserService userService;
public void setUserService(UserServiceuserService) {
this.userService = userService;
}
(2)直接在Struts中配置LoginAction
<action name=”LoginAction”class=”com.test.LoginAction”/>
由于已经在application.xml文件中装配了userService属性,这样spring就可以自动装配LoginAction中的UserService了。
*****************************************************************************************************************************
其他
j2ee常用的设计模式?说明工厂模式。
总共23种,分为三大类:创建型,结构型,行为型
我只记得其中常用的6、7种,分别是:
创建型(工厂、工厂方法、抽象工厂、单例)
结构型(包装、适配器,组合,代理)
行为(观察者,模版,策略)
然后再针对你熟悉的模式谈谈你的理解即可。
工厂模式:
工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
单例模式
在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。