• C语言中文网教程离线版下载(PDF下载)
    C语言中文网
    • C语言教程
    • C++教程
    • Linux教程
    • Shell脚本
    • socket编程
    • 更多>>
    Maven
    1 Maven是什么
    2 Maven的安装与配置
    3 用命令提示符创建Maven项目
    4 使用cmd命令生成站点和报告
    5 使用MyEclipse建立maven项目
    6 使用MyEcplise构建Maven项目
    7 基于M2Eclipse生成站点和报告
    8 使用Maven开发Web应用
    9 使用Maven开发用户模块的CRUD(增删改查)
    10 Archiva服务器的搭建步骤
    11 Maven私服的配置和使用
    12 Maven搭建SSH框架(一)
    13 Maven搭建SSH框架(二)
    14 Maven搭建SSM框架
    15 版本管理介绍
    16 GPG的安装和使用
    17 Maven使用GPG进行签名验证
    18 Maven生命周期
    19 Maven插件的获取和配置
    20 Maven插件的调用和解析
    21 Maven坐标
    22 Maven仓库及管理方式
    23 Maven仓库的分类
    24 Maven配置远程仓库
    25 Maven快照版本
    26 Maven从仓库中解析依赖的机制
    27 Maven配置镜像仓库
    28 Maven依赖配置和依赖范围
    29 Maven的排除依赖、归类依赖和优化依赖
    30 软件测试的概念和分类
    31 Java单元测试框架
    32 Maven测试插件
    33 Maven测试报告
    34 Maven测试代码的重用
    35 Maven属性
    36 Maven的资源过滤
    37 Maven profile配置管理
    38 Maven的Web资源过滤
    39 激活集成测试
    40 Maven自定义插件
    41 Maven自定义插件的实现
    42 Maven自定义插件Mojo标记和参数
    43 Archetype插件
    44 Archetype数据库的介绍和使用
    首页 > Maven 阅读:408

    Maven搭建SSH(Struts2+Spring+Hibernate)框架入门教程(附带实例)

    < 上一页Maven私服的配置和使用 Maven搭建SSH框架(二)下一页 >

    前面介绍了基于 Archiva 的私服搭建工作,现在全项目组就可以在私服下共用 Maven 开发环境了。

    接下来在 Maven 环境下,基于 Struts2+Spring4.2+Hibernate4.1 框架,体验 Web 应用的开发过程。

    为了展现 Maven 开发的优势,将按如下步骤进行。
    1. 创建三个 POM 工程,定义好 Hibernate、Spring 和 Struts 的基本依赖。
    2. 创建 Service 和 DAO 层的接口模块。
    3. 创建 Service 和 DAO 层的实现模块。
    4. 创建基于 Struts 的 Web 模块。
    5. 整合前面的所有模块,形成一个完整的 SSH 项目。
    6. 完善相关的文档插件的配置,进行安装和测试。

    创建公共 POM 模块

    1. 创建 Hibernate 的公共 POM 模块

    基于 MyEclipse 的 maven-archetype-quickstart 创建 Maven 工程(同前面创建基本的 Maven 工程一样)。因为用的是公共 POM 模块,这里不需要写代码,只需将 Hibernate 和相关的依赖配置在 pom.xml 中,并且在 pom.xml 中将 packaging 方式设置成 pom,表示是一个公共的父 pom。代码如下:
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.com.mvn.ssh.pom</groupId>
        <artifactId>Hibernate4MySQLPOM</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>pom</packaging>
    
        <name>Hibernate4MySQLPOM</name>
        <url>http://maven.apache.org</url>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.7</version>
                <scope>test</scope>
            </dependency>
            <!--hibernate -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>${project.build.hibernate.version}</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-ehcache</artifactId>
                <version>${project.build.hibernate.version}</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate.javax.persistence</groupId>
                <artifactId>hibernate-jpa-2.0-api</artifactId>
                <version>1.0.0.Final</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.34</version>
            </dependency>
        </dependencies>
        <distributionManagement>
            <repository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/internal</url>
            </repository>
            <snapshotRepository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/snapshots</url>
            </snapshotRepository>
        </distributionManagement>
    </project>
    注意 pom.xml 中的第 9 行,<packaging>pom</packaging>表示当前的 pom 是一个独立的 pom 父模块,可以独立安装到仓库中,被其他工程继承使用。

    同时注意最后的 distributionManagement 配置,该配置可以让工程以构件的形式发布到指定的私服。

    右击“工程”,选择 Run As→Maven install 命令,就可以把当前 pom 安装到前面搭建好 Archiva 私服。安装后,可以在 Archiva 管理界面的 Browse 导航页中,看到 Hibernate4MySQLPOM 构件。

    2. 创建 Spring 的公共 POM 模块

    同前面 Hibernate 的 POM 创建一样,可以创建基于 Spring 的 POM 公共构件模块。具体工程创建就不演示了,直接复制到 pom.xml 中。
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.com.mvn.pom</groupId>
        <artifactId>SpringPOM</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>pom</packaging>
    
        <name>SpringPOM</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!-- 3.2.16.RELEASE,3.1.4.RELEASE -->
            <project.build.spring.version>4.2.7.RELEASE
            </project.build.spring.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.7</version>
                <scope>test</scope>
            </dependency>
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>5.0.0.Final</version>
            </dependency>
        </dependencies>
        <distributionManagement>
            <repository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/internal</url>
            </repository>
            <snapshotRepository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/snapshots</url>
            </snapshotRepository>
        </distributionManagement>
    </project>
    同样注意粗体提示部分。右击“工程”,选择 Run As→Maven install 命令,安装 POM 构件。

    3. 创建 Struts 的公共 POM 模块

    重复前面的流程,直接复制 pom.xml 代码和安装 pom 后的管理界面。需要注意,在 pom.xml 中,除了 Struts 的依赖之外,还有 jsp/servlet 的依赖和 Struts 同 Spring 集成的插件依赖。

    pom.xml 内容如下:
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.com.mvn.pom</groupId>
        <artifactId>StrutsPOM</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>pom</packaging>
    
        <name>StrutsPOM</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <!-- jsp servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <!-- struts2 -->
            <!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->
            <dependency>
                <groupId>org.apache.struts</groupId>
                <artifactId>struts2-core</artifactId>
                <version>2.3.16</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-spring-plugin -->
    
            <dependency>
                <groupId>org.apache.struts</groupId>
                <artifactId>struts2-spring-plugin</artifactId>
                <version>2.3.4.1</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.7</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <distributionManagement>
            <repository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/internal</url>
            </repository>
            <snapshotRepository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/snapshots</url>
            </snapshotRepository>
        </distributionManagement>
    </project>

    实现 Hibernate DAO 模块

    在实际项目中,一般会使用面向接口编程,从而实现调用者和被调用者的完全解耦,方便项目的团队开发和后期的扩展。鉴于这样的考虑,Hibernate 持久层的实现分两步进行:第 1 步定义公共 DAO 接口和类;第 2 步基于 Hibernate 完成 DAO 接口的实现。详细介绍如下。

    1. 定义公共 DAO 接口和类

    创建一个普通的 Maven 工程:MvnSSHDemo.DAO。目录结构如图 1 所示。


    图 1  DAO项目结构

    pom.xml 内容如下:
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.com.mvn.ssh.demo</groupId>
        <artifactId>MvnSSHDemo.DAO</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>MvnSSHDemo.DAO</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.7</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <distributionManagement>
            <repository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/internal</url>
            </repository>
            <snapshotRepository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/snapshots</url>
            </snapshotRepository>
        </distributionManagement>
    </project>
    这里有两类代码:一类是实体类(MvnUser),另一类是实体 DAO 接口(IMvnUserDAO)。因为 MvnUser 里面有个状态(status)属性,定义了一个枚举状态类(Status)。具体内容如下。

    1)Status.java 代码如下所示:
    package cn.com.mvn.ssh.demo.entity;
    
    public enum Status {
        ACTIVE("Active"), INACTIVE("Inactive"), DELETED("Deleted"), LOCKED("Locked");
    
        private String status;
    
        private Status(final String status) {
            this.status = status;
        }
    
        public String getStatus() {
            return status;
        }
    
        public void setStatus(String status) {
            this.status = status;
        }
    
        public String toString() {
            return this.status;
        }
    }
    2)MvnUser.java 如下所示:
    package cn.com.mvn.ssh.demo.entity;
    
    public class MvnUser {
        private int urId;
        private String urUserName;
        private String urPassword;
        private int urAge;
        private String urStatus = Status.ACTIVE.getStatus();// Active
    
        public int getUrId() {
            return urId;
        }
    
        public void setUrId(int urId) {
            this.urId = urId;
        }
    
        public String getUrUserName() {
            return urUserName;
        }
    
        public void setUrUserName(String urUserName) {
            this.urUserName = urUserName;
        }
    
        public String getUrPassword() {
            return urPassword;
        }
    
        public void setUrPassword(String urPassword) {
            this.urPassword = urPassword;
        }
    
        public int getUrAge() {
            return urAge;
        }
    
        public void setUrAge(int urAge) {
            this.urAge = urAge;
        }
    
        public String getUrStatus() {
            return urStatus;
        }
    
        public void setUrStatus(String urStatus) {
            this.urStatus = urStatus;
        }
    }
    3)IMvnUserDAO.java 代码如下所示:
    package cn.com.mvn.ssh.demo.dao;
    
    import java.util.List;
    import cn.com.mvn.ssh.demo.entity.MvnUser;
    
    /**
    * MvnUser实体对象的持久层代码,封装了对MvnUser实体对象的CRUD方法
    *
    * @author Noble
    * @version 1.0
    */
    public interface IMvnUserDAO {
        /**
         * 在数据库中,添加一个新的MvnUser对象
         *
         * @param user 需要添加的用户实体对象,该对象需要有用户名、密码、年龄和状态属性
         *
         * @return void
         * @throws RuntimeException 添加失败或出现其它意外
         */
        public void addUser(MvnUser user);
    
        /**
         * 更新MvnUser对象。该对象中需要设置年龄、状态和id属性,属性和状态是要更新的新值,id为条件
         *
         * @param user 需要更新的MvnUser对象
         *
         * @return void
         * @throws RuntimeException 更新失败或出现其它意外
         */
        public void update(MvnUser user);
    
        /**
         * 删除MvnUser对象,该对象中需要有要删除对象的id属性,id属性为删除条件
         *
         * @param user 要删除的MvnUser对象
         *
         * @return void
         * @throws RuntimeException 删除失败或出现其它意外
         */
        public void deleteUser(MvnUser user);
    
        /**
         * 根据id查询对应的MvnUser对象
         *
         * @param id 要查询的MvnUser对象的id
         * @return MvnUser id对应的MvnUser对象,如果没有对象,返回null
         * @throws RuntimeException 出现意外情况
         */
        public MvnUser findUserById(int id);
    
        /**
         * 根据用户名查询对应的MvnUser对象
         *
         * @param userName 要查询的MvnUser对象的用户名
         * @return MvnUser 用户对应的MvnUser对象,如果没有对象,返回null
         * @throws RuntimeException 出现意外情况
         */
        public MvnUser findUserByUserName(String userName);
    
        /**
         * 查找数据库中所有的用户对象,以List集合的形式返回
         *
         * @return List<MvnUser> 所有用户对象的集合
         * @throws RuntimeException 出现意外情况
         */
        public List<MvnUser> findUsers();
    }
    右击“工程”,选择 Run As→Maven install 命令,MyEclipse 会自动将工程代码编译打包。如果没有错误,最后会以构件的形式安装在本地仓库中。结果如图 5 所示。

    为了方便公司其他开发人员使用,接下来将该项目以构件的形式发布到前面搭建好的私服。为了使发布成功,请按前面的私服介绍搭建并启动私服,同时在当前工程的 pom.xml 中,添加 distributionManagement 配置,详细参考前面的 pom.xml。具体操作和效果图如下所示。

    右击“工程”,选择 Run As→Maven build… 命令。

    在 Goals 中输入 deploy,单击 Run 按钮。

    2. 基于 Hibernate 完成 DAO 接口的实现

    团队商量确定好接口,接下来就是对接口的实现和基于接口上的开发工作了。因为有共同的接口,所以这两个工作可以同步进行。这种现象同计算机配件一样(硬盘、内存、CPU、显卡等),事先定义好标准(插口),不同厂商就可以按同样的标准各自生产,然后顺利组装在一起,不用管是哪个厂家、在哪里、用哪条流水线生产的。

    接下来介绍 DAO 接口的实现,分以下 4 步进行。

    1)创建工程,添加相关依赖

    这个步骤比较简单,创建工程的方式同以前一样,具体创建过程不重复,项目结构如图 2 所示。

    Hibernate DAO项目结构
    图 2  Hibernate DAO项目结构
    注意如下:

    ① 因为前面创建了公共的 Hibernate POM 工程,里面有描述好了 Hibernate 相关的依赖(目的是让所有开发人员重用,不再重复编写),并且以构件的形式安装发布好了。这里要体现的是怎样继承前面定义好的 pom。

    ② 同样地,因为新工程里面要实现 MvnSSHDemo.DAO 中定义的接口,并且用到里面定义的公共类,而且根据前面的介绍,MvnSSHDemo.DAO,也以构件的形式安装发布到私服中了。在这里,要介绍一下怎样在自己的工程里面设置团队内部发布的构件。

    这两点注意事项主要体现在 pom.xml 中,pom.xml 内容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <project
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
        xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>cn.com.mvn.pom</groupId>
            <artifactId>Hibernate4MySQLPOM</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <groupId>cn.com.mvn.ssh.demo.dao.hibernate</groupId>
        <artifactId>MvnSSHDemo.DAO.Hibernate</artifactId>
        <name>MvnSSHDemo.DAO.Hibernate</name>
        <url>http://maven.apache.org</url>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <dependency>
                <groupId>cn.com.mvn.ssh.demo</groupId>
                <artifactId>MvnSSHDemo.DAO</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>cn.com.mvn.pom</groupId>
                <artifactId>SpringPOM</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <type>pom</type>
            </dependency>
        </dependencies>
        <distributionManagement>
            <repository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/internal</url>
            </repository>
            <snapshotRepository>
                <id>archivaServer</id>
                <url>http://localhost:8080/repository/snapshots</url>
            </snapshotRepository>
        </distributionManagement>
    </project>
    其中 7~11 行,它描述的是当前的 pom.xml,继承了 Hibernate4-MySQLPOM 构件中定义的 pom 内容,其中 groupId、artifactId 和 version 共同形成构件的坐标。

    当 pom 需要继承别人定义好的 pom 时,只需要使用如上 parent 配置指定就行。不过这里的继承同 Java 中继承一样,只能单继承,而且只能继承 packaging 类型为 pom 的构件(这点可以看 Hibernate4MySQLPOM 中的 pom.xml 文件,里面的 packaging 是 pom)。

    20~30 行,描述的是两个依赖。第 1 个依赖是前面定义的 DAO 接口和公共类的构件依赖。通过查看代码,其实同使用从网上找的其他依赖一样。

    第 2 个虽然也是使用前面定义的 Spring 的公共 pom 依赖,但是有点不同,里面包含了一个<type>pom</type>,这个元素指定的是依赖的 packaging 类型。

    依赖的 packaging 类型默认是 jar(前面所有 pom.xml 中没有指定 type 的情况),如果 pom 引用的依赖是 pom 类型,就需要在 dependency 中添加 type 元素,指定是类型 pom,形同这里用到的第 2 个依赖,否则构建的时候会报错。

    2)编写实现代码

    基于 Hibernate 的 DAO 实现代码主要有如下几个类。

    ① MvnUser4Hibernate.java,该类继承了 MvnUser 类,里面用注解描述了实体信息,代码如下所示。
    package cn.com.mvn.ssh.demo.entity.hibernate;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import cn.com.mvn.ssh.demo.entity.MvnUser;
    
    @Entity
    @Table(catalog = "mvn_db", name = "mvn_user")
    public class MvnUser4Hibernate extends MvnUser {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "ur_id")
        public int getUrId() {
            // TODO Auto-generated method stub
            return super.getUrId();
        }
    
        @Column(name = "ur_user_name", length = 20, unique = true, nullable = false)
        public String getUrUserName() {
            // TODO Auto-generated method stub
            return super.getUrUserName();
        }
    
        @Column(name = "ur_password", length = 10, nullable = false)
        public String getUrPassword() {
            // TODO Auto-generated method stub
            return super.getUrPassword();
        }
    
        @Column(name = "ur_age")
        public int getUrAge() {
            // TODO Auto-generated method stub
            return super.getUrAge();
        }
    
        @Column(name = "ur_status", length = 20, nullable = true)
        public String getUrStatus() {
            // TODO Auto-generated method stub
            return super.getUrStatus();
        }
    }
    ② AbstractDAO.java,该类定义了实体的公共持久化方法,所有的 DAO 实现类就继承它,代码如下所示。
    package cn.com.mvn.ssh.demo.dao.hibernate;
    
    import java.io.Serializable;
    import java.lang.reflect.ParameterizedType;
    import java.util.List;
    
    import org.hibernate.Criteria;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import cn.com.mvn.ssh.demo.entity.MvnUser;
    import cn.com.mvn.ssh.demo.entity.hibernate.MvnUser4Hibernate;
    
    public abstract class AbstractDAO<PK extends Serializable, T> {
    
        private final Class<T> persistentClass;
    
        @SuppressWarnings("unchecked")
        public AbstractDAO() {
            this.persistentClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass())
                    .getActualTypeArguments()[1];
        }
    
        @Autowired
        private SessionFactory sessionFactory;
    
        protected Session getSession() {
            return sessionFactory.getCurrentSession();
        }
    
        @SuppressWarnings("unchecked")
        public T getByKey(PK key) {
            return (T) getSession().get(persistentClass, key);
        }
    
        public void persist(T entity) {
            getSession().persist(entity);
        }
    
        public void delete(T entity) {
            getSession().delete(entity);
        }
    
        public void update(T entity) {
            getSession().merge(entity);
        }
    
        public List<T> findAll() {
            Criteria cri = this.createEntityCriteria();
            cri.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);// 消除重复对象
            return cri.list();
        }
    
        protected Criteria createEntityCriteria() {
            return getSession().createCriteria(persistentClass);
        }
    }
    ③ MvnUserDAOImpl.java,该类实现了 MvnUser 实体类的所有持久化方法,代码如下所示。
    package cn.com.mvn.ssh.demo.dao.hibernate.impl;
    
    import java.util.List;
    
    import org.hibernate.Criteria;
    import org.hibernate.criterion.Restrictions;
    import org.springframework.stereotype.Repository;
    import org.springframework.transaction.annotation.Transactional;
    
    import cn.com.mvn.ssh.demo.dao.IMvnUserDAO;
    import cn.com.mvn.ssh.demo.dao.hibernate.AbstractDAO;
    import cn.com.mvn.ssh.demo.entity.MvnUser;
    import cn.com.mvn.ssh.demo.entity.hibernate.MvnUser4Hibernate;
    
    @Repository("userDAO")
    @Transactional // 标记使用事务,为了方便DAO设置,是临时的,正式事务应该设置在服务层
    public class MvnUserDAOImpl extends AbstractDAO<Integer, MvnUser4Hibernate> implements IMvnUserDAO {
    
        public void addUser(MvnUser user) {
            MvnUser4Hibernate u = this.convertToMvnUser4Hibernate(user);
            super.persist(u);
        }
    
        public void update(MvnUser user) {
            MvnUser4Hibernate u = this.convertToMvnUser4Hibernate(user);
            super.update(u);
        }
    
        public void deleteUser(MvnUser user) {
            MvnUser4Hibernate u = this.convertToMvnUser4Hibernate(user);
            super.delete(u);
        }
    
        public MvnUser findUserById(int id) {
            return super.getByKey(id);
        }
    
        public MvnUser findUserByUserName(String userName) {
            Criteria criteria = super.createEntityCriteria();
            criteria.add(Restrictions.eq("urUserName", userName));
            return (MvnUser) criteria.uniqueResult();
        }
    
        public List<MvnUser> findUsers() {
            Criteria criteria = super.createEntityCriteria();
            return criteria.list();
        }
    
        private MvnUser4Hibernate convertToMvnUser4Hibernate(MvnUser user) {
            MvnUser4Hibernate u = (MvnUser4Hibernate) this.findUserById(user.getUrId());
            // 这里不要轻易new一个同已经存在的一样的对象,否则会抛
            // org.hibernate.NonUniqueObjectException:
            // a different object with the same identifier value was
            // already associated withthe session异常
            if (u == null) {
                u = new MvnUser4Hibernate();
                u.setUrId(user.getUrId());
            }
            u.setUrAge(user.getUrAge());
            u.setUrPassword(user.getUrPassword());
            u.setUrStatus(user.getUrStatus());
            u.setUrUserName(user.getUrUserName());
            return u;
        }
    }
    ④ HibernateConfiguration.java,Hibernate 的配置类,描述 Hibernate 的配置信息,代替 hibernate.cfg.xml,代码如下所示。
    package cn.com.mvn.ssh.demo.dao.hibernate.config;
    
    import java.util.Properties;
    import javax.sql.DataSource;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.core.env.Environment;
    import org.springframework.jdbc.datasource.DriverManagerDataSource;
    import org.springframework.orm.hibernate4.HibernateTransactionManager;
    import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    //配置类
    @Configuration
    @EnableTransactionManagement // 要支持事务管理
    @ComponentScan({ "cn.com.mvn.ssh.demo.dao.hibernate.config" })
    @PropertySource(value = { "classpath:db.properties" }) // 自动读入的属性文件
    public class HibernateConfiguration {
        // 自动注入 Spring的环境对象(上下文)
        @Autowired
        private Environment environment;
    
        // 创建一个SessionFactory
        @Bean(name = "sessionFactory")
        public LocalSessionFactoryBean sessionFactory() {
            LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
            // 数据源
            sessionFactory.setDataSource(dataSource());
            // 指定数据实体类的包
            sessionFactory.setPackagesToScan(new String[] { "cn.com.mvn.ssh.demo.entity.hibernate" });
            // hibernate的属性信息
            sessionFactory.setHibernateProperties(hibernateProperties());
            return sessionFactory;
        }
    
        // 初始化数据源对象
        @Bean(name = "dataSource") // 将当前方法返回的对象,当成普通Bean对象,放入IOC容器中
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            // 设置连接数据库的四要素
            dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
            dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
            dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
            dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
            return dataSource;
        }
    
        // 将Hibernate除连接数据库之外的配置,封装到Properties
        private Properties hibernateProperties() {
            Properties properties = new Properties();
            properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
            properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
            properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
            properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
            return properties;
        }
    
        @Bean
        @Autowired
        public HibernateTransactionManager transactionManager(SessionFactory s) {
            HibernateTransactionManager txManager = new HibernateTransactionManager();
            txManager.setSessionFactory(s);
            return txManager;
        }
    }
    ⑤ db.properties,描述数据库连接信息和 Hibernate 的一些配置信息,代码如下所示。

    jdbc.username=root
    jdbc.password=root
    jdbc.url=jdbc:mysql://localhost:3306/mvn_db
    jdbc.driverClassName=com.mysql.jdbc.Driver
    hibernate.dialect = org.hibernate.dialect.MySQLDialect
    hibernate.show_sql = true
    hibernate.format_sql = true
    hibernate.hbm2ddl.auto = update

    3)编写测试代码

    测试代码基于 JUnit,相对比较简单,只有一个类,针对 MvnUserDAOImpl.java 进行测试,另外还有一个 Spring 的配置文件 applicationContext.xml。

    需要注意的是,测试的所有代码和资源文件,都分别放在 src/test 目录下对应的子目录中。在 Maven 中具体文件的存放位置是固定的。测试代码和配置文件的内容如下所示。

    ① TestMvnUserDAOImpl.java 代码如下所示:
    package cn.com.mvn.ssh.demo.dao.hibernate.impl;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.com.mvn.ssh.demo.dao.IMvnUserDAO;
    import cn.com.mvn.ssh.demo.entity.MvnUser;
    import cn.com.mvn.ssh.demo.entity.Status;
    import junit.framework.Assert;
    
    public class TestMvnUserDAOImpl {
        private IMvnUserDAO userDAO;
        private ApplicationContext ctx = null;
    
        @Before
        public void init() {
            ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            userDAO = (IMvnUserDAO) this.ctx.getBean("userDAO");
            // userDAO = (IMvnUserDAO) this.ctx.getBean(MvnUserDAOImpl.class);
        }
    
        @Test
        public void testAddUser() {
            MvnUser user = new MvnUser();
            user.setUrAge(11);
            user.setUrPassword("11");
            user.setUrStatus(Status.ACTIVE.getStatus());
            user.setUrUserName("userName11");
            this.userDAO.addUser(user);
    
            MvnUser u = this.userDAO.findUserByUserName("userName11");
            Assert.assertTrue(u != null && u.getUrAge() == 11);
            this.userDAO.deleteUser(u);
        }
    
        @Test
        public void testFindUserById() {
            MvnUser user = this.userDAO.findUserById(1);
            Assert.assertEquals("zhangsan", user.getUrUserName());
        }
    
        @Test
        public void testUpdate() {
            MvnUser user = this.userDAO.findUserById(1);
            user.setUrAge(99);
            this.userDAO.update(user);
            user = this.userDAO.findUserById(1);
            Assert.assertEquals(99, user.getUrAge());
        }
    
        @After
        public void destory() {
            this.userDAO = null;
            this.ctx = null;
        }
    }
    ② 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:mvc="http://www.springframework.org/schema/mvc"
        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.0.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.0.xsd">
        <!--spring自动扫描组件类的包,包括子包和子子包等 -->
        <context:component-scan
            base-package="cn.com.mvn.ssh.demo"></context:component-scan>
    </beans>

    4)测试安装发布

    右击“工程”,选择 Run As→Maven test 命令,Maven 会自动对 JUnit 写的测试代码进行测试,并且显示测试结果。

    右击“工程”,选择 Run As→Maven install 命令,Maven 会自动将工程代码编译,运行完测试代码,通过后,打包成构件,发布到本地仓库。

    右击“工程”,选择 Run As→Maven build… 命令,在弹出框的 Goals 输入框中输入 deploy,单击 Run 按钮,Maven 会自动将工程构件发布到指定的私服仓库。需要注意,一定要在 pom.xml 中配置 distributionManagement.

    实现 Service 模块

    同 DAO 层定义的接口类似,先将 Service 的接口定义好,并且发布成一个单独的构件,在自己的计算机上创建一个新的工程,继承 SpringPOM,集成 DAO 接口的依赖和 Service 接口的依赖,独立进行 Service 的实现代码编写和测试。

    因为要对 Service 实现方法进行测试,编码的时候可以面向接口编程。测试的时候,肯定要基于 DAO 的实现才能操作数据库。所以在测试的时候还需要额外添加前面 Hibernate 的 DAO 实现依赖,不过该依赖的 score 是 test,即只在测试的时候有效。详细情况请注意接下来介绍的工程 pom.xml 中的备注。

    下面按类似 Hibernate 的 DAO 实现的思路,介绍 Service 的实现模块。

    1)配置 pom.xml

    同之前一样,创建一个 Maven 工程,工程目录结构如图 3 所示。

    Maven Service项目结构
    图 3  Maven Service项目结构

    根据本节开始的介绍,需要在 pom.xml 中做如下设置。
    • 配置继承 SpringPOM 构件的信息(里面配置了 Spring 需要的依赖)。
    • 添加 DAO 接口构件和 Service 接口构件的依赖。
    • 添加 Hibernate DAO 实现构件的依赖,作用范围是 test。

    请查看如下 pom.xml,注意加粗部分内容和注释,细心的读者会发现里面没有添加 DAO 接口的构件依赖,只添加 Service 接口的构件依赖,同前面介绍的第 2 点要求不符合。

    原因是 Service 接口构件内部有配置好对应 DAO 接口构件的依赖,只要在这里配置 Service 接口构件的依赖,Maven 会在加载 Service 接口构件依赖的同时,自动地连带着将 Service 接口构件内部所需要的其他依赖加进来。

    pom.xml 内容如下:
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <!--继承SpringPOM构件 -->
        <parent>
            <groupId>cn.com.mvn.pom</groupId>
            <artifactId>SpringPOM</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <groupId>cn.com.mvn.ssh.demo</groupId>
        <artifactId>MvnSSHDemo.Service.impl</artifactId>
        <packaging>jar</packaging>
    
        <name>MvnSSHDemo.Service.impl</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <!--Service接口构件依赖 -->
            <dependency>
                <groupId>cn.com.mvn.ssh.demo</groupId>
                <artifactId>MvnSSHDemo.Service</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
    
            <!--Hibernate DAO实现构件依赖 -->
            <dependency>
                <groupId>cn.com.mvn.ssh.demo.dao.hibernate</groupId>
                <artifactId>MvnSSHDemo.DAO.Hibernate</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <!--作用范围 -->
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>

    2) 编写 Service 实现代码

    Service 的实现代码相对比较简单,只是要有 Spring 容器管理相关的基础,因为里面用到 Spring 内部的组件注解、依赖注入注解和事务管理注解,详情请看代码和 Spring 相关的资料。
    package cn.com.mvn.ssh.demo.service.impl;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import cn.com.mvn.ssh.demo.dao.IMvnUserDAO;
    import cn.com.mvn.ssh.demo.entity.MvnUser;
    import cn.com.mvn.ssh.demo.service.IUserService;
    
    @Service("userService") // 注册成服务组件
    @Transactional // 要求启动事务
    public class UserServiceImpl implements IUserService {
        @Autowired // 自动根据类型注入
        @Qualifier("userDAO") // 根据name注入
        private IMvnUserDAO userDAO;
    
        @Transactional(propagation = Propagation.REQUIRED) // 需要進行事务管理
        public void createUser(MvnUser user) {
            // 验证输入的用户是否为null
            if (user == null) {
                throw new RuntimeException("创建的user不能为null");
            }
            // 验证用户名是否有存在
            MvnUser u = this.userDAO.findUserByUserName(user.getUrUserName());
            if (u != null) {
                throw new RuntimeException(u.getUrUserName() + " 已经存在");
            }
            this.userDAO.addUser(user);
        }
    
        @Transactional(propagation = Propagation.REQUIRED) // 需要進行事务管理
        public void editUser(int age, String status, int id) {
            // 根据id找到以前的用户对象
            MvnUser user = this.userDAO.findUserById(id);
            // 判断用户是否存在,不存在抛异常,存在就更新
            if (user == null) {
                throw new RuntimeException("id为" + id + "用户不存在");
            } else {
                user.setUrAge(age);
                user.setUrStatus(status);
                this.userDAO.update(user);
            }
        }
    
        @Transactional(propagation = Propagation.REQUIRED) // 需要進行事务管理
        public void deleteUser(int id) {
            // 根据id找到以前的用户对象
            MvnUser user = this.userDAO.findUserById(id);
            // 判断用户是否存在,不存在抛异常,存在就删除
            if (user == null) {
                throw new RuntimeException("id为" + id + "用户不存在");
            } else {
                this.userDAO.deleteUser(user);
            }
        }
    
        @Transactional(readOnly = true) // 只读,不需要进行事务管理
        public MvnUser searchUser(int id) {
            MvnUser user = null;
            user = this.userDAO.findUserById(id);
            return user;
        }
    
        @Transactional(readOnly = true) // 只读,不需要进行事务管理
        public MvnUser searchUser(String userName) {
            MvnUser user = null;
            user = this.userDAO.findUserByUserName(userName);
            return user;
        }
    
        @Transactional(readOnly = true) // 只读,不需要进行事务管理
        public List<MvnUser> searchUsers() {
            List<MvnUser> userList = null;
            userList = this.userDAO.findUsers();
            return userList;
        }
    }

    3)编写 Service 的测试案例代码和必需的配置资源文件

    因为测试代码的测试环境是依赖 Spring 容器的,所以测试部分的内容除了有针对 UserServiceImpl.java 的测试案例类之外,还需要配置一个 applicationContext.xml。而且还要注意,不管是测试类还是测试资源,都需要放在 src/test 的对应子目录下。

    ① TestUserServiceImpl.java 代码如下所示:
    package cn.com.mvn.ssh.demo.service.impl;
    
    import java.util.List;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.com.mvn.ssh.demo.entity.MvnUser;
    import cn.com.mvn.ssh.demo.entity.Status;
    import cn.com.mvn.ssh.demo.service.IUserService;
    import junit.framework.Assert;
    
    public class TestUserServiceImpl {
        private IUserService userService;
        private ApplicationContext ctx = null;
    
        @Before
        public void init() {
            this.ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            this.userService = (IUserService) ctx.getBean("userService");
        }
    
        @Test
        public void testCreateUser() {
            MvnUser user = new MvnUser();
            user.setUrAge(11);
            user.setUrPassword("11");
            user.setUrStatus(Status.ACTIVE.getStatus());
            user.setUrUserName("service1");
            this.userService.createUser(user);
            MvnUser u = this.userService.searchUser("service1");
            boolean bool = u != null && u.getUrAge() == 11 && u.getUrStatus().equals(Status.ACTIVE.getStatus());
            Assert.assertTrue(bool);
            // 删除用户
            this.userService.deleteUser(u.getUrId());
        }
    
        @Test
        public void testEditUser() {
            MvnUser user = new MvnUser();
            user.setUrAge(11);
            user.setUrPassword("11");
            user.setUrStatus(Status.ACTIVE.getStatus());
            user.setUrUserName("service1");
            this.userService.createUser(user);
            MvnUser u = this.userService.searchUser("service1");
            this.userService.editUser(88, Status.INACTIVE.getStatus(), u.getUrId());
            u = this.userService.searchUser("service1");
            Assert.assertTrue(u.getUrAge() == 88 && u.getUrStatus().equals(Status.INACTIVE.getStatus()));
            this.userService.deleteUser(u.getUrId());
        }
    
        @Test
        public void testDeleteUser() {
            MvnUser user = new MvnUser();
            user.setUrAge(11);
            user.setUrPassword("11");
            user.setUrStatus(Status.ACTIVE.getStatus());
            user.setUrUserName("service1");
            this.userService.createUser(user);
            MvnUser u = this.userService.searchUser("service1");
            this.userService.deleteUser(u.getUrId());
            MvnUser u2 = this.userService.searchUser(u.getUrId());
            Assert.assertTrue(u != null && u2 == null);
        }
    
        @Test
        public void testSearchUserById() {
            MvnUser user = this.userService.searchUser(1);
            Assert.assertNotNull(user);
        }
    
        @Test
        public void testSearchUserByUserName() {
            MvnUser user = this.userService.searchUser("zhangsan");
            Assert.assertNotNull(user);
        }
    
        @Test
        public void testSearchUsers() {
            List<MvnUser> userList = this.userService.searchUsers();
            Assert.assertTrue(userList != null && userList.size() > 0);
        }
    
        @After
        public void destory() {
            this.userService = null;
            this.ctx = null;
        }
    }
    2)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:mvc="http://www.springframework.org/schema/mvc"
        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.0.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
        <context:component-scan base-package="cn.com.mvn.ssh.demo"/>
    </beans>

    4. 测试安装和发布

    这里的测试安装和发布同 Hibernate DAO 实现里面的一样。右击“工程”,选择 Run As→Maven test 命令。

    由于篇幅有限,请点击《Maven搭建SSH框架(二)》继续阅读。
    < 上一页Maven私服的配置和使用 Maven搭建SSH框架(二)下一页 >

    所有教程

    • socket
    • Python基础教程
    • C#教程
    • MySQL函数
    • MySQL
    • C语言入门
    • C语言专题
    • C语言编译器
    • C语言编程实例
    • GCC编译器
    • 数据结构
    • C语言项目案例
    • C++教程
    • OpenCV
    • Qt教程
    • Unity 3D教程
    • UE4
    • STL
    • Redis
    • Android教程
    • JavaScript
    • PHP
    • Mybatis
    • Spring Cloud
    • Maven
    • vi命令
    • Spring Boot
    • Spring MVC
    • Hibernate
    • Linux
    • Linux命令
    • Shell脚本
    • Java教程
    • 设计模式
    • Spring
    • Servlet
    • Struts2
    • Java Swing
    • JSP教程
    • CSS教程
    • TensorFlow
    • 区块链
    • Go语言教程
    • Docker
    • 编程笔记
    • 资源下载
    • 关于我们
    • 汇编语言
    • 大数据
    • 云计算
    • VIP视频

    优秀文章

    • C++ deque,STL deque(双向队列详解)
    • Java快速排序法(Quicksort)
    • Java反射在类中的应用:通过反射执行方法(获取方法)
    • Qt QString类及常用函数功能详解
    • 到底什么时候会调用拷贝构造函数?
    • Python Pygal模块安装和使用
    • Spark总体架构和运行流程
    • Python split()方法详解:分割字符串
    • Hibernate isNotNull方法:判断是否不为null
    • Java数据类型:基本数据类型和引用数据类型

    精美而实用的网站,提供C语言、C++、STL、Linux、Shell、Java、Go语言等教程,以及socket、GCC、vi、Swing、设计模式、JSP等专题。

    底部Logo ↑