hibernate 结合servlet及 jsp 的使用

hibernate 结合servlet及 jsp 的使用

1、搭建Hibernate框架

搭建Hibernate框架,大家都不陌生,我这里也不再重复。新建一个项目ServletHibernate,把连接MySQL数据库的jar包、Hibernate所需的jar包和JSTL标签库的jar包拷贝到该工程的WebContent/WEB-INF/lib目录下. 

2、创建数据库文件

为了使例子简单易懂,创建数据库表时,表字段很少。本章的例子只需两张表,一张部门表和一张员工表。部门表的主键设置成自动增长。部门表和员工表是一对多的关系,所以在员工表中,部门表的主键作为员工表的外键,员工表的主键设置成自动增长。

-- ----------------------------

-- Table structure for `dept`

-- ----------------------------

DROP TABLE IF EXISTS `dept`;

CREATE TABLE `dept` (

  `depno` int(11) NOT NULL AUTO_INCREMENT,

  `depname` varchar(255) DEFAULT NULL,

  PRIMARY KEY (`depno`)

) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Table structure for `emp`

-- ----------------------------

DROP TABLE IF EXISTS `emp`;

CREATE TABLE `emp` (

  `empno` int(11) NOT NULL AUTO_INCREMENT,

  `empname` varchar(255) DEFAULT NULL,

  `password` varchar(255) DEFAULT NULL,

  `depno` int(11) DEFAULT NULL,

  PRIMARY KEY (`empno`),

  KEY `FK188C86CDD0E0B` (`depno`),

  CONSTRAINT `FK188C86CDD0E0B` FOREIGN KEY (`depno`) REFERENCES `dept` (`depno`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

 

3、编写映射文件创建实体类

部门表对应的实体:

public class Dept implements Serializable{

 

/**1

 * 

 */

private static final long serialVersionUID = 1L;

private Integer depno;

private String depname;

private Set emps = new HashSet(0);

public Dept() {

}

public Dept(Integer depno) {

this.depno = depno;

}

public Dept(Integer depno, String depname, Set emps) {

this.depno = depno;

this.depname = depname;

this.emps = emps;

}

 

public Integer getDepno() {

return depno;

}

 

public void setDepno(Integer depno) {

this.depno = depno;

}

 

public String getDepname() {

return depname;

}

 

public void setDepname(String depname) {

this.depname = depname;

}

 

public Set getEmps() {

return emps;

}

 

public void setEmps(Set emps) {

this.emps = emps;

}

 

@Override

public String toString() {

return "Dept [depno=" + depno + ", depname=" + depname + ", emps=" + emps + "]";

}

}

Dept类中有3个属性depnodepname对应数据库表的字段。Set集合对应的是一对多的多方,这里是员工实体类。Dept类的对应的映射文件和实体类在同一包下,代码如下:编写Hibernate配置文件

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

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

 <class name="com.nercl.model.Dept" table="dept" catalog="bank">

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

 <column name="depno" />

 <generator class="native" />

 </id>

 

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

  <column name="depname" />

 </property>

 

 <set name="emps" inverse="true">

 <key>

  <column name="depno" />

 </key>

  <one-to-many class="com.nercl.model.Emp" /><!-- 一对多关系映射 -->

 </set>

 </class>

</hibernate-mapping>

员工表对应的实体:

public class Emp implements Serializable{

 

/**

 * 

 */

private static final long serialVersionUID = 1L;

 

 

private Integer empno;

private Dept dept;//部门实体类对象

private String empname;

private String password;

public Emp() {

}

public Emp(Integer empno) {

this.empno = empno;

}

public Emp(Integer empno, Dept dept, String empname,String password) {

this.empno = empno;

this.dept = dept;

this.empname = empname;

this.password = password;

}

 

public Integer getEmpno() {

return empno;

}

 

public void setEmpno(Integer empno) {

this.empno = empno;

}

 

public Dept getDept() {

return dept;

}

 

public void setDept(Dept dept) {

this.dept = dept;

}

 

public String getEmpname() {

return empname;

}

 

public void setEmpname(String empname) {

this.empname = empname;

}

 

public String getPassword() {

return password;

}

 

public void setPassword(String password) {

this.password = password;

}

 

@Override

public String toString() {

return "Emp [empno=" + empno + ", dept=" + dept + ", empname=" + empname + ", password=" + password + "]";

}

}

Dept是员工表外键对应的属性,是一对多关系映射中的一方。Emp类对应的映射文件和实体类在同一包下,代码如下:

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

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

 <class name="com.nercl.model.Emp" table="emp" catalog="bank">

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

  <column name="empno" />

  <generator class="native" />

 </id>

<!-- 多对一的关系映射 -->

 <many-to-one name="dept" class="com.nercl.model.Dept" fetch="select">

  <column name="depno" />

 </many-to-one>

 

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

  <column name="empname" />

 </property>

 

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

  <column name="password" />

 </property>

 

 </class>

 

</hibernate-mapping>

4、编写Hibernate配置文件

文件名为hibernate.cfg.xml,在该文件中配置数据库连接和实体类映射文件,配置文件在src的跟目录下,代码如下:

<?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>

 <!-- 连接数据库的配置 -->

 <property name="current_session_context_class">thread</property>

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

 <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/bank</property>

 <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

 <property name="show_sql">true</property>

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

 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

 <!-- 实体类的映射文件 -->

 <mapping resource="com/nercl/model/Dept.hbm.xml"/>

 <mapping resource="com/nercl/model/Emp.hbm.xml"/>

 </session-factory>

</hibernate-configuration>

5、编写HibernateSessionFactory

HibernateSessionFactory类是原来初始化Hibernate的,使用Hibernate开发时,必须编写该类。

public class HibernateSessionFactory {

 

private static Configuration cf = null;

private static SessionFactory sf = null;

 

static {

try {

cf = new Configuration().configure();

sf = cf.buildSessionFactory();// 创建session

System.out.println("SessionFactory创建成功!");

} catch (HibernateException e) {

throw new RuntimeException("SessionFactory创建失败", e);

}

}

 

public static Session getSession() {// 获得session的方法

Session session = null;

try {

if (session == null || session.isOpen() == false)

session = null;

session = sf.getCurrentSession();

} catch (HibernateException e) {

throw new RuntimeException("Session创建失败", e);

}

return session;

}

 

public static void closed(Session session) {// 关闭session的方法

try {

if (session != null)

session.close();

} catch (HibernateException e) {

throw new RuntimeException("Session关闭失败", e);

}

}

}

 

6、登录操作

a) 登录页面 代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>用户登录</title>

</head>

<body>

<form action="LoginServlet" method="post">

用户名:<input type="text" name="username">

密码:<input type="password" name="password">

<input type="submit" value="登录">

</form>

</body>

</html>

上述代码中,from表单提交到LoginServlet中,使用post提交方式

b) Servlet处理类 LoginServlet代码如下:(这里使用的servlet3.0新特性:注解,如果不采用这种方式需要在web.xml中进行配置)

