当前位置:文档之家› struts+spring+hibernate整合笔记

struts+spring+hibernate整合笔记

struts+spring+hibernate整合笔记
struts+spring+hibernate整合笔记

-------------------------------------1----------------------------------

MVC:Model(JavaBean),View(JSP),Controller(Servlet)

Servlet中跳转到另一个JSP,并且将参数保存在request中,写在doPost中ServletContext application = this.getServletContext();

RequestDispatcher rd = application.getRequestDispatcher("/result.jsp");

rd.forward(request, response);

引入一个自定义类<%@ page import="po.Student"%>

或者:

//////////////有时出现错误,可能是局部对象作用范围的问题,参见Prj1_1里的

SQL模糊查询,LIKE的通配符"_"(一个字符),"%"(任意个字符),汉字是两个字符,所以使用__

eg:SELECT * FROM table WHERE name LIKE '%s%';包含s的所有结果

-------------------------------------2----------------------------------

Struts就是一个基于MVC模式的框架,只是一个编程规范,让大家的代码风格更统一

在Struts中:

1.JSP表单内容首先提交给ActionServlet,ActionServlet将信息打包在ActionFrom中,送给Action(ActionServlet是Struts自带的)

2.ActionServlet不直接处理业务逻辑,让Action来调用JavaBean

3.Action负责决定跳转到另一个JSP,并显示结果(只是决定跳转,但动作还是由底层的ActionServlet做的)

4.配置文件(负责JSP->ActionForm,ActionForm->Action的映射)

需要编写:JSP,ActionForm,Action,配置文件(xml文件,struts-config.xml),JavaBean

////////////首先必须导入Struts支持包,并更爱base package for new calsses

////////////ActionFrom容纳表单提交的值

1。必须继承org.apache.struts.action.ActionForm

2。必须编写和表单元素同名的的属性

3。必须在Struts配置文件中进行注册(让Struts框架认识这个ActionFrom)

////////////Action负责接收ActionFrom传来的数据

1。必须继承org.apache.struts.action.Action;

2。重写execute函数,来处理业务逻辑

3。将这个类在配置文件中进行注册

public ActionForward execute(ActionMapping mapping, ActionForm form, HTTPServletRequest request, HTTPServletResponse response) throws Exception{

//ActionForward:封装了跳转目标的路径

//mapping:访问配置文件

//form:传过来的ActionFrom对象

//跳转部分写法如下,变量可以保存在request里面,因为ActionForward默认的不是进行重定向跳转,而是进行forward跳转,所以不会丢失

ActionForward af = new ActionForward("/queryResult.jsp");

return af;

}

////////注册

运行流程总结:客户端JSP提交到ActionForm,ActionFrom根据客户端JSP里的action,去掉".do"后,获得/query --> 在xml中的mapping中查找到/query --> 取得name里的queryForm --> 将提交的内容送给queryForm --> 又根据mapping 中的type获得Action的地址,将ActionForm中打包的内容送给Action

///////可以将所要跳转的地址设置成为逻辑名称

在action中跳转代码则变成:ActionForward af = mapping.findForward("RESULT");

-------------------------------------3----------------------------------

//////////自己建立配置文件的映射关系只需要在config文件的图形界面中右击new->form action and jsp

Struts框架包括自定义标签库,它可以用在很多方面.尽管这些库并不要求用框架,但是使用他们会有助于程序的开发.

struts-html taglib : 包含用来生成动态html用户界面和窗体的tag

struts-bean taglib : 包含在访问bean和bean的属性时使用的tag,也包含一些消息显示的tag

struts-logic taglib : 包含的tag用来管理根据条件生成输出文件,和其他一些用来控制的信息

tld文件是标签库定义文件(tag library definition)

/////////////////html标签库

其中的//action的内容不同于传统的form,传统的需要写成"/Prj3_1/reg.do",这里只需要写成"/reg.do",其中的"/"相当于项目的根目录,而且可以不写".do"

//需要在ActionForm中定义同名的property,并设置set,get函数.如果设置了value的话则不需要,因为:

在Struts标签中如果没有手动设置property的value值,则系统会自动调用ActionForm的getter函数获取初始值,不过最好还是定义一下

文本框:

密码框:

多行文本框:

隐藏表单:

单选按钮:男//默认选择的话需要在ActionFrom中设置,

private String sex = "boy";

下拉菜单:

显示的值

成组多选按钮://最好使用multibox

唱歌

跳舞

在ActionForm中需要定义一个数组来存储多选按钮的值:private String[] fav;//不能设置初值,有问题,要使用可以设置初值的则选用

