博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SSH小应用
阅读量:4919 次
发布时间:2019-06-11

本文共 18808 字,大约阅读时间需要 62 分钟。

1:Spring整合Hibernate

1 
2 5
6
7
8 9
10
org.hibernate.dialect.MySQL5InnoDBDialect
11 12
13
true
14
true
15 16
17
update
18 19
20 21
22 23
jdbc.user=luweijdbc.password=luweijdbc.driverClass=com.mysql.jdbc.Driverjdbc.jdbcUrl=jdbc:mysql:///sshjdbc.initPoolSize=5jdbc.maxPoolSize=10#...

2:整合struts2

/WEB-INF/views/emp-list.jsp
        
    

3:开始写应用:

  1):两个实体类:部门和员工

package com.ssh.entities;public class Department {    private Integer id;    private String departmentName;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getDepartmentName() {        return departmentName;    }    public void setDepartmentName(String departmentName) {        this.departmentName = departmentName;    }    @Override    public String toString() {        return "Department [id=" + id + ", departmentName=" + departmentName                + "]";    }    }
package com.ssh.entities;import java.util.Date;public class Employee {    private Integer id;    // 不能被修改    private String lastName;    private String email;    // 从前端传入的是 String 类型, 所以需要注意转换    private Date birth;    // 不能被修改    private Date createTime;    // 单向 n-1 的关联关系    private Department department;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getLastName() {        return lastName;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    public Date getBirth() {        return birth;    }    public void setBirth(Date birth) {        this.birth = birth;    }    public Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }    public Department getDepartment() {        return department;    }    public void setDepartment(Department department) {        this.department = department;    }    @Override    public String toString() {        return "Employee [id=" + id + ", lastName=" + lastName + ", email="                + email + ", birth=" + birth + ", createTime=" + createTime                + ", department=" + department + "]";    }    }

  2):写DAO层。这个层面就是为了从数据库中查询出数据

package com.ssh.dao;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;import com.ssh.entities.Employee;public class EmployeeDao {    private SessionFactory sessionFactory;    public void setSessionFactory(SessionFactory sessionFactory) {        this.sessionFactory = sessionFactory;    }    public Session getSession(){        return this.sessionFactory.getCurrentSession();    }        public List
getAll(){ String hql = "FROM Employee e LEFT OUTER JOIN FETCH e.department"; return getSession().createQuery(hql).list(); }}

得到的值放在getAll()方法中。

  3):写service层

package com.ssh.service;import java.util.List;import com.ssh.dao.EmployeeDao;import com.ssh.entities.Employee;public class EmployeeService {    private EmployeeDao employeeDao;    public void setEmployeeDao(EmployeeDao employeeDao) {        this.employeeDao = employeeDao;    }        //现在从数据库中得到employee所有的数据。得到的employee信息放到request.在Action中写。    public List
getAll(){ List
employees=employeeDao.getAll(); return employees; } }

4:):写Action层

package com.ssh.action;import java.util.Map;import org.apache.struts2.interceptor.RequestAware;import com.opensymphony.xwork2.ActionSupport;import com.ssh.service.EmployeeService;public class EmployeeAction extends ActionSupport implements RequestAware{    /**     *      */    private static final long serialVersionUID = 1L;    private EmployeeService employeeService;    public void setEmployeeService(EmployeeService employeeService) {        this.employeeService = employeeService;    }   //把在service中得到数据存放到request作用域中。然后在页面上直接可以这个request作用域就得到相应的数据。    private Map
request; public void setRequest(Map
arg0) { this.request = arg0; } public String list() { System.out.println("1"); request.put("employees", employeeService.getAll()); System.out.println("2"); return "list"; }}
//主页面 List All Employees

展示的页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags" %>      显示所有的信息              
没有任何 信息
ID LASTNAME EMAIL BIRTH CREATETIME DEPT
${id } ${lastName } ${email } ${birth } ${createTime } ${department.departmentName }

这里会出现一个no session 懒加载异常。是因为在查询department的时候没有立即加载。用的时候才加载。但是session已经被hibernate给关闭了。

解决:使用迫切左外连接。先把数据查询出来。

FROM Employee e LEFT OUTER JOIN FETCH e.department

 理解:1:action,service,dao都是类。然后让spring去管理这些类。加载类。bean。然后利用set注入的方式。把值给传入到类中。

       2:写Action的时候一定要加上 scope="prototype"

    3:创建request的时候继承RequestAware接口。

4:简单删除:

  1):页面上的获取id

1 删除

  2):跳转

/emp_list

  3):从数据库中删除这条id的信息

public void delete(Integer id){        String hql="DELETE FROM Employee e WHERE e.id=?";        getSession().createQuery(hql).setInteger(0, id).executeUpdate(); //setInteger(0,id) 说明是第一个参数。executeUpdate() 执行修改。    }

  4):service获取删除这条数据的信息

public void delete(Integer id){        employeeDao.delete(id);    }

  5):Action得到

private Integer id;    public void setId(Integer id) {        this.id = id;    }    public String delete(){        employeeService.delete(id);        return "success";    }