/**

 * Servlet implementation class LoginServlet

 */

@WebServlet("/LoginServlet")

public class LoginServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

       

    /**

     * @see HttpServlet#HttpServlet()

     */

    public LoginServlet() {

        super();

        // TODO Auto-generated constructor stub

    }

 

/**

 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

 */

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// TODO Auto-generated method stub

doPost(request,response);

}

 

/**

 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

 */

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// TODO Auto-generated method stub

response.setCharacterEncoding("utf-8");//设置response编码方式

request.setCharacterEncoding("utf-8");//设置request编码方式

//获取前台传递过来的数据

String username = request.getParameter("username");

String password = request.getParameter("password");

 

System.out.println("username==="+username+"password====="+password);

 

EmpDao empDao = new EmpDaoImpl();

//判断是否存在

if(empDao.check(username,password)!=null){

request.getRequestDispatcher("index.jsp").forward(request, response);

}else{

request.getRequestDispatcher("login.jsp").forward(request, response);

}

}

 

}

 

上述代码中有这样一行代码:

EmpDao dao = new EmpDaoImp();

其中EmpDao是一个接口,EmpDaoImp是接口实现类。这一行代码是接口实现类的对象指向接口的引用。

c) 接口以及接口实现类

接口类EmpDao中代码如下:

public interface EmpDao extends BaseDao<Emp>{

 

public Emp check(String username, String password);

 

}

上述代码出现了extends关键字,这里我继承了基本的Dao操作,这个基本dao提供常用的一些数据库操作的方法。

BaseDao代码如下:

public interface BaseDao<T>{

public void save(T entity);  

  

    public void update(T entity);  

  

    public void delete(Serializable id);  

  

    public T findById(Serializable id);  

  

    public List<T> findByHQL(String hql, Object... params);

    

    public List<T> findAll(String hql);

}

他们想对应的实现类如下:

public class EmpDaoImpl extends BaseDaoImpl<Emp> implements EmpDao {

 

@Override

public Emp check(String username, String password) {

// TODO Auto-generated method stub

Emp emp = null;

//这里调用父类的获取session的方法

Session session = this.getSession();

session.beginTransaction();

Query query = session.createQuery("from Emp e where e.empname = ? and e.password = ?").setParameter(0, username).setParameter(1, password);

emp = (Emp)query.uniqueResult();

return emp;

}

 

}

 

public class BaseDaoImpl<T> implements BaseDao<T>{

 

private Class<T> clazz;

/** 

     * 通过构造方法指定DAO的具体实现类 

     */  

    @SuppressWarnings("unchecked")

public BaseDaoImpl() {  

        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();  

        clazz = (Class<T>) type.getActualTypeArguments()[0];  

    }

    /** 

     * 获取当前工作的Session 

     */  

    protected Session getSession() {  

        return HibernateSessionFactory.getSession();  

    }   

@Override

public void save(T entity) {

// TODO Auto-generated method stub

System.out.println("执行保存方法 start!!");

//this.getSession.save(entity); 

//直接使用这个会出现一种情况,保存后数据库没有数据。

//但是使用数据库管理工具添加数据,本来是没有记录的,插入数据之后ID竟然不是从一开始的

//出现这种的现象的原因是事务没有开启。

//hibernate成功执行sava且不报错后,数据库中没有数据的原因:hibernate 必须显示的声明提交事务

Session session = this.getSession();

session.beginTransaction();

session.save(entity);

session.beginTransaction().commit();

System.out.println("执行保存方法 end!!");

}

 

@Override

public void update(T entity) {

// TODO Auto-generated method stub

//参考save方法修改

this.getSession().update(entity);

}

 

@Override

public void delete(Serializable id) {

// TODO Auto-generated method stub

Session session = this.getSession();

session.beginTransaction();

session.delete(this.findById(id));

session.beginTransaction().commit();

}

 

@SuppressWarnings("unchecked")

@Override

public T findById(Serializable id) {

// TODO Auto-generated method stub

Session session = this.getSession();

session.beginTransaction();

return (T)session.get(this.clazz, id);

}

 

@SuppressWarnings("unchecked")

@Override

public List<T> findByHQL(String hql, Object... params) {

// TODO Auto-generated method stub

Query query = this.getSession().createQuery(hql);  

        for (int i = 0; params != null && i < params.length; i++) {  

            query.setParameter(i, params);  

        }  

        return query.list();  

}

@SuppressWarnings("unchecked")

@Override

public List<T> findAll(String hql) {

// TODO Auto-generated method stub

Session session = this.getSession();

session.beginTransaction();

Query query = session.createQuery(hql);  

return query.list();

}

 

}

 

编写好这些代码以后就可以实现基本的登录操作咯。登录之后可以对部门进行添加删除等操作。方法同上面就不在写了。


你可能感兴趣的:(hibernate 结合servlet及 jsp 的使用)