1. 程式人生 > >SSH電力項目一 搭建Hibernate框架

SSH電力項目一 搭建Hibernate框架

http mls under 註解 extc domain break eth ont

Hibernate所需要的基本文件:

ElectText.java

ElecText.hbm.xml

hibernate.cfg.xml

第一步:創建測試表Elec_Text:

create table Elec_Text(textID varchar(50) not null primary key,textName varchar(50),textDate datetime,textRemark varchar(500) );

第二步:創建項目,導入jar包

第三步:持久層

(1)在com.elec.domain中創建ElecText.java

ElecText.java 說明:持久層要實現一個序列化接口:Serializable

public class ElecText implements java.io.Serializable {
    
    private String textID;        //主鍵ID
    private String textName;      //測試名稱
    private Date textDate;        //測試日期
    private String textRemark;    //測試備註
    
    public String getTextID() {
        return textID;
    }
    public void
setTextID(String textID) { this.textID = textID; } public String getTextName() { return textName; } public void setTextName(String textName) { this.textName = textName; } public Date getTextDate() { return textDate; } public void setTextDate(Date textDate) {
this.textDate = textDate; } public String getTextRemark() { return textRemark; } public void setTextRemark(String textRemark) { this.textRemark = textRemark; } }

在com.elec.domain目錄下,創建ElecText.java對應的映射文件 ElecText.hbm.xml

到對應的jar包中找到約束,復制到配置文件中:

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 打開hibernate包,找到約束文件 -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 有了約束,就可以寫mapping -->
<hibernate-mapping>
    <class name="com.kangjie.elec.domain.ElecText" table="Elec_Text"><!-- name是類型 ,在類名上按F2選中全路徑名-->
        <id name="textID" type="string" column="textID">
            <generator class="uuid"></generator>
        </id>
        <property name="textName" type="string" column="textName"></property>
        <property name="textDate" type="date" column="textDate"></property>
        <property name="textRemark" type="string" column="textRemark"></property>
    </class>
</hibernate-mapping>
<!-- 然後寫映射文件 -->

(3) 在工程下創建文件夾config,config下創建hibernate.cfg.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>
    <!-- 連接數據庫信息 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/kangjie?useUnicode=true&amp;characterEncoding=utf8</property>
        <property name="hibernate.connection.username">admin</property>
        <property name="hibernate.connection.password">admin</property>
        <!-- 其他配置 --><!--  測試業務層的時候,不用自動提交 -->
        <property name="hibernate.connection.autocommit">true</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.hbm2ddl.auto">update</property><!-- 沒有表就自動創建 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 添加映射 -->
        <mapping resource="com/kangjie/elec/domain/ElecText.hbm.xml"/>
        <!-- 修改了項目名稱,可以還需要修改myeclipse下的web選項的名稱 -->
    </session-factory>

</hibernate-configuration>

(4) 使用junit在test包中進行測試(並且導入log4j的配置文件)

public class TestHibernate {
/**
 * 測試保存
 */
    @Test
    public void save(){
        Configuration configuration = new Configuration();
        configuration.configure();//加載classpath下的hibernate.cfg.xml文件
        SessionFactory sf = configuration.buildSessionFactory();
        Session s = sf.openSession();
        Transaction ts = s.beginTransaction();
        
        ElecText elecText = new ElecText();
        elecText.setTextName("測試數據");
        elecText.setTextDate(new Date());
        elecText.setTextRemark("備註");
        s.save(elecText);
        ts.commit();
        s.close();
        /**
         * 測試的過程中可能會有日誌警告,因為hibernate需要配置log4j日誌
         */
    }
}

然後添加log4j.propertities

技術分享

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change ‘info‘ to ‘debug‘ ###

log4j.rootLogger=error, stdout

#log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
#log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
#log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
#log4j.logger.org.hibernate.tool.hbm2ddl=debug

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
#log4j.logger.org.hibernate.cache=debug

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

測試結果:

技術分享

數據庫中的顯示

技術分享

第四步:DAO層

每個持久化對象都會對應一個Dao,都有操作單標的CRUD的操作;為了避免重復,抽取一個公用的Dao:CommonDao

技術分享

(1) 在com.elec.dao中創建2個接口(公用接口和業務接口)

* 公共接口

public interface ICommonDao<T> {
    void save(T entity);
}

