SSH学习笔记

时间:2021-02-01 20:39:48

Struts2登录模块处理流程:

  1. 浏览器发送请求http://localhost/appname/login.action,到web应用服务器;
  2. 容器接收到该请求,根据web.xml的配置,服务器将请求转到FilterDispatcher进行处理,进入Struts2的流程中;
  3. 框架在struts.xml配置文件中查找名为login的action对应的类;
  4. 框架初始化该Action,执行其中的set***方法填充数据,再执行excute方法;
  5. Execute方法执行后并返回字符串“success”或者“fail”,分别表示执行成功或失败;
  6. 框架检查配置以查看当返回的字符串所对应的页面。(structs.xml)

每一个action对象都服务一个请求,这和Servlet的原理是不一样的。

在action中:

Public class LoginAction{

Private LoginBean loginUser;

Public LoginBean getLoginUser(){

Return loginUser;

}

public LoginBean setLoginUser(){this.loginUser=loginUser;}

public String execute(){

if(loginUser.getAccount().equals(loginUser.getPassword())){

return “success”;

return “fail”;}

}

}

在Action类中访问servlet中对象的方式:通过ServletActionContext中定义的静态方法来获得servlet中的对象。

HttpServletRequest request=ServletActionContext.getRequest();

HttpServletResponse response=ServletActionContext.getResponse();

HttpSession session=request.getSession();

Action类中提供多个方法来处理多个不同类型的请求:

Public class LoginRegisterAction{

Public String login(){…}

Public String register(){…}

Public String execute(){…}

},此时,action在structs.xml的配置应该这么写:

配置方式

访问方式

方式一

声明action的名字和类型<action name="LoginRegisterAction"            class="...LoginRegisterAction">

</action>

为每一个处理请求的方法定义一个Action,如<action name=”login” class=”..LoginRegisterAction method=”login””>..</action>

如<action name=”register” class=”..LoginRegisterAction method=”register””>..</action>

方式二

http://localhost:8080/struts2/
      LoginRegisterAction!login.action

以actionName!methodName.action形式访问

以actionName.action形式访问,如

http://localhost:8080/struts2/login.action

Structs.xml示范:

<!--struts.xml-->

<?xml
version="1.0" encoding="UTF-8" ?>

<struts>

       <package name="strutsBean"

                        extends="struts-default"
namespace="/">

         <action name="login"
class="Actions.LoginAction">

               
<result name="success">/loginSuccess.jsp</result>

               
<result name="fail">/loginFail.jsp</result>

         </action>

       </package>

</struts>

Package中:name表示包名,extends用于设置对其他包的基础,通常继承一个structs2的内置包“structs-default”,可以多重继承。Namespace是命名空间,用于解决大型项目中的重名问题,不同命名空间下可以有相同的action名字。

Hibernate学习:

对象和关系映射:

在ORM中,一个PO对象,一般表示数据库中一条记录,只是对这个记录的操作可以简化成对这个Bean对象的操作,操作之后数据库中的记录相应变化。框架根据配置文件读取表格中各个列和Bean对象中各个属性的映射。框架提供一些能够对这些对象进行操作的函数。

Hibernate是一个面向java环境的数据库映射工具,管理java类到数据库的映射。把对对象的操作自动转化为对数据库的SQL语句操作。

原理:

对于一个数据库操作,其执行步骤为:

  1. 框架API通过读取Hibernate配置文件,连接到数据库
  2. 当对PO进行操作时,框架API通过Hibernate映射文件,来决定操作的表名和列名。
  3. 框架API执行SQL语句

利用Hibernate编程,步骤:

  1. 编写Hibernate配置文件,连接到数据库;
  2. 编写PO(属性的数据类型都选用了对象类型,而非基本数据类型,原因是属性和字段对应,只有对象才能表示空值的概念);
  3. 编写Hibernate映射文件,将PO和表映射(名字不一定相同,但基本上都命名为相同,并且放在同一个包下面),PO中的属性和表中的列映射;
  4. 编写DAO,使用Hibernate进行数据库操作

