論壇首頁 Java企業應用論壇

SSH框架注解版整合搭建圖文教程

瀏覽 102 次
精華帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隱藏帖 (0)
作者 正文
   發表時間:2019-06-03  

文章轉載自:https://www.jiweichengzhu.com/article/68df4c127c2a491bb6f7056e970318d5

如果還有問題,加群交流:686430774

案例代碼下載,請移步原文鏈接!

SSH框架用起來還是可以的,但配置也蠻多,struts一堆配置,hibernate一堆配置,spring更不用說也是一堆配置,還好各個框架的設計團隊都意識到了這個問題,都在朝著這方面而努力,在后續的版本中,都推出了注解配置,方便了很多。

之前的筆記中也有關于ssh框架的注解版,整理出來分享給大家,由于前面講過了ssh配置版,描述的比較詳細了,這一次就不再重復講解了,只將我認為一些關鍵的地方貼出來著重說明一下。

除了spring的版本保持不變,另外兩個框架都稍微提升了幾個小版本:

Struts版本:2.3.24

Spring版本:4.1.5.RELEASE

Hibernate版本:4.3.10.Final

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"/>
    <!-- 將對象交給spring管理 -->
    <!-- 此時可以不用在applicationContext.xml中生命bean了,直接從action就可以注入進去 -->
    <constant name="struts.objectFactory" value="spring"/>
    <!-- 確定搜索包的路徑(坑死:一定記得加上這句啊,默認只掃描以action命名的包) -->
    <constant name="struts.convention.package.locators" value="controller"/>

</struts> 

后兩個配置需要重點關注,由于使用注解了,那我們就不再需要手動聲明bean來注入對象了,直接交給spring來管理就行,而沒了配置文件,struts的@Namespace也需要使用注解來聲明,在這里要指定@Namespace注解所在的包名,默認是action,如果你跟我一樣習慣性寫controller,千萬記得在這里指定,我當時被坑了好久。

applicationContext.xml

?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 	http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
 	http://www.springframework.org/schema/tx 
 	http://www.springframework.org/schema/tx/spring-tx-4.1.xsd 
 	http://www.springframework.org/schema/context
 	http://www.springframework.org/schema/context/spring-context-4.1.xsd">

    <!-- 開啟注解并掃描   -->
    <!-- <context:annotation-config /> -->
    <!-- 開啟注解并掃描,并指定掃描目錄(有下面這一句,上面那句就可以省略) -->
    <context:component-scan base-package="com.ssh"/>

    <!-- 數據源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true"/>
        <property name="username" value="test"/>
        <property name="password" value="111111"/>
    </bean>

    <!-- hibernate使用注解的方式 -->
    <!-- 可以使用@Column、@OneToOne、@DateTimeFormat、@JsonSerialize等注解 -->
    <!-- @JoinColumn(name = "關聯字段", unique = true) -->
    <!-- @OneToOne(targetEntity = 關聯實體bean.class) -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 注解方式,下面這句一定要加上,不然掃描不到實體bean -->
        <property name="packagesToScan" value="com.ssh.entity"/>
        <!-- 在這里配置了xml映射文件的位置,就不需要在hibernate.cfg.xml中配置了 -->
        <!-- <property name="mappingLocations" value="classpath:com/ssh/entity/*.hbm.xml"/> -->
        <!-- 配置sql格式化、dialect等屬性 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.autoReconnect">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <!-- hibernate使用配置文件的方式 -->
    <!--
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
                <prop key="hibernate.autoReconnect">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        直接將配置文件寫在spring配置中
        <property name="mappingResources">
            <list>
                <value>com/ssh/entity/Book.hbm.xml</value>
                <value>com/ssh/entity/School.hbm.xml</value>
                <value>com/ssh/entity/Student.hbm.xml</value>
            </list>
        </property>
        引用外部配置文件

        <property name="configLocations">
           <list>
               <value>classpath:hibernate.cfg.xml</value>
           </list>
       </property>

    </bean>
    -->

    <!-- 將hibernateTemplate交由Spring管理,以便使用注解的方式進行調用 -->
    <!-- 否則,需要在dao層繼承hibernateDaoSupport,使用的時候需要調用getHibernateTemplate()方法 -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 事務管理 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 開啟@Transactional注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

?

spring的這個配置文件中,關于hibernate的配置,與之前相比有了兩個變化:不用引入映射文件需要掃描實體bean,因為使用了注解模式,可以不需要那些映射文件了,直接在bean使用注解來取代xml。

JavaBean注解:

package com.ssh.entity;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.format.annotation.DateTimeFormat;

@Entity // 表明是一個實體bean
@Table(name = "students") // 對應數據庫的表名字
public class Student {