* 業務接口(需要繼承公共接口,並且指定泛型T所對應的對象:

/**
 * 每個持久化對象都會對應一個Dao,都有操作單單表的CRUD:create , Retrieve,update,delete
 *
 */
public interface IElecTextDao extends ICommonDao<ElecText>{
    public static final String SERVICE_NAME="com.kangjie.elec.dao.impl.ElecTextDaoImpl";
}

(2)在com.elec.dao.impl中創建2個接口的實現類

* 公用類(需要繼承HibernateDaoSupport,這樣可以方便使用HibernateTemplate對象):

public class CommonDaoImpl<T> extends HibernateDaoSupport implements ICommonDao<T> {

    /**
     * 使用hibernate模板保存:
     */
    @Resource(name="sessionFactory")
    public void setDi(SessionFactory sessionFactory){
        System.out.println("sessionFactory" + sessionFactory);
        this.setSessionFactory(sessionFactory);
    }
    
    public void save(T entity) {
        this.getHibernateTemplate().save(entity);
    }

}

* 業務類(需要繼承公用類,這樣可以使用公用類中的定義的方法)

/**
* spring容器:
* * 創建Action,Service,Dao的對象(IOC)
* * * <bean id="" class=""></bean>
* * 每層進行註入(DI)
* ** <property name="" ref=""/>
* * 聲明式事務(AOP)切面編程
* **** 聲明事務管理器
* * 電力項目(註解方式)
* * @Controller @Service , @Repository @Commponent
*
*/
//註解支持
/**
* 相當於正在spring容器中定義:
* <bean id="elecTextDaoImpl" class="com.itheima.elec.dao.impl.ElecTextImpl">
*這種寫法過於繁瑣,在接口IElecTextDao中指定 標示 public static final String SERVICE_NAME="com.kangjie.elec.dao.impl.ElecTextDaoImpl";


*/
//唯一的屬性
@Repository(IElecTextDao.SERVICE_NAME)
public class ElecTextDaoImpl extends CommonDaoImpl<ElecText> implements IElecTextDao {

}

(3) 在config中創建spring的配置文件(beans.xml)

<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context 
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd
                            http://www.springframework.org/schema/tx 
                            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                            http://www.springframework.org/schema/aop 
                            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> 
<!-- 1.添加組件對註解的支持 :表示這個包下都支持註解 -->                            
<context:component-scan base-package="com.kangjie.elec"/>    
<!--  -->

<!-- 3.spring整合hibernate的核心:session工廠 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <!-- 註入資源 -->
    <property name="configLocation">
        <value>
            classpath:hibernate.cfg.xml
        </value>
    </property>
</bean>
<!-- 4.創建事務管理器 :管理session工廠,即:hibernate -->
<bean id="trManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- 註入 sessionfactory -->
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 5:事務處理     註解,[email protected] -->
<tx:annotation-driven transaction-manager="trManager" />
<!--下邊這部分是設置配置文件,只做演示--> <!-- 事務處理配置文件--> <!-- <tx:advice id="aa" transaction-manager="trManager"> <tx:attributes> <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/> <tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/> <tx:method name="delete*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/> <tx:method name="*" read-only="false"/> </tx:attributes> </tx:advice> <aop:config> --> <!-- * com.itheima.elec.service..* .* (..) --> <!-- 返回任意類型 service包及其子包 中所有類, 類中所有方法 參數任意--> <!-- <aop:pointcut expression="execution(* com.kangjie.elec.service..*.*(..))" id="bb"/> <aop:advisor advice-ref="aa" pointcut-ref="bb"/> </aop:config> --> </beans>

技術分享

技術分享

(4) 使用junit完成測試

public class TestDao {

    //保存
    @Test
    public void save(){
        //加載spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        IElecTextDao elecTextDao = (IElecTextDao) ac.getBean(IElecTextDao.SERVICE_NAME);//找節點
        ElecText elecText = new ElecText();
        elecText.setTextName("abcde");
        elecText.setTextDate(new Date());
        elecText.setTextRemark("make a difference");
        elecTextDao.save(elecText);
    }
}

註意:如果數據沒有保存,需要設置事務自動提交:在hibernate.cfg.xml中添加:

<!-- 使用hibernate的方式提交事務(自動提交) -->
<property name="hibernate.connection.autocommit">true</property>

第五步:Service層

(1) 在com.elec.service中創建接口:

public interface IElecTextService {
    public static final String SERVICE_NAME="com.kangjie.elec.service.impl.ElecTextServiceImpl";

    public void saveElecText(ElecText elecText);
}

(2) 在com.elec.service.impl中創建接口的實現類:

/**
 * spring框架使用的是分層的註解
* @Repository 持久層
* @Service 服務層
* @Controller 控制層
* 在Service層添加註解: @Transactional
*
* @Service *相當於在spring中定義: * <bean id ="" class="">
*/ @Service(IElecTextService.SERVICE_NAME) @Transactional(readOnly=true) //由於spring提供的聲明式事務處理,進行事務的控制,[email protected](),同時去掉hibernate.cfg.xml中的配置,由spring統一控制。 public class ElecTextServiceImpl implements IElecTextService { @Resource(name=IElecTextDao.SERVICE_NAME) IElecTextDao elecTextDao;
/*
由於spring提供的聲明式事務處理,進行事務的控制,在業務層的類和方法上定義@Transactional(),同時去掉hibernate.cfg.xml中的配置,由spring統一控制。去掉的代碼是

<!-- 使用hibernate的方式提交事務(自動提交) -->

<property name="hibernate.connection.autocommit">true</property>

*/

    @Override
    @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)
    public void saveElecText(ElecText elecText) {
        elecTextDao.save(elecText);
        //然後測試
    }

}