Hibernate实例:

package
po;

public
class Student {

         private String stuno;

         private String stuname;

         private String stusex;

         public String getStuno() { return
stuno; }

         public void setStuno(String stuno) {
this.stuno = stuno;}

         /**其它get, set方法**/     

}

Student.hbm.xml:

<hibernate-mapping>

      <class name="po.Student"
table="T_STUDENT">

         <id name="stuno"
column="STUNO">

                 
<generator class="assigned" />

         </id>

         <property name="stuname"
column="STUNAME" />

         <property name="stusex"
column="STUSEX" />

      </class>

</hibernate-mapping>

  • <class  name="类名"  table="表名">:类和表对应
  • <id name="属性" column="列名">:填写主键,即使表内没有主键,配置文件中也要配置一个唯一标识
  • <generator
    class="assigned"/>
    :主键的生成策略,assigned 表示由用户赋值
  • <property name="属性" column="列名"/>:将属性和列对应起来

注册映射文件:

在hibernate.cfg.xml中注册:

<hibernate-configuration>

<session-factory>

         <property
name="connection.username">root</property>

         <property name="connection.password"></property>

         <property
name="connection.driver_class">

                                       
com.mysql.jdbc.Driver</property>

              ……

         <mapping
resource="po/Student.hbm.xml" />

</session-factory>

</hibernate-configuration>

利用Hibernate进行数据库操作:

利用Hibernate基本API载入并建立连接:

  1. 读取Hibernate配置文件(Hibernate.cfg.xml):Configuration conf=new Configuration.configure();
  2. 生成SessionFactory,对session进行管理;SessionFactory sf = conf.buildSessionFactory();
  3. 利用SessionFactory打开Session Session=sf.openSession();

添加:session.saveOrUpdate(Object);

删除:session.delete(Object);

修改:Session.saveOrUpdate(Object);

查询:Object
Session.get(PO对应的类,主键);如Student stu=(Student)session.get(Student.class,”0002”);

RgusersDAO
dao = new RgusersDAO();//
实例化
DAO

Transaction
tran = dao.getSession().beginTransaction();//
打开事务

Rgusers
bean = new Rgusers();//
生成普通
Java
类                

bean.setUsername("赵六");// 设置属性

bean.setPassword("zhao1234");

bean.setUserId(4);         

dao.save(bean);//
插入数据               

tran.commit();//
提交事务

dao.getSession().close();

深入学习Hibernate:

  1. Configuration:(可以理解成与hibernate.cfg.xml对应)

一个Configuration实例代表了一个应用程序中Java类型到SQL数据库映射的完整集合;

用于构建SessionFactory;

可以使用Configuration类的configure方法来读取hibernate.cfg.xml文件,并负责管理配置信息;

Configuration conf =
new Configuration().configure();

SessionFactory sf =
conf.buildSessionFactory();

其他方法:addResourc(String
path):指定一个hbm文件路径,动态添加映射文件;

addClass(class persistentClass):指定PO类,载入该类对应配置的映射文件;

conf.addResource(Student.hbm.xml);

conf.addClass(pdao.Student.class);

  1. SessionFactory:

SessionFactory由Configuration建立;

应用程序从Sessionfactory中获得Session实例;

通常情况下,一个数据库只有唯一一个SessionFactory,可在应用初始化时被创建

SessionFactory sf =
conf.buildSessionFactory();Hibernate允许应用程序使用多个数据库,并相应的创建多个sessionFactory实例。

Sessionfactory非常耗内存!它缓存了SQL语句和映射元数据。

  1. Session:

代表与数据库之间的一次操作,需要进行数据访问时,从连接池获得一个JDBC连接;

通过SessionFactory打开,在所有工作完成后,需要关闭;

HibernateSessionFactory把生产Session的过程进行优化,比较高效:

HibernateSessionFactory.getSession();

HibernateSessionFactory.closeSession();