唱歌

跳舞

设置初始值,private String[] fav = {"初始值1","初始值2"};

单个复选按钮:

是否会员?//返回的是boolean值

ActionForm中定义如下:private boolean inteam = true;//但是此方法会出现inteam的值不可以更改,可在reset函数(每次提交都执行一次)

中设置如下:inteam = false;

多选下拉列表框://multiple属性设置了可以进行多选,size表示显示的时候是显示几个.

ActionForm中定义如下:private String[] books = {"sanguo","hongloumeng"};//可以跳着多选,并不需要顺序对应

-------------------------------------4----------------------------------

html标签库:生成链接

1。//需要使用'/'符号,否则出错

2。

3。//需要在配置文件中的内进行注册

4。//适合链接同时还做一些操作的情况,如退出操作

链接的同时传递参数

1。//参数param保存在request中

2。<% session.setAttribute("msg","1"); request.setAttribute("msg","2"); application.setAttribute("msg","3");%>

//系统找到2

//系统自动从page--->request--->session--->application中寻找参数paramName 对应的参数

其他情况:在一个类中的属性作为参数

<% Student stu = new Student(); stu.setStuId("0001"); session.setAttribute("stu", stu);%>

//传递stu的stuId属性

其他情况:传递多个参数,可将多个参数放到HaspMap中

<% HashMap hm = new HashMap(); hm.put("param1","msg1"); hm.put("param2","msg2"); session.setAttribute("hm",hm);%>

/////////////////bean标签,访问http信息,name是从别处的来的,id是自己的

1。得到参数值并放入变量,Id:将参数给一个变量名,Name:参数名.相当于request.getParameter();

//将名字为param的变量值传递给str,相当于String str = request.getParameter("param");

2。相当于out.print,可以显示javabean内容,Name:显示某个变量的值,也可以显示javaBean内的属性:如果内容中有标签,如:hello,此标签默认不会识别标签,显示的时候就是原样显示.filter属性设置成false就可以使得所要显示的内容不要以原样显示.filter="false",显示成粗体hello.而out.print则不是以原样显示,显示成粗体hello

打印上面的内容:

3。得到cookie并放入变量.Id:将参数给一变量名,Name:cookie 名,value:默认值,相当于request.getCookie();然后for循环查找cookie.只有读cookie标签,没有写cookie标签,这样符合MVC设计模式

<% request.addCookie(new Cookie("username","cst"));%>

//显示cookie1对象的属性value

/////////////////logic标记,比较运算,相当于if语句

1。:相等时返回true;name和value:看变量是否等于value;cookie 和value:看cookie是否等于value;parameter和value;name,property和value.eg:ok看st是否值为1,是则显示ok

2。:不等返回true

3。:>=

4。:<=

5。:>

6。:<

7。:存在性判断,判断角色是否存在.Cookie:cookie是否存在.Parameter:请求参数是否存在.name和property:javabean的属性是否存在,判断page->request->session->application内是否有一个名为stu的javabean:

8。:判断某个角色是否不存在,相当于if(XXX!=null)

9。遍历集合.Id和Name:遍历过程中将某集合取名为Id,此集合可以是JavaBean.Length:要遍历的数目,默认是遍历所有的.Offset:从哪一个开始,设置name和property:某个JavaBean的属性是集合的情况.相当于获取集合内容加上for循环

eg1:简单集合(包括数组)的遍历

ArrayList list = new ArrayList(); list.add("三国"); list.add("水浒"); list.add("西游");session.setAttribute("list",list);

//id代表了所要遍历集合的单个元素

eg2:集合里面还有JavaBean的情况

ArrayList stus = new ArrayList();

Student stu1 = new Student(); stu1.setStuId("0001"); stus.add(stu1);

Student stu2 = new Student(); stu2.setStuId("0002"); stus.add(stu2);

Student stu3 = new Student(); stu3.setStuId("0003"); stus.add(stu3);

session.setAttribute("stus", stus);

eg3:JavaBean里面含有集合属性的情况,假设Student里有熟悉private ArrayList phones;

Student stu = new Student(); ArrayList phones = new ArrayList();

phones.add("1213123"); phones.add("23423423"); stu.setPhones(phones); session.setAttribute("stu",stu);

eg4:复杂集合,以HashMap为例

HashMap hm = new HashMap();

hm.put("param1","msg1"); hm.put("param2","msg2"); hm.put("param3","msg3"); sessiong.setAttribute("paramList",hm);

//显示HaspMap中的key 值