(3) 測試

public class TestService {

    @Test
    public void save(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        IElecTextService elecTextService = (IElecTextService)ac.getBean(IElecTextService.SERVICE_NAME);
        
        ElecText elecText = new ElecText();
        elecText.setTextName("測試service名稱3");
        elecText.setTextDate(new Date());
        elecText.setTextRemark("備註service3");
        elecTextService.saveElecText(elecText);
    }
}

由於spring提供的聲明式事務處理,進行事務的控制,在業務層的類和方法上定義@Transactional(),同時去掉hibernate.cfg.xml中的配置,由spring統一控制。去掉的代碼是:

<!-- 使用hibernate的方式提交事務(自動提交) -->
<property name="hibernate.connection.autocommit">true</property>

第六步:

(1)在com.elec.web.action中創建Action(業務Action)類和BaseAction(公用Action)

Action類:(註意:這裏要設置成多例,[email protected](value=prototype),因為struts2的Action是多實例,多線程)

struts2是模型驅動 ?

@SuppressWarnings("serial")
@Controller("elecTextAction")
@Scope(value="prototype")
public class ElecTextAction extends ActionSupport implements ModelDriven<ElecText>{

    ElecText elecText = new ElecText();
    
    //註入Service
    @Resource(name=IElecTextService.SERVICE_NAME)
    IElecTextService elecTextService;
    
    
    //執行保存
    public String save(){
        elecTextService.saveElecText(elecText);
        return "save";
    }

    @Override
    public ElecText getModel() {
        
        // TODO Auto-generated method stub
        return elecText;
    }
}

然後將復用的內容抽取為一個公用類BaseAction類

package com.elec.web.action;

