用Hibernate+Struts2实现一个简单的用户登录界面,记录学习轨迹,练习框架简单配置。当然MyEclipse可以使用工具配置框架环境,但是在学习阶段,还是纯手动操作的好。
一、环境介绍
- ubuntu
- MyEclipse10
- jdk1.7
- Hibernate3.2更换为hibernate4.3
- Struts2.3
- MySQL
- Tomcat7
二、Hibernate配置篇
1.所需jar包(本次操作必要的,具体jar包根据Hibernate版本而定,数据库驱动包根据DB类型而定)----这个是hibernate3.2版本最小配置所需jar包,后面出错,更换为hibernate4.3版本的
2.hibernate.cfg.xml配置(可以使用MyEclipse的DBbrowser插件连接好数据库后,工程右键-MyEclipse-add Hibernate Capallites)
需要注意的是:hibernate.cfg.xml文件名不能更改,在IDE中必须在src目录下
具体配置如下:有详细注释,最下方的<mapping resourse=""/>为配置属性文件(*.hbm.xml)的注册信息,后面介绍
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!--1. 配置数据库连接相关信息 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property><!--数据库驱动--> <property name="connection.url">jdbc:mysql://localhost:3306/ssh</property><!--url--> <property name="connection.username">root</property><!--用户名--> <property name="connection.password">k42jc</property><!--密码--> <!-- 2.hibernate自身配置相关信息 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property><!-- 使用哪种数据库,这里使用Mysql --> <property name="show_sql">true</property><!-- 是否显示sql语句 --> <property name="format_sql">true</property><!-- 以格式化语句显示 --> <!-- 3.配置注册文件信息 --> <!--以下是Hibernate的三种映射关系(上课期间配的):一对一 一对多 多对多 个人感觉是Hibernate作为数据持久化框架的灵魂所在--> <!--这里实现简单的登录只需要用到一张数据库表,这个就没必要使用到了--> <!-- <mapping resource="one2one_sharePK/o2o_sharePK.hbm.xml"/> <mapping resource="one2one_uniqueFK/o2o_uniqueFK.hbm.xml"/> <mapping resource="one2many_twoWay/o2m_twoWay.hbm.xml"/> <mapping resource="one2many_oneWay/o2m_oneWay.hbm.xml"/> <mapping resource="many2many/m2m.hbm.xml"/> <mapping resource="hql/hql.hbm.xml"/> --> <mapping resource="entity/user.hbm.xml"/> </session-factory> </hibernate-configuration>
3.创建数据库表(database为ssh)
CREATE TABLE user( id INT PRIMARY KEY auto_increment, username VARCHAR(20), password VARCHAR(20) ); INSERT INTO user(username,password) VALUES( 'admin','654321' ); INSERT INTO user(username,password) VALUES( 'normal','123456' );
4.javaBean实体
package entity; public class User { private int id; private String username; private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
5.*.hbm.xml文件配置
此配置文件位置任意,在hibernate,cfg.xml文件的mapping标签中指定所在路径即可,本例中放在entity包下
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="entity"> <class name="User" table="user"> <id name="id" column="id" type="int"> <generator class="native"></generator> </id> <property name="username" column="username" type="java.lang.String"></property> <property name="password" column="password" type="java.lang.String"></property> </class> </hibernate-mapping>
指定包名、类名、属性名,充分体现面向对象思想,除了id(主键)稍微有点特殊(特别是三种映射关系的时候),native表示根据数据库方言来自动确定主键增长方式,很常用。另外还要注意数据类型,int型可以直接写基本类型(不知道之下的行否),其它的得写完整报名加类型,建议都写为java包装类
6.Hibernate工具类
用于获取Session对象,跟自动配置Hibernate环境生成的HibernateSessionFactory.java效果一致。
package util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static Configuration cfg=null; private static SessionFactory sf=null; private static ThreadLocal<Session> local=new ThreadLocal<Session>(); private static Session session=local.get(); //静态代码块保证对象创建并且只创建一次 static{ cfg=new Configuration(); sf=cfg.configure().buildSessionFactory(); } //保证获取到的session是当前线程内的 public static Session getCurrentSession(){ if(session==null){ local.set(sf.openSession()); } session=local.get(); return session; } //关闭session public static void closeCurrentSession(){ if(session!=null){ session.close(); } } }
7.测试一下
package test; import org.hibernate.Session; import org.hibernate.Transaction; import entity.User; import util.HibernateUtil; public class Test { public static void main(String[] args) { Session session=null; Transaction ta=null; try{ session=HibernateUtil.getCurrentSession(); ta=session.beginTransaction(); User user=(User)session.get(User.class, 1); System.out.println(user.getUsername()); }catch(Exception e){ if(ta!=null) ta.rollback(); e.printStackTrace(); }finally{ HibernateUtil.closeCurrentSession(); } } }
可以通过session的get/load/createQuery/createSQLQuery获得数据库对象,每种方式适用不同,这里测试只用get方法。另外,简单查询不涉及Tansaction事务。
很好!出异常了:java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(Z)V 因为我把Struts2的jar包和Hibernate要用的jar包一起导如的,导致jar包冲突,百度一下,出错原因是Hibernate3.2的cglib 包和与Struts2的asm包冲突,我之前下载了hibernate官网最新版本4.3.5,将原来的jar包清除,换上4.3.5lib目录request下的jar包导入,便没问题了,貌似新版本的优化更好,jar包少了
运行结果:
能查询出来,测试通过
三、Struts2配置篇
1、所需jar包----最小配置所必须使用的,即从Struts2原代码下解压出来的Strust2-blank工程下的jar包
2、写个简单的jsp登录界面与登录成功页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>登录界面</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <s:form action="/login" method="post"> <s:label value="系统登录"/> <s:textfield name="username" label="帐号"/> <s:password name="password" label="密码"/> <s:submit value="登录"/> </s:form> </body> </html>
跟以前jsp+Servlet主要的不同就是使用Struts2标签库,感觉方便很多,上述代码红色部分,因为是在网上学习配置的,代码为借鉴的
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>登录成功界面</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <label>欢迎${username}</label> </body> </html>
3、编写LoginAction类,用与登录业务处理
package action; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport{ private static final long serialVersionUID = 7922979648150320921L; private String username; private String password; /** * get/set方法 */ public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /**重写execute方法*/ @Override public String execute() throws Exception { //当用户输入匹配时,则返回SUCCESS表示登录成功(后续配置) if("admin".equals(username)&&"123456".equals(password)) return SUCCESS; //否则返回LOGIN,表示继续登录操作 return LOGIN; } }
代码中都有详细注解
5、配置struts.xml----关系到xml配置文件的,因为dtd感觉也没必要死记,将源代码中现有的拷贝过来,留下头文件即可
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="default" namespace="/" extends="struts-default"> <action name="login" class="action.LoginAction" method="execute"> <result name="success">/welcome.jsp</result> <result name="login">/login.jsp</result> </action> </package> </struts>
分别指定登录操作成功与否跳转页面
6、配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>Struts2</display-name> <!-- 1.配置工程struts2可用(以过滤器为入口) --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <!-- 需要注意的东东:这个文件里,配置的过滤器的类是:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter。 和原来配置的类不一样。原来配置的类是:org.apache.struts2.dispatcher.FileDispatcher。 这是因为,从struts-2.1.3以后,org.apache.struts2.dispatcher.FileDispatcher值被标注为过时。 虽然仍然起作用,但是不建议使用。 --> </filter> <!-- 2.配置所有请求全都经过struts2处理 --> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 将浏览器发来的所有请求,交给名为"struts2"的过滤器处理, 该过滤器是由org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter类实现的, 这样即实现了Struts 2框架全面接管Web请求的环境。 --> </web-app>
有详细注解,就不解释了,刚开始都是参照学习,大体了解什么意思就行7、测试一下
将web工程部署到tomcat服务器---这个就不介绍了---开启tomcat,在浏览器输入:http://localhost:8080/struts2/login.jsp
登录成功界面
测试通过,表示配置没问题
接下来就将Struts2所用到的用户名密码换成数据库数据,并由Hibernate操作
四、Struts2配合Hibernate部署及配置
需要注意的是:防止可能出现的jar包冲突,其它的尚未发现问题,能正常实现。上面已经说了,也copy下来一份
Hibernate3.2的cglib 包和与Struts2的asm包冲突,我之前下载了hibernate官网最新版本4.3.5,将原来的jar包清除,换上4.3.5lib目录request下的jar包导入,便没问题了