理解:从页面中得到id。然后在action中设置一个成员变量。setId方法中。形参赋值给成员变量id。然后this.id得到页面上的值,传递给service里delete方法的形参。然后传递给

     dao中的delete方法的形参。然后hibernate从数据库中删除数据。

 5:AJAX删除:

1 删除2          3 

给a节点加上class类。function直接用class的名字。然后再弄一个隐藏域,用来显示名字。

    
            if(data =="1"){                        alert("删除成功");                        $tr.remove();                    }else{                        alert("删除失败"); } 这句话要用到ajax在struts2中如何使用。 用inputStream
private InputStream inputStream;    public InputStream getInputStream() {        return inputStream;    }    public String delete(){        try {            employeeService.delete(id2);            inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));        } catch (Exception e) {            e.printStackTrace();            try {                inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));            } catch (UnsupportedEncodingException e1) {                e1.printStackTrace();            }        }        return "delete";    }
 

注意这个返回值 return "delete"; 

在struts.xml中的跳转。不用去重定向到emp_list了。name就是返回值。

       
text/html
inputStream

 6:添加一个员工信息

需要先把是哪个部门给查询出来

因为每个Dao都要用到Session。所以写一个类BaseDao

1 package com.ssh.dao; 2  3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5  6 public class BaseDao { 7     private SessionFactory sessionFactory; 8  9     public void setSessionFactory(SessionFactory sessionFactory) {10         this.sessionFactory = sessionFactory;11     }12     public Session getSession(){13         return this.sessionFactory.getCurrentSession();14     }15     16 }

从数据库中查询出部门

public class DepartmentDao extends BaseDao{    public List
getAll(){ String hql ="FROM Department"; return getSession().createQuery(hql).list(); }}

Service

public class DepartmentService {    private DepartmentDao departmentDao;    public void setDepartmentDao(DepartmentDao departmentDao) {        this.departmentDao = departmentDao;    }        public List
getAll(){ return departmentDao.getAll(); }}

在Action中写个input方法,用来把Department的方法存储到request作用域中

public String input(){        request.put("departments", departmentService.getAll());        return INPUT;    }

用Spring来管理Service和Dao

主页面:

点击添加后,跳转到emp_input Action,然后在Action中调用input方法,去加载Department信息。跳转到添加的页面

/WEB-INF/views/emp-input.jsp
//把部门的信息显示出来     

点击提交submit的时候,到Action中。先去调用prepareSave()方法。创建一个Employee对象

  public void prepareSave(){        model = new Employee();    }

然后调用getModel()方法,把Employee对象放到值栈的栈顶。由prepare拦截器把表单的值赋值给栈顶对象对应的属性。