import java.lang.reflect.ParameterizedType;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class BaseAction<T> extends ActionSupport implements ModelDriven<T> {

T entity;
// T型實例化
public BaseAction(){
//T型轉換
// this.getClass().getGenericSuperclass();
ParameterizedType parameterizedType = (ParameterizedType) this.getClass().getGenericSuperclass();
Class entityClass = (Class) parameterizedType.getActualTypeArguments()[0] ;
try {
entity = (T) entityClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public T getModel() {
return entity;
}

}

斷點調試,使用watch查看this.Class的值 :

技術分享

繼續查看

技術分享

技術分享

轉換成功

首先

在com.elec.util包下創建公用類(用於泛型轉換)。

泛型轉換的目的子類傳遞真實對象類型,在父類中使用泛型轉換成真實對象類型。

以後util包下封裝的就是公用類。

package com.elec.utils;

import java.lang.reflect.ParameterizedType;

public class TUtils {

    public static Class getActualType(Class entity){
        ParameterizedType parameterizedType = (ParameterizedType) entity.getGenericSuperclass();
        Class entityClass = (Class) parameterizedType.getActualTypeArguments()[0];
        return entityClass;
    }
}

然後抽取BaseAction類,調用TUtils中的方法

BaseAction.java

package com.elec.web.action;
public class BaseAction<T> extends ActionSupport implements ModelDriven<T>,ServletRequestAware,ServletResponseAware{ T entity; protected HttpServletRequest request; protected HttpServletResponse response; // protected HttpServletRequest request; //實例化泛型 public BaseAction(){ //T型轉換 Class entityClass = TUtils.getActualType(this.getClass()); try { entity = (T) entityClass.newInstance(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public T getModel(){ return entity; } @Override public void setServletResponse(HttpServletResponse response) { // TODO Auto-generated method stub this.response = response; } @Override public void setServletRequest(HttpServletRequest request) { // TODO Auto-generated method stub this.request = request; } }

ElecTextAction.java 繼承BaseAction

package com.elec.web.action;

@SuppressWarnings("serial")
@Controller("elecTextAction")
@Scope(value="prototype")
public class ElecTextAction extends BaseAction<ElecText>{

    ElecText elecText = this.getModel();
    
    //註入Service
    @Resource(name=IElecTextService.SERVICE_NAME)
    IElecTextService elecTextService;
    
    
    //執行保存
    public String save(){
        elecTextService.saveElecText(elecText);
        String textDate = request.getParameter("textDate");
        System.out.println(textDate);
        return "save";
    }

}

創建struts2的配置文件struts.xml

<?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>
    <!-- 開發模式 -->
    <constant name="struts.devMode" value="true"></constant>
    <!-- ui主題,簡單主題 -->
    <constant name="struts.ui.theme" value="simple"></constant>
    <!-- 修改struts的後綴 改成do -->
    <constant name="struts.action.extension" value="do"></constant>
    
    <!-- 系統管理 -->
    <package name="system" namespace="/system" extends="struts-default">
        <!-- 測試 -->
        <action name="elecTextAction_*" class="elecTextAction" method="{1}">
                <result name="save">/system/textAdd.jsp</result>
        </action>
    </package>
</struts>

在web.xml中添加配置:

<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></display-name>    
    <!-- 配置struts2的過濾器,這是struts2運行的核心 -->
    <filter>
        <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- web容器啟動的時候,自動加載spring容器(監聽器) -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:beans.xml</param-value>
    </context-param>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

測試頁面:

textAdd.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
   <script type="text/javascript" src="${pageContext.request.contextPath}/My97DatePicker/WdatePicker.js"></script>
<html>
<head>
<title>測試專用jsp</title>
<link href="${pageContext.request.contextPath }/css/Style.css" type="text/css" rel="stylesheet">

  <script language="javascript"> 
   function checkchar(){
          document.Form1.action="${pageContext.request.contextPath }/system/elecTextAction_save.do";
          document.Form1.submit();
  }
  function addEnter(element){
   document.getElementById(element).value = document.getElementById(element).value+"<br>";
   
  }
  </script>


</head>

<body>
<form name="Form1" id="Form1" method=post>

    <table cellspacing="1" cellpadding="5" width="90%" align="center" bgcolor="#f5fafe" style="border:1px solid #8ba7e3" border="0">

        <tr>
            <td class="ta_01" colspan=2 align="center" background="${pageContext.request.contextPath }/images/b-info.gif">
            <font face="宋體" size="2"><strong>測試專用jsp</strong></font>
            </td>
        </tr>
        <TR height=10><td></td><td></td></TR>
        
        <tr>
            <td class="ta_01" align="center" bgcolor="#f5fafe" width="15%">測試名稱:</td>
            <td class="ta_01" bgcolor="#ffffff" style="word-break: break-all">
    
            <textarea name="textName" id="textName"   style="width: 500px; height: 160px; padding: 1;FONT-FAMILY: 宋體; FONT-SIZE: 9pt" onkeydown="if(event.keyCode==13)addEnter(‘textName‘);"></textarea>
            </td>
            
        </tr>
        <tr>
            <td class="ta_01" align="center" bgcolor="#f5fafe" width="15%">測試日期:</td>
            <td class="ta_01" bgcolor="#ffffff" style="word-break: break-all">
    
            <input name="textDate" type="text" maxlength="50" size=20 onclick="WdatePicker()">
            </td>
            
        </tr>
        <tr>
            <td class="ta_01" align="center" bgcolor="#f5fafe" width="15%">測試備註:</td>
            <td class="ta_01" bgcolor="#ffffff" style="word-break: break-all">
            <textarea name="textRemark" id="textRemark"  style="width: 500px; height: 160px; padding: 1;FONT-FAMILY: 宋體; FONT-SIZE: 9pt" onkeydown="if(event.keyCode==13)addEnter(‘textRemark‘);"></textarea>
            </td>
            
        </tr>
        <tr>
            <td class="ta_01" style="width: 100%" align="center" bgcolor="#f5fafe" colspan="2">
            <input type="button" name="BT_Submit" value="保存" onclick="checkchar()" id="BT_Submit" style="font-size:12px; color:black; height=20;width=50">
            </td>
        </tr>
    </table>
      
</form>

</body>
</html>

實現ServletRequestAware,ServletResponseAware報錯:

can not implement the missing methods,either due to compile errors or the projects build path does not resolve all dependencies

上面的錯誤提示的意思是:不能實現丟失的方法,或許是因為編譯錯誤或者工程創建的路徑不能解決所有依賴;也就是缺少Servlet相關的jar包了,這裏是servlet-api.jar

解決辦法:添加servlet-api.jar。

這個jar包可以在tomcat的lib目錄下找到,復制到項目中去就可以了

SSH電力項目一 搭建Hibernate框架