主键生成策略:

assigned:用户定义

increment:自动递增(long,integer,short)

uuid.hex:利用uuid算法

identity:由数据库根据identity生成主键

native:系统自动选择相应算法生成主键

sequence:由数据库根据序列生成主键

hilo:根据Hibernate的hilo生成主键

复合主键:

改写po类:若表中有多个列组成主键,则为这几个列封装成一个类作为主键,并增加setter和getter方法,编写PO类,将主键对象作为属性之一。

Public class StudentPK implements java.io.Serializable{

Private
String stuno;

Private
String stuname;

Public
String getStuno(){return stuno;}

Public
string getStuname(){return stuname;}

Public
void setStuno(){this.stuno=stuno;}

Public
void setStuname(this.stuname=stuname;)

}

Public
class Student{

Private StudentPK spk;

Private
String stusex;

Public StudentPK getSpk(){

Return
spk;

}

Public void setStudentPK(){

this.spk=spk;

}

Public String getStusex(){

Return
stusex;

}

Public
void setStusex(){

this.sex=sex;

}

}

在映射文件中进行配置:将主键类中的每个属性和表中的列对应,并制定复合主键的类型

<hibernate-mapping>

       <class name="po.Student"
table="T_STUDENT">

         <composite-id
name="spk" class="po.StudentPK">

                <key-property name="stuno"

                                     
column="STUNO"></key-property>

                <key-property
name="stuname"

                                       column="STUNAME"></key-property>

         </composite-id>             

         <property
name="stusex"  
column="STUSEX"/>   

       </class>

</hibernate-mapping>

使用复合主键操作数据库:

查询主键为【001 张三】的学生的性别

Session
session = util.HibernateSessionFactory.getSession();

StudentPK
spk = new StudentPK();

spk.setStuno(“001”);

spk.setStuname(“张三”);

Student
stu = (Student)session.get(Student.class,spk);

If(stu!=null){

System.out.println(stu.getStusex());

}

util.HibernateSessionFactory.closeSession();

HQL查询步骤:

  1. Query
    Session.createQuery(String queryString),该方法为HQL查询语句生成一个Query类的对象。
  2. 返回的Query中,有list()方法,返回一个List对象,通过遍历这个List对象得到查询的内容

查询语句:from 类名 as 对象名[where属性条件]

Session
session=util.HibernateSessionFactory.getSession();

String
hql=”from Student where stusex=’女’”;

Query
query=session.createQuery(hql);

List
list=query.list();

for(int
i=0;i<list.size();i++){

Student
stu=(Student)list.get(i);

System.out.println(stu.getStuname());

}

Util.HibernateSessionFactory.closeSession();

其他hql写法:

Select 属性 from 类名 as对象名[where 属性条件],

select
stuno,stuname from Student where stusex=’女’ ;这样的话,查询之后得到的结果集就要用Object来表示了。

For(int
i=0;i<list.size();i++){

Object[]
objs=(Object[])list.get(i);

System.out.println(objs[0]+””+objs[1]);

}

带参数的hql写法:

String
sex=”female”;

String
hql=”select stuno,stuname from Student where stusex=:sex”;

Query
query=session.createQuery(hql);

query.setString(“sex”,sex);

关联关系映射:

单向关联:多对一

Person和Country

Public
class Person{private Integer id;private String name; private Country country;}

Public
Class Country{private Integer id; private String name;}

Person表

ID

Name

CountryID

Country表

ID

name

Person.hbm.xml:

<hibernate-mapping>

<class name=”po.Person” table=”person”
catalog=”test”>

<id name=”id” column=”ID”><generator
class=”native” /></id>

<property name=”name” column=”Name”/>

<many-to-one
name=”country” column=”CountryID” class=”po.Country” cascade=”all”/>

</class>

</hibernate-mapping>

Country.hbm.xml:

<hibernate-mapping>

<class name=”po.Country” table=”country”
catalog=”test”>

<id name=”id” column=”ID”><generator
class=”native” /></id>