    /**
     * ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)// 數據庫自增,這句加不加無所謂
    //如果使用的是oracle數據庫,需要使用自增序列,可以使用下面兩行注解配置
    //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_student")
    //@SequenceGenerator(name = "seq_student", sequenceName = "ZZ_STUDENTS", allocationSize = 1)
    private int id;

    /**
     * 姓名
     */
    @Column(name = "student_name", nullable = false, length = 25)
    private String name;

    /**
     * 性別
     */
    @Column(name = "student_sex", nullable = false, length = 5)
    private String sex;

    /**
     * 年齡
     */
    @Column(name = "student_age", nullable = false, length = 5)
    private int age;

    /**
     * 生日
     */
    @Column(name = "student_birthday")
    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    /**
     * 愛好
     */
    @Column(name = "student_hobby", nullable = false, length = 50)
    private String hobby;

    /**
     * 學校(schoolId關聯)
     */
    // xml配置方式的一對一,就是參照這里的注解方式
    // 多方(主動方)加關聯,并限定唯一從而達到一對一效果,一方(被動方)則不用加配置
    @JoinColumn(name = "school_id", unique = true)
    @ManyToOne(targetEntity = School.class, fetch = FetchType.EAGER)
    // 上面兩個注解的效果,等同于下面的配置
    // <many-to-one name="school" column="school_id" unique="true" lazy="false"/>
    private School school;

    public Student() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

}
?

可以看到,很多在xml中的配置,都以注解的形式表現出來了,@Id、@Column、@ManyToOne等等,語義也都清晰,一眼看過去就知道是什么意思,代碼中的注釋寫的比較全,這里不在多說。

Controller控制器:

package com.ssh.controller;

import com.ssh.entity.School;
import com.ssh.service.SchoolService;
import java.util.List;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

@Controller// spring托管
@Scope("prototype")// 多例
@Namespace("/schoolManage")// 對應配置文件中的每個action的name
@ParentPackage("struts-default")// 對應配置文件中的:<package name="default" extends="struts-default">
public class SchoolController extends BaseController {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    // 由于bean配置了spring托管,所以這里可以直接使用注解注入
    @Autowired
    private SchoolService schoolService;

    /**
     * list列表
     */
    private List<School> list;
    /**
     * 實體bean
     */
    private School school;

    @Action(value = "school_list", results = {@Result(name = "list", location = "/school_list.jsp")})
    public String list() {
        list = schoolService.list(searchText);
        return "list";
    }

    @Action(value = "school_toAdd", results = {@Result(name = "add", location = "/school_maintain.jsp")})
    public String toAdd() {
        type = "add";
        return "add";
    }

    @Action(value = "school_add", results = {@Result(name = "refresh", type = "redirect", location = "/schoolManage/school_list.action")})
    public String add() {
        schoolService.add(school);
        return "refresh";
    }

    @Action(value = "school_toUpdate", results = {@Result(name = "update", location = "/school_maintain.jsp")})
    public String toUpdate() {
        type = "update";
        school = schoolService.getById(id);
        return "update";
    }

    @Action(value = "school_update", results = {@Result(name = "refresh", type = "redirect", location = "/schoolManage/school_list.action")})
    public String update() {
        schoolService.update(school);
        return "refresh";
    }

    @Action(value = "school_delete", results = {@Result(name = "refresh", type = "redirect", location = "/schoolManage/school_list.action")})
    public String delete() {
        schoolService.delete(id);
        return "refresh";
    }

    // 感覺這也是struts非常不爽的地方
    // 前臺需要用到的變量總是需要set、get一下才行,springMVC中就不需要
    public List<School> getList() {
        return list;
    }

    public void setList(List<School> list) {
        this.list = list;
    }

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

}
?

在控制器頭部加了一堆的注解,有指定spring托管的,有配置作用域的,有配置namespace的,大家直接看我上面寫的注釋就行。

基本上需要注意的一些點都列出來了,還是比較簡單的,再給大家來一張工程目錄結構圖:

SSH框架注解版搭建圖文教程?

論壇首頁 Java企業應用版

跳轉論壇:
Global site tag (gtag.js) - Google Analytics pk10缩号工具手机版 邯郸县| 凉城县| 柯坪县| 兖州市| 本溪| 岳阳市| 龙江县| 巴林右旗| 吉林省| 常宁市| 宁化县| 张家港市| 邓州市| 盐边县| 永定县| 岫岩| 筠连县| 江津市| 屏东县| 邯郸县| 兴城市| 尤溪县| 绍兴县| 东丽区| 凤凰县| 旺苍县| 雷波县| 福海县| 鄂托克前旗| 红原县| 平南县| 巴林右旗| 甘德县| 大连市| 遵义县| 虹口区| 普兰店市| 昭通市|