//显示HaspMap中的value值

-------------------------------------5----------------------------------

实际案例中分析时,看有几个动作,理论上有几个动作就需要几个Action,然后根据动作判断是否需要ActionForm

产生随机数:Random rnd = new Random(); int rndNumber = rnd.nextInt();

通过request获得session:HttpSession session = request.getSession();

如果使用标签遍历的是集合,则有一个序号标记,可以通过该标记传递集合里数据所在的序号:

注意,跳转时:,或者需要动用Action的跳转

-------------------------------------6----------------------------------

可以维护一个自定义标签,例如多个页面中有一个共同的菜单需要维护的时候,可以为这个菜单定义一个自定义标签

/////////////标签简介:

标签格式:<前缀:标签名属性="属性值"/>

空标签,没有体,也没有属性或者 空体标签,没有体,但是有属性或者

有体有属性标签:

/////////////如何开发空标签和空体标签

自定义标签的要素:

1。标签处理程序(一个java文件,已经被编译):使用不同的方法和对象来定义标签的行为,即认识某属性的不同值能做不同的事情

作用:包含类和方法的定义,定义标签的功能

对于空体标签,需要继承:javax.servlet.jsp.tagext.TagSupport

对于有体标签,需要继承:javax.servlet.jsp.tagext.BodyTagSupport

以上两类都需要实现接口:javax.servlet.jsp.tagext.Tag接口

所要重写的Tag接口中的方法如下:

doStartTag();一般的返回SKIP_BODY,让标签不要对体求值.初始化标签的一些内容,如连接数据库.有体标签则返回EV AL_BODY_TAG,对体求值

doEndTag();一般的返回EV Al_PAGE,让标签后的JSP继续执行.做一些善后工作,如关闭数据库.有体标签同样返回EV AL_PAGE,让后面的继续执行

release();释放这个标签对象

doAfterBody();完成标签体求值之后调用

doBeforeBody();开始标签体求值之前调用

对于标签里面的属性,类似于JavaBean里的属性,对他们设置get和set方法

最厉害的角色:pageContext保护成员,可以通过它获得JSP的内置对象,从而可以向页面输出一些内容.

2。标签库描述文件(TLD文件)(一个XML格式文件):包含客户标签的描述性列

表的XML文件,即识别不同的属性能做不同的事情

1.2

1.1

stu

stu

displayAll

tags.DisplayAllTag

displayBySex

tags.DisplayBySexTag

sex

true

true

3。JSP文件(为了嵌入自定义标签):包含标签以及表示内容的HTML代码

<%@ taglib uri="stu" prefix="自定义的前缀" %>

-------------------------------------7----------------------------------

资源文件(需要制定编码为gb2312):在Struts中生成的.properties文件,用于定义一些在多个页面中使用的信息或者资源

资源文件格式:key=value形式.eg:info.input.account=please input account :

调用:

可以使用资源文件,传参数来显示

# 可以使用参数{0}, (4)

info.input=please input {0} :

调用://输出显示please input account :

资源文件中还可以使用标签:info.input=please input {0} :

可以自己建立一个新的资源文件,然后在配置文件中进行注册:

调用://需要指定bundle

//////////////在资源文件中使用中文的话需要转码:native2ascii -encoding gb2312 源文件名,目标文件名

此命令在jdk的bin目录文件下eg:native2ascii -encoding gb2312 a.properties

b.properties

//////////////错误处理,两类错误:

1。前端错误,如输入为空,一般在ActionForm中实现

在ActionForm中实现:

////1.首先在配置文件中设置inputJSP,即在Acion标签中的input选项(当前端出现错误时所要跳转到的页面)中设置出错后所要到达的页面

////2.在ActionForm中的Validate方法(进行前端的错误验证)中做以下动作:定义ActionErrors;如果有错误,添加ActionMessage,并指定属性名称和资源文件key 值;返回ActionError(ActionErrors是错误集合,当内部有ActionError时则认定前端发生了错误)

eg:资源文件中定义错误:error.null={0} cannot be null

ActionForm中定义了:ActionMessage error = new ActionMessage("error.null","account");//第一个参数是资源文件中的key,后面的是参数,可以使用多个参数.errors.add("account(对此error加一个属性标记",error);

////3.在页面中写

2。业务逻辑错误,比如登陆不成功,一般在Action中实现

需要保存错误:this.saveErrors(request, errors);//推荐第二个参数是ActionMessages类型

return mapping.getInputForward();

-------------------------------------8----------------------------------

1。ActionForm高级应用之Scope(范围),在Action标签中定义:

当scope=request时,表示每次提交都会新生成一个ActionForm对象;而当scope=session时表示在一次会话中生成一个ActionForm对象,以后不再生成,而是在session中取得;当scope=session时一定要注意reset方法.(一般情况下表单的数据都是暂态的,所以放到request中

2。ActionForm高级应用之表单跨页:(scope需要设置成session)在选择建立Action时选择Type为forward(只进行跳转,同时能对内容进行打包,无use cases):,缺点是跳转回去后不能保存原来的值,可以设置value的值,让它可以恢复空值

3。ActionForm高级应用之利用索引属性的ActionForm(如电话号码有多个,可以使用数组属性,也可以使用索引属性)优点是跳转回去后能够保存原来的值,缺点是事先必须知道表单元素的个数(此缺点可以通过改成集合的方式来克服掉)

ActionFrom中定义如下:

private String[] phones = new String[3];

public String getPhone(int i){

return phones[i];

}

public void setPhone(int i, String phone){//i和phone的顺序不能变,因为那是规

this.phones[i] = phone;

}

使用集合的方法:缺点是失去了顺序,慎用

private ArrayList phones = new ArrayList();

public String getPhone(int i){

if(i < phones.getSize()){

return (String)phones.get(i);

} else return null;

}

public void setPhone(int i, String phone){

this.phones[i].add(phone);

}

-------------------------------------9----------------------------------

4。ActionForm高级应用之动态ActionForm(因为过多的额ActionForm让系统过于庞大.)解决如下://但是此方法会使得失去验证功能

////建立动态的ActionForm

建立ActionForm类的时候在Form Impl中选择Dynamic FormBean,可以避免代码的编写,系统自动在配置文件中注册如下

////使用DynaActionForm.get()方法使用动态ActionForm

DynaActionForm regForm = (DynaActionForm)form;

String account = regForm.get("account");

String password = regFOrm.get("passowrd");

////////////////前端验证:

1。ActionForm验证

2。使用Validate框架验证(核心思想:将验证的作用写在XML文件中,使许多判断的if语句相对集中在XML中了)

使用:首先必须有两个jar文件:Jakarta-oro.jar处理文本文件和commons-validator.jar提供验证功能;其次需要系统提供的文件

validator-rules.xml(此文件定义了我们项目中可能出现的所有要验证的规则,它是Struts自己定义的,以后只要在自己的XML文件中调用即可)

此xml文件中定义如下:包含了一些通用规则,一般不需要改变

////////////////步骤:

1。首先建立validator-rules.xml文件和validation.xml文件(此文件是自己写的,

可以命名其他名字)

2。将这两个文件作为插件存入Struts配置文件,在Struts配置文件中最后加上:(因为这两个文件都是struts所不认识的)

3。编写JSP,ActionForm,Action,注意此时ActionForm应该继承org.apache.struts.validator.ValidatorForm(静态的ActionForm);如果是动态的ActionForm则需要继承org.apache.struts.validator.DynaValidatorForm,然后就可以在validation.xml文件中写验证规则了

动态ActionForm中的type属性需要改成org.apache.struts.validator.DynaValidatorForm

validation.xml文件编写如下:

////////////高级内容之设定单个验证门限:如电话长度最少7位,

方法:在field中定义

规则名称

参数中可以使用所定义的var:

////////////设定多个验证门限:如果是对范围设定门限,则只要对min,max设定就可以了

////////////设定条件验证门限:在field中增加validatewhen,定义:

test

(前一个属性==*this*)

如果不适用框架,而是在ActionForm中做验证,而且是一些比较复杂的验证,推荐使用静态类https://www.doczj.com/doc/4d14966298.html,mons.validator.GenericValidator

-------------------------------------10----------------------------------

Po:持久化对象;Vo:值对象

??为何保存在session中的对象,在更新以后不需要再次将其添加到session中? -------------------------------------11----------------------------------

/////////////Action高级应用之DispatchAction(Action的子类,用于实现轻量级组件,可以在一个Action中实现多个操作),传统方法可以通过设置一个状态变量,通过状态变量不同的值来标示不同的操作.

实现步骤:(注意表单method=post)此方法可以降低耦合性,缺陷:JSP需要认识Action里的方法名,可以使用MappingDispatchAction解决

1。建立一个DispatchAction,并给定参数method,编写处理函数(可以继承DispatchAction来实现)

在配置文件中的action中需要添加parameter="自己给定名称,用来在调用action时指定用于处理的函数名称"

2。在JSP中使用action路径?method=方法名称的方式来提交

/////////////Action高级应用之MappingDispatchAction(降低耦合性,并且只编写一个Action而让他指向多个不同结构的ActionForm)

实现,需要在配置文件中写多个Action标签,其中的parameter需要改成所要调用的函数的名称

/////////////Action高级应用之LookupDispatchAction(处理一个表单具备两个不同的按钮,传统方法中可以对两个的按钮起不同的名字)

使用方法:(此方法降低了耦合性)

1。先建立ActionForm和相应的JSP,建立LookupDispatchAction,注意,按钮标签从资源文件中获得!

2。重写getKeyMethodMap函数,注意map.put(资源文件key,方法名);此方法即用一个map保存资源文件key和方法名的映射

Map map = new HashMap();

map.put("key1","函数名1");

map.put("key2","函数名2");

return map

3。编写方法

4。为Action建立参数

在配置文件中的action标签里添加parameter="名称随便",然后在提交按钮中需要设置:

5。将提交按钮property和参数名称一致

-------------------------------------12----------------------------------

一个页面中有多个栏位时,可以使用传统框架实现,也可以使用Tiles布局来实现1。传统方法:可以使用将页面共同部分做成小页面然后在整合页面中使用将所要使用的页面包含进来就可以了2。Struts中的标签:使用tiles标签库标签,

page="a.jsp"> (同)

3。使用Struts的Tiles模板功能:

定义一个模板:layout,在需要不同的方写: (相当于在页面中挖了一个空)

在页面中调用模板:

注意:整个页面是一个页面,不能进行局部跳转,如果非要实现在页面访问时先要访问数据库的话,可以先访问此Action,然后再让Action跳转到主页面中进行显示

-------------------------------------13----------------------------------

分页策略:1。内容全部查询出来以后再分页(查完再分).2。根据该页需要显示的内容进行分页(用多少查多少).选择:权衡查询难度和数据量

页数计算:if(总的条数%每页条数==0) 页数=总的条数/每页条数else 页数=总的条数/每页条数+1

第N页显示第几条记录(记录从0开始计算):(N-1)*每页条数=< 序号<= N*每页条数-1 或者(N-1)*每页条数=< 序号< N*每页条数

本质:传入一个比较大的集合,返回需要显示的页上记录

注意:如果一个参数是boolean类型的话,不要将其命名为isXXX,因为默认生成getter,setter函数的时候名称会有问题

遗留问题:为何存入request中的变量,在点击下一页,上一页后会消失掉,造成多次查询数据库~~~~!!

-------------------------------------14----------------------------------

文件上传:需要考虑的问题:文件编码,大小和分块.但在Struts中,一切都很容易,有一个upload包,专门负责这个工作

步骤:

1。如果表单中有文件要上传,表单的属性:

-enctype="multipart/form-data",这个属性告诉Struts,表单的数据将被编码并且具备多个部分(写在表单头中)

-

2。需要在ActionForm中定义一个同名属性,其类型是:org.apache.struts.upload.FormFile

此类有以下常用方法:getContentType(得到文件类型);getFileName(得到文件名称);getFileSize(得到文件大小)

如果不选择而提交,getFileName得到的是空字符串,getFileSize得到0.并且这个控件支持中文

////////////限制文件大小:在配置文件中设置

////////////保存文件在服务器端:(默认得是保存在bin目录下) FileOutputStream fos = null;//java.io.FileOutputStream

try{

byte[] data = file.getFileData();

String fileName = file.getFileName();

//有第二个参数,不写的话表示再次上传的时候进行覆盖,如果第二个参数写为:new FileOutputStream(fileName,"true").则在第二次上传的时//候进行添加,而不是进行覆盖

fos = new FileOutputStream(fileName);

fos.write(data);

}catch(Exception ex){ex.printStackTrace();}

finally{

try{fos.close();}

catch(Exception ex){ex.printStackTrace();}

}

/////////////更改文件上传路径:注意:java在访问服务器硬盘时,一定要提供逻辑路径(如c:\...),应用默认bin目录下

1。fos = new FileOutputStream("绝对路径" + fileName);//可以用,但一但服务器地址变了的话,更改起来比较麻烦

2。使用application

ServletContext application = this.getServlet().getServletContext();

String realPath = application.getRealPath("/FILES/");//其中FILES当前项目下的一个文件夹

fos = new FileOutputStream(realPath + "/" + fileName);

/////////////getInputStream()得到文件的输入流,返回InputStream.可以对文件进行分析

分析文件流:BufferReader br = new BufferReader(new InputStreamReader(is));//通过BufferReader来读取文件

/////////////上传多个文件:传统的数组方法已经不能使用了,建议使用ArrayList来保存

步骤:

1。将控件定义为索引(还不会!)

2。定义索引属性,可以用数组,也可以用ArrayList来存储

-------------------------------------15----------------------------------

//////////////多模块:对于庞大的系统,多个模块中的内容有相同部分,但却又细节不同,一个Struts-config.xml文件有缺陷,可以建立多个配置文件;另外如果是分工合作,在整合的时候可以使用一个模块将其他的模块进行整合,也用到了多模块: 1。建立单独的Struts配置文件

2。在W eb.xml中配置相应信息:

增加一个参数名称为config/模块名的参数,指明另一模块配置文件的路径.注意:模块名称和目录名称要一样

config/submodule(子模块名称)//调用的话:localhost:8001/Prj14_1/submodule/类名称

/WEB-INF/2.xml

如果是通过链接调用的话

或者

默认模块:或者

/////////另一种模块切换方法:在配置文件中配置如下:

调用:

//默认模块

//////////////插件开发:有些时候希望Struts在启动的时候做一些初始化工作:

1。传统方法:使用过滤器,系统启动自动调用init一次,以后每次提交调用doFilter 使用方法:

建立一个类,实现javax.servlet.Filter接口

在web.xml中进行注册:

filter1

filter.Filter1

filter1

/*

2。Struts插件方法:(只实现服务器启动时初始化,并不实现每次调用时进行提交,比过滤器少了doFilter函数)

////建立一个类,实现org.apache.struts.action.PlugIn接口

////编写方法,注意servlet参数,用处很大

////注册插件

注意:在配置文件中可以通过设置属性来影响插件行为

3。另一种扩展:让表单在处理之前做一些事情:传统方法使用过滤器,但是并不能访问Struts对象(只接受表单提交,且通过this可以访问Struts资源)

一个隐藏在后面的角色:RequestProcessor类,Struts运行时,提交到ActionServlet,底层实际上是调用RequestProcessor来完成工作的

////建立一个类,继承:org.apache.struts.action.RequestProcessor

////编写方法,注意重写方法processPreprocess,注意返回值(一般返回true,表示继续向下传递,而false表示到此为止)

////配置控制器:

-------------------------------------16----------------------------------

Hibernate思想:用一个类专门负责组织SQL,表名和列名在配置文件中注册,将表名对应到Customer类,列名对应到Customer类的属性,让数据库对DAO来说是

透明的.需要两个配置文件,分别负责数据库的链接,负责对象和关系表的映射(ORM)-------(可以自动组织SQL语句)

///////持久化层,O/R Mapping

基于B/S的典型三层架构:

展现层(Presention Layer) --->业务逻辑层(Buseness Layer) --->持久化层(Data Source Layer)

W ebW ork/Struts --(IoC)-->Spring

--(IoC)-->Hibernate

Action,FormBean,配置文件,模板页面--->IoC容器,AOP,Hibernate的支持,事务管理--->映射文件,Hibernate接口,DAO模式

///////Bean一般表示数据表中的一条记录,只是对记录的操作可以转换为对对象的操作,操作之后数据库的记录相应变化,必须提供对这些对象操作的函数,Bean能够通过函数对数据库实现增删改查.

Hibernate使用:(不需要服务器,可以建立java项目来实现)

1。建立数据库记录封装类po.Customer

2。写另一个配置文件:Customer.hbm.xml;//hbm代表的是hibernate Mapping

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"https://www.doczj.com/doc/4d14966298.html,/hibernate-mapping-3.0.dtd">

3。在hibernate配置文件中对建立的配置文件进行注册

4。实现增删改查(另外需要写一个类)

//////////添加一条记录

-读取Hibernate配置文件:

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

-Hibernate操作要由Session来完成,Session由SessionFactory来管理,所以要生成SessionFactory:

SessionFactory sf = conf.buildSessionFactory();

-打开Session(并非web里面的Session,而是Hibernate的Session,跟web里的Session完全不同):

Session session = sf.openSession();

-增删改查(注意Session的事务不是自动提交):

设置自动提交:Transaction tran = session.beginTransaction();

session.save(new Customer("1","1","1",1));//或者session.saveOrUpdate(new Customer("1","1","1",1));//有就更新,没有就添加

https://www.doczj.com/doc/4d14966298.html,mit();

///////////查询一条记录

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

SessionFactory sf = conf.buildSessionFactory();

Session session = sf.openSession();

Customer cus = new Customer();

session.load(cus,"主键值");//多于一条记录时会抛出异常

///////////修改一条记录

Transaction tran = session.beginTransaction();

session.update(cus);

https://www.doczj.com/doc/4d14966298.html,mit();

///////////删除一条记录

Transaction tran = session.beginTransaction();

session.delete(cus);

https://www.doczj.com/doc/4d14966298.html,mit();

-------------------------------------17----------------------------------

///////////org.hibernate.cfg.Configuration:(注意:这是一个瞬态对象,一旦SessionFactory建立,就丢弃,占据系统资源较少)

作用:负责管理Hibernate的配置信息(hibernate.cfg.xml),hibernate映射文件(*.hbm.xml)生成SessionFactory

使用方法:读取xml文件(hibernate.cfg.xml)

Configuration conf = new Configuration();然后调用它的configure()函数,默认读取hibernate.cfg.xml

configure()方法可以指定参数;

addResource(String path)可以指定hbm文件路径;(即可以不在hibernate.cfg.xml 中注册其他的配置文件,而是动态添加配置)

addClass(Class persistentClass)只指定类;

///////////org.hibernate.SessionFactory:

应用程序从SessionFactory中获得Session实例,通常情况下一个数据库只用一个SessionFactory,例如应用初始化时建立(消耗内存),网站中适合放在application 中

///////////org.hibernate.Session:(代表与数据库的一次操作)

Session通过SessionFactory打开,在完成操作之后,需要关闭;它与web中的HttpSession没有任何关系.(网站时适合保存在HttpSession中)

如何生存Session是一个麻烦问题,可以借助帮助类来进行优化(HibernateSessionFactory(名字不定非要这样)),则生成session的代码就变为: Session session = util.HibernateSessionFactory.getSession();//该类有方法getSession和closeSession

util.HibernateSessionFactory.closeSession();//关闭Session

///////////比较好的事务操作方法:(使用错误处理的方法)

try{

session.update(cus);

https://www.doczj.com/doc/4d14966298.html,mit();

} catch (Exception ex){ tran.rollBack();//回退}

finally{util.HibernateSessionFactory.closeSession();}

///////////简单增删改查:

增加:save(单纯的添加),saveOrUpdate(如果存在就更新,不存在就添加)

查询:load(找不到时抛出异常),Customer cus = (Customer)session.get(Customer.class,"主键值");//找不到时返回空,不抛出异常(常用)

///////////复杂增删改查:(批量查询之:HQL(Hibernate Query Language)

基本语法:

1。from 类名as 对象名(where 属性条件);

eg:from Customer where cbalance>1000;//或者from Customer as cus where cus.cbalance>1000(注意:用的是类的属性,而不是数据库表)

String hql = "from Customer where cbalance > 1000";

Query query = session.createQuery(hql);

List list = query.List();//查询,并返回一个list

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

Customer cus = (Customer)list.get(i);

}

2。select 内容from 类名as 对象名(where 属性条件)

eg:select cname,cbalance from Customer where cbalance > 1000;//只查询姓名和余额

String hqp = "select cname,cbalance from Customer where cbalance > 1000"; Query query = session.createQuery(hql);

List list= query.list();

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

Object[] obj = (Object[])list.get(i);//此时list里放置的不是对象,而是object 数组

}

3。使用参数":参数名"

double money = 1000.0;

String hql = "from Customer where cbalance > :money";

Query query = session.createQuery(hql);

query.setDouble("money",money);

///////////复杂增删改查:(批量查询之准则查询方法:org.hibernate.Criteria)

步骤:

1。Criteria cri = session.createCriteria(Class persistentClass),将Criteria绑定到JavaBean

2。Criteria.add(规则); Criteria.addOrder();//eg:cri.add(Restrictions.gt("cbalance",1000));//增加限制:cbalance>1000

3。规则由Restrictions类得到

4。用list方法得到结果

注意:这种方法也支持聚合,连接等操作,但使用得较少.可以进行排序:cri.addOrder(Order.asc("所要排序的列"));

注意Criteria的两个重要方法:

c.setFirstResult(i);//从第i条记录开始显示

c.setMaxResults(i);//最大显示的记录号

给分页带来了方便

///////////复杂增删改查:(批量查询之:SQL查询)(不太常用的方法)

步骤:

1。SQLQuery sq = session.createSQLQuery(String sql);

2。用SQLQuery.addEntity(Class class)方法来绑定对象

3。用list方法得到结果

注意:在使用查询的时候,如果遇到查询的结果无法放置到JavaBean中

注意:在实际项目实施当中,对数据库比较批量的操作应该写成存储过程

//调用存储过程:Session通过Connection绕道JDBC

java.sql.Connection conn = session.Connection();

conn.prepareCall(s);

-------------------------------------18----------------------------------

在IDE中导入数据库的驱动:在MyEclipse中的Hibernate窗口中建立一个数据库连接模板就可以了(注意JdbcOdbcDriver在rc.jar包中,不可见)

//////////复合主键的情况

1。编写一个类(实现序列化接口),封装主键,并写属性,原类则去掉主键属性,增加新建立的类属性,增加get,set函数

2。po内编写各个属性,包括主键类型

3。在映射文件中写明:

//////////主键生成策略:Generator:主键生成器,每个主键都必须定义相应的主键生成策略,它用来为持久化类实例生成唯一的标志.

Hibernate内置主键生成策略:

assigned:由用户手工给定一个值(例如账号由用户决定)

increment:不用手工给值,由系统自动递增(注意,这些只是Hibernate的策略)账号由系统返回.需要保证列是数字,而非字符串

identity:由数据库生成主键

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

hilo:根据hibernate特殊算法生成主键

native:系统自动选择identity,sequence,hilo

uuid.hex:hibernate利用uuid算法生成主键

//////////动态模型:不用编写po

更改配置文件:

在类中使用动态模型:

HashMap hm = new HashMap();

hm.put("account", account);

hm.put("password", password);

hm.put("cname", cname);

hm.put("cbalance", cbalance);

Transaction tran = session.beginTransaction();

session.save("Customer", hm);

https://www.doczj.com/doc/4d14966298.html,mit();

-------------------------------------19----------------------------------

Hibernate处理表间关联的情况:(注意表间关联时可能会出现查询出错的情况,需要更换驱动jdts,SQL Server 打补丁SP4)

1。1对1关联:(两个类在配置文件中的主键要相同)Hibernate与数据库的耦合性很低,此处的主键设置与真实的数据库主键并无关系

要在没有外码的类(主动类)中,建立一个外码po类(被动方)的对象.(看例子)

再在主动类中的配置文件中进行注册:

2。1对多关联:one-to-many

要在没有外码的类(主动类)中,建立Set类型属性,用于装入所有与之关联的外码po类(被动方)的对象

再在主动类中的配置文件中进行注册:

添加的时候使用HashSet来存储set数据,然后进行添加操作

所存在的问题:

////////当表中定义了主键外键关系的时候存在bug,必须还要配置多对一,配置多对一关联如下:

-在Student类(外码类,被动类)中添加BanJi(主动类)属性

-在Student.hbm.xml中添加注册

-在BanJi.hbm.xml中set标签内添加属性:inverse="true"(表示它是主动方)

3。多对多关联:many-to-many(最多的操作时查询,因为增删改的时候问题比较多)

在主动类和被动类中都必须添加set属性

两个hbm文件中配置如下:

-------------------------------------20----------------------------------

使用Struts+Hibernate编程的时候,前台交给Struts处理,后台则交给Hibernate 处理(只需要添加配置文件,更改DAO代码即可,使得系统更加灵活,更具有低耦合性特点,而且降低了后台DAO开发人员的工作量)

面向接口编程的思想:对于Struts中的Action,不需要知道后台DAO的变动,可以为后台DAO创建一个统一的接口,让DAO实现这个接口,那么就可以达到DAO 内函数统一的目的.同时在Action中使用DAO的时候,使用: DAO接口name = new DAO();//接口类对象指向子类DAO对象

进一步改进:DAO接口name = 工厂类.getDAO();

需要建立一个工厂类,用于返回一个DAO接口类型指针,但其实返回的是一个DAO对象,这样就可以达到Action完全不依赖后台DAO的情况.降低了系统的耦合性.

BO:Business Object业务对象,比较注重业务逻辑,将某个实体能够做到的动作集中到一起,位于Action和DAO之间

-------------------------------------21----------------------------------

控制反转和依赖注入是Spring的两个核心思想!

使用工厂的时候可以运用反射机制:

public class BeanFactory{//框架化,这就是最早的String结构,可以处理多个相同结构的切换

public static Object getBeanDao(String aName){//aName是Action中传来的别名

String className = 根据别名到类名;

return Class.forName(className).newInstance();

}

}

Action中调用

ICustomerDao dao = (ICustomerDao)getBeanDao(别名);

////////在Spring配置文件中注册别名

相关主题
文本预览
相关文档 最新文档