<property name=”name” column=”name”/>

</class>

</hibernate-mapping>

单向关联一对一:

Person与PersonAddress

Public
class Person{private Integer id;private String name; private PersonAddress
address;}

Public
class PersonAddress{private Integer id;private String city;
private String street;}

Person表

ID

Name

AddressID

PersonAddress表

ID

city

street

Person.hbm.xml:

<hibernate-mapping>

<class
name=”po.Person” table=”person” catalog=”test”>

<id
name=”id” column=”ID”><generator class=”native”/></id>

<property
name=”name” column=”Name”/>

<many-to-one
name=”address” column=”AddressID” class=”po.Country” unique=”true”></many-to-one>

</class>

</hibernate-mapping>

PersonAddress.hbm.xml:

<hibernate-mapping>

<class name=”po.PersonAddress” table=”personaddress”
catalog=”test”>

<id name=”id” column=”ID”><generator
class=”native” /></id>

<property name=”name” column=”name”/>

<property name=”street” column=”street”/>

</class>

</hibernate-mapping>

单向关联一对多:

Person与Phone

Public
class Person{private Integer id;private String name; private Set phones=new
HashSet(0);}

Public
class Phone{private Integer id;private String number; }

Person表

ID

Name

Phone表

ID

number

personid

Person.hbm.xml

<hibernate-mapping>

<class
name=”po.Person” table=”person” catalog=”test”>

<id
name=”id” column=”ID”><generator class=”native”/></id>

<property
name=”name” column=”Name”/>

<set name=”phones” cascade=”all” lazy=”false”>

<key column=”personid”/>

<one-to-many class=”po.Phone”/>

</set>

</class>

<hibernate-mapping>

Phone.hbm.xml:

<hibernate-mapping>

<class name=”po.Phone” table=”phone”
catalog=”test”>

<id name=”id” column=”ID”><generator
class=”native” /></id>

<property name=”number” column=”number”/>

</class>

</hibernate-mapping>

单向关联多对多:
Person和Flight:

Public class
Person{private Integer id;private String name; private Set flights=new
HashSet(0);}

Public
class Flight{private Integer id;private String name; }

Person表

ID

Name

Flight表

ID

name

Person-flight表

personID

flightID

Person.hbm.xml

<hibernate-mapping>

<class
name=”po.Person” table=”person” catalog=”test”>

<id
name=”id” column=”ID”><generator class=”native”/></id>

<property
name=”name” column=”Name”/>

<set name=”flights” table=”person_flight”>

<key column=”personID”/>

<many-to-many column=”flightID” class=”po.Flight”/>

</set>

</class>

<hibernate-mapping>

Flight.hbm.xml:

<hibernate-mapping>

<class name=”po.Flight” table=”Flight”
catalog=”test”>

<id name=”id” column=”ID”><generator
class=”native” /></id>

<property name=”name” column=”name”/>

</class>

</hibernate-mapping>

双向关联一对多/多对一:

Person和Department:
Public class Person{private Integer id;private
String name; private Department department;}

Public
class Department{private Integer id;private String
number; private Set staffs=new HashSet(0);}

Person表

ID

Name

departmentID

Department表

ID

name

Person.hbm.xml:

<hibernate-mapping>

<class
name=”po.Person” table=”person” catalog=”test”>

<id
name=”id” column=”ID”><generator class=”native”/></id>

<property
name=”name” column=”Name”/>

<many-to-one name=”department” class=”po.Department”
column=”departmentID”></many-to-one>

</class>

<hibernate-mapping>

Department.hbm.xml:

<hibernate-mapping>

<class
name=”po.Department” table=”Department” catalog=”test”>

<id
name=”id” column=”ID”><generator class=”native”/></id>

<property
name=”name” column=”Name”/>

<set name=”staffs” >

<key column=”departmentID”/><one-to-many class=”po.Person”/>

</set>

</class>

<hibernate-mapping>

双向关联一对一:
Person与IDCard:

Public
class Person{private Integer id;private String name; private IDCard cardID;}

Public
class IDCard{private Integer id;private String memo; private Person person;}

Person表

ID

Name

IDCard表

ID

name

personID

Person.hbm.xml:

<hibernate-mapping>

<class
name=”po.Person” table=”person” catalog=”test”>

<id
name=”id” column=”ID”><generator class=”native”/></id>

<property
name=”name” column=”Name”/>

<one-to-one name=”cardID” class=”po.IDCard” cascade=”all”/>

</class>

<hibernate-mapping>

IDCard.hbm.xml:

<hibernate-mapping>

<class
name=”po.IDCard” table=”idcard” catalog=”test”>

<id
name=”id” column=”ID”><generator class=”native”/></id>

<property
name=”memo” column=”memo”/>

<many-to-one name=”person”class=”po.Person” unique=”true”><column
name=”personid”/>

</many-to-one>

</class>

<hibernate-mapping>

双向关联多对多:

Student和Teacher:
Public class Student{private Integer id;private
String name; private Set teachers= new HashSet(0);}

Public
class Teacher{private Integer id;private String name; private Set
students=new HashSet(0);}

Person表

ID

Name

Teacher表

ID

Name

Student_teacher

studentID

taecherID

Person.hbm.xml:

<hibernate-mapping>

   
<class name="po.Student" table="student"
catalog="test">

       
<id name="id" type="java.lang.Integer">

            <column name="ID"
/>

            <generator
class="native"></generator>

       
</id>

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

            <column name="name"
length="45" not-null="true" />

       
</property>

      
 <set name="teachers"
table="teacher_student">

            <key column="studentid"/>

           
<many-to-many 
column="teacherid"  
class="po.Teacher"/>

        </set>

   
</class>

</hibernate-mapping>

Teacher.hbm.xml:

<hibernate-mapping>

   
<class name="po.Teacher" table="teacher"
catalog="test">

       
<id name="id" type="java.lang.Integer">

            <column name="ID"
/>

            <generator
class="native"></generator>

       
</id>

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

            <column name="Name"
length="45" not-null="true" />

       
</property>

       
<set
name="students" table="teacher_student">

            <key
column="teacherid"/>

           
<many-to-many 
column="studentid"  
class="po.Student"/>

        </set>

   
</class>

</hibernate-mapping>

Spring:

Spring的核心是个轻量级(Lightweight)容器(Container),实现了IoC(Inversion of Control)模式的容器,基于此核心容器所构建的应用程序,可以达到组件的松散耦合,使得整个应用程序可以在架构上与维护上都能得到相当程度的简化

Spring IoC:依赖倒转原则,其核心是将具体类之间的依赖,转化成抽象类依赖。即类Person应依赖抽象类ICar而不是Car。

Public Person{
         ...
         public void drive(){
                 Car toyota=new Car(\"TOYOTA\");
                 toyota.
挂档;
                 toyota.
踩油门;
                 toyota.
打方向;
         }       
}

导致了对象boy需要负责对象toyota的创建,甚至是整个生命周期的管理,耦合度高,不易维护。
若男孩换车,驾驶Audi,则要修改代码

实例:

applicationContext.xml为spring bean配置文件

Action接口:定义了一个execute方法,不同的Action实现提供了各自的execute方法

public interface Action {

         public
String execute(String str);

}

Action接口的两个实现:UpperAction

Public class UpperAction implemets
Action{

Private String message;

Public String getMessage(){return
message;}

Public void setMessage(String
message){this.message=message;}

Public String execute(String
str){return (getMessage()+str).toUpperCase();}

}

Spring配置文件applicationContext.xml:

<beans>

      
<description>Spring Quick Start</description>

      
<bean id="TheAction"

                  class="com.UpperAction">

         <property
name="message">

                 <value>HELLO</value>

         </property>

      
</bean>

</beans>

测试代码:

Public void testQuickStart(){

ApplicationContext ctx = new
ClassPathXMLApplicationContext(“applicationContext.xml”);

Action action=(Action)ctx.getBean(“TheAction”);

System.out.println(action.execute(“Rod
Johnson”));

}

输出结果:HELLO Rod Johnson

总结:

  1. 除测试代码之外所有程序代码中,并没有出现Spring中的任何组件
  2. UpperAction的Message属性由Spring通过配置文件动态设置
  3. 客户代码(这里的测试代码面向接口编程,无需知道类的具体名称)

依赖注入:由容器动态地将某种依赖关系注入到组件之中

  1. 接口注入
  2. 设值注入
  3. 构造方法注入

接口注入:将调用者与实现者分离

Public class ClassA{

Private InterfaceB clzB;

Public doSomething(){

Object
obj=Class.forName(Config.BImplementation).newInstance();

clzB=(InterfaceB)obj;

clzB.doIt();

}

}

设值注入:

Public class ClassA{

Private InterfaceB clzB;

Public void setClzB(InterfaceB clzB){this.clzB=clzB;}

Public InterfaceB
getInterfaceB(){return clzB;}

}

举例子:

Public Person{

Private ICar car;

Public Person(){}

Public void setCar(Icar
onecar){car=onecar;}

Public ICar getCar(){return car;}

Public void drive(){car.挂档;car.踩油门;,,,}

}

调用:

Toyota Toyota = new Toyato();

Person boy = new Person();

Boy.setCar(toyota);

Boy.drive();

Public interface ICar{void 挂档();void 踩油门();}

Public Class Toyato implements
ICar{public void 挂档();public void 踩油门();}

Public Class Audi implements
ICar{public void 挂档();public void 踩油门();}

Public class Factory{

Public final String TOYOTA = “toyota”;

Public final String Audi = “audi”;

Public ICar getCar(String craname){

If(carnema.equals(TOYOTA)) return new
Toyota();

Else if(carname.equals(AUDI)) return
new Audi();

Else throws new
IllegalAroumentException(“车名错误”);

}

}

Public class Test{

Public static void main(String
args[]){

Person boy = new Person();

ICar car=new
Factory().getCar(Factory.TOYOTA);

Boy.setCar(car);

Boy.drive();

ICar car=new
Factory().getCar(Factory.Audi);

Boy.setCar(car);

Boy.setCar(car);

Boy.drive();

}

}

<!bean.xml>

<beans>

<bean id=”Toyota” class=”***.Toyota”/>

<bean id=”Audi” class=”***.Audi”/>

</beans>

Public class Test{

Public static void main(String
args[]){

Person boy = new Person();

ApplicationContext ctx=new
FIleSysytemXmlAplicationContext(“bean.xml”);

ICar car=(ICar)ctx.getBean(“Toyota”);

Boy.setCar(car);

Boy.drive();

}

构造方法注入:

public class ClassA {
  private InterfaceB clzB;
  public ClassA(InterfaceB clzB) {  this.clzB=clzB   }

  ……
}

配置文件的读取方式

  • FileSystemXmlApplicationContext
    • 配置文件必须位于项目根目录中,即与src平级
    • ApplicationContext ctx =

new FileSystemXmlApplicationContext("bean.xml");

  • ClassPathXmlApplicationContext
  • 配置文件在classpath中,即在src目录下
  • 在Web应用程序的文档结构中读取
  • XmlWebApplicationContext

SSH整合:

  1. 导入structs2:

项目右键——myeclipse——add structs capability——structs2.1——/*——Structs2 core Libraries和Structs 2 Spring Libraries(如果后面要添加spring的,这个包一定要导入进去,否则会报一个错误:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener。如果后面不要添加spring的,这个包不要导入)。——finished

  1. 导入spring:

项目右键——myeclipse——add spring capability——Spring 3.0 core Libraries和Spring3.0 web Libraries——enable AOP
Builder,applicationContext.xml放在web-inf目录下——finished。

在web.xml中添加:

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>