private Employee model;    public Employee getModel() {        // TODO Auto-generated method stub        return model;    }

 

需要先继承ModelDriven<Employee>,Preparable拦截器。

//这是Preparable拦截器的方法public void prepare() throws Exception {    }

关于PrepareInterceptor

对应的源码分析:com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor
public String doIntercept(ActionInvocation invocation) throws Exception {              // 获取实例              Object action = invocation.getAction();                                         // 判断Action是否实现了Preparable接口              if (action instanceof Preparable) {                  try {                      String[] prefixes;                      // 根据当前拦截器firstCallPrepareDo(默认为false)                      // 属性确定prefixes                      if (firstCallPrepareDo) {                          prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};                      } else {                          prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};                      }                      // 若为false,则prefixes为:prepare、prepareDo                      // 调用前缀方法                      PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);                  }                  catch (InvocationTargetException e) {                      Throwable cause = e.getCause();                      if (cause instanceof Exception) {                          throw (Exception) cause;                      } else if(cause instanceof Error) {                          throw (Error) cause;                      } else {                          throw e;                      }                  }                // 根据当前拦截器的alwaysInvokePrepare(默认为true)决定是否调用Action的prepare方法               if (alwaysInvokePrepare) {                              ((Preparable) action).prepare();                          }                      }                            return invocation.invoke();                  }         }

对上面程序中的PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);进行分析:

 

public String doIntercept(ActionInvocation invocation) throws Exception {              // 获取实例              Object action = invocation.getAction();                                         // 判断Action是否实现了Preparable接口              if (action instanceof Preparable) {                  try {                      String[] prefixes;                      // 根据当前拦截器firstCallPrepareDo(默认为false)                      // 属性确定prefixes                      if (firstCallPrepareDo) {                          prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};                      } else {                          prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};                      }                      // 若为false,则prefixes为:prepare、prepareDo                      // 调用前缀方法                      PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);                  }                  catch (InvocationTargetException e) {                      Throwable cause = e.getCause();                      if (cause instanceof Exception) {                          throw (Exception) cause;                      } else if(cause instanceof Error) {                          throw (Error) cause;                      } else {                          throw e;                      }                  }                // 根据当前拦截器的alwaysInvokePrepare(默认为true)决定是否调用Action的prepare方法               if (alwaysInvokePrepare) {                              ((Preparable) action).prepare();                          }                      }                            return invocation.invoke();                  }         }

 

对上面的程序中的   Method method = getPrefixedMethod(prefixes, methodName, action);方法进行分析:

 

public String doIntercept(ActionInvocation invocation) throws Exception {              // 获取实例              Object action = invocation.getAction();                                         // 判断Action是否实现了Preparable接口              if (action instanceof Preparable) {                  try {                      String[] prefixes;                      // 根据当前拦截器firstCallPrepareDo(默认为false)                      // 属性确定prefixes                      if (firstCallPrepareDo) {                          prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};                      } else {                          prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};                      }                      // 若为false,则prefixes为:prepare、prepareDo                      // 调用前缀方法                      PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);                  }                  catch (InvocationTargetException e) {                      Throwable cause = e.getCause();                      if (cause instanceof Exception) {                          throw (Exception) cause;                      } else if(cause instanceof Error) {                          throw (Error) cause;                      } else {                          throw e;                      }                  }                // 根据当前拦截器的alwaysInvokePrepare(默认为true)决定是否调用Action的prepare方法               if (alwaysInvokePrepare) {                              ((Preparable) action).prepare();                          }                      }                            return invocation.invoke();                  }         }

 

进行分析后得到的结论:

(1)若Action实现了Prepare接口,则Struts将尝试执行prepare[ActionMethodName]方法,

prepare[ActionMethodName]不存在,则尝试执行prepareDo[ActionMethodName]方法,若都存在,就都不执行。
(2)若PrepareInterceptor的alwaysInvokePrepare属性为false,则Struts2将不会调用实现了Preparable的Action。
(3)解决前一篇文章的方案是:可以为每一个ActionMethod准备Prepare[ActionMethodName]方法,而抛弃原来的prepare方法;避免PrepareInterceptor的alwaysInvokePrepare属性为false,以避免Struts2框架在用prepare方法。
false

然后写保存方法

public String save(){        System.out.println(model);        employeeService.saveOrUpdate(model);        return SUCCESS;    }

service

public void saveOrUpdate(Employee employee){        employeeDao.saveOrUpdate(employee);    }

dao

  public void saveOrUpdate(Employee employee){        getSession().saveOrUpdate(employee);    }

保存完 后重定向到显示所有的页面

/emp_list

 因为页面上的日期是String类型。转换成Date类型

自己写个转换的类。然后java.util.Date   xwork-conversion.properties  指向这个类 java.util.Date=com.ssh.converters.SSHDateConverter

 

package com.ssh.converters;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Map;import org.apache.struts2.util.StrutsTypeConverter;public class SSHDateConverter extends StrutsTypeConverter {    private DateFormat dateFormat;        {        dateFormat = new SimpleDateFormat("yyyy-MM-dd");    }        @Override    public Object convertFromString(Map context, String[] values, Class toClass) {        if(toClass == Date.class){            try {                return dateFormat.parse(values[0]);            } catch (ParseException e) {                e.printStackTrace();            }        }                return null;    }    @Override    public String convertToString(Map context, Object o) {        if(o instanceof Date){            return dateFormat.format((Date)o);        }        return null;    }}

 

 **:用ajax去校验姓名

    添加员工      

在Action中写个lastName属性。页面上输入的值就传入到这个属性中。然后这个属性传入到get方法中。

private String lastName;        public void setLastName(String lastName) {        this.lastName = lastName;    }        public String validateLastName() throws UnsupportedEncodingException{        if(employeeService.lastNameIsValid(lastName)){            inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));         }else{            inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));         }                return "ajax-success";    }

service

//是一个boolean。lastName 是不是为 null 如果为null,为true 就是可用。不为空,false 不可用。     //是一个只读的方法。在事务中添加上 
    public boolean lastNameIsValid(String lastName){
        return employeeDao.getEmployeeByLastName(lastName) == null;     }

dao

public Employee getEmployeeByLastName(String lastName){        String hql="FROM Employee e where e.lastName=?";        Query query=getSession().createQuery(hql).setString(0, lastName);        Employee employee=(Employee) query.uniqueResult();        return employee;    }

 

 

 

 

   

转载于:https://www.cnblogs.com/bulrush/p/8011620.html

你可能感兴趣的文章
What is 0.0.0.0.0
查看>>
第三次作业
查看>>
在ubuntu上搭建开发环境5---联想Y470安装 ubuntu,解决双显卡发热等问题
查看>>
数据库_10_校对集问题
查看>>
三、绘图和可视化之matplotlib
查看>>
HDU 3605 Escape
查看>>
位域/字节对齐
查看>>
Topcoder SRM633 DIV2 解题报告
查看>>
如何使用Log4j?
查看>>
sql 递归显示所有父节点
查看>>
hdu_1558_Segment set(并查集+计算几何)
查看>>
【洛谷2633】Count on a tree(树上主席树)
查看>>
简析平衡树(二)——Treap
查看>>
初学计算几何(一)——点与向量·叉积与点积
查看>>
668. Kth Smallest Number in Multiplication Table
查看>>
多线程——死锁
查看>>
清楚float浮动的四种方法
查看>>
解决Your content must have a ListView whose id attribute is 'android.R.id.list'
查看>>
bzoj5192: [Usaco2018 Feb]New Barns
查看>>
结对-航空购票系统-结对项目总结
查看>>