基于maven,构建父子项目

一直想用maven建立一个父子项目,对现有的架构进行重构一下,减少代码的耦合度,直到冗余的代码越来越多,维护得有些吃力了,才痛下决心,把这个项目建立起来。

环境说明

开发工具:Spring Tool Suite 3.8.3.RELEASE
org.springframework.boot 2.1.4.RELEASE
开发环境jdk、maven路径等等,一定要提前配置好了。

架构说明

实体类、Dao层、Service层、Controller层、公共类、管理后台、前台等各为一个项目。
目的:实现实体类、Dao层、Service层、公共类代码复用,管理后台、前台不再只需维护一套以上的代码,减少维护的压力。

第一步,file->new maven project,建立父项目。
图-1

图-2

删除父项目下的src文件,只留pom文件。


图-3
pom文件的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<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>
  <!-- 指定依赖关系 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.example</groupId>
  <artifactId>example-root</artifactId>
  <version>0.0.1-SNAPSHOT</version>  
  <!-- 父项目的packaging必须为pom -->
  <packaging>pom</packaging>
  <name>这是一个父项目</name>
  <description>所有子项目的父项目</description>  
  <properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!-- 依赖的架包 -->
    <dependencies>
        
    </dependencies> 
  <!-- 子模块 -->
  <modules>    
  </modules>
</project>
第二步建立子项目,选中父项目,点击右键,选择 other,在other里面选择maven moudle,然后next,最后finish。
图-4

图-5

这时,建成的子项目已经在父项目之中了。


图-6

从父项目的pom中可以看到,已经把子项目生成进去了。
图-7

打开子项目的pom文件,有些冗余的内容,就删掉了一些,只留必要的。

<?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>com.example</groupId>
    <artifactId>example-root</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>example-entity</artifactId>
  <name>example-entity</name>
  <packaging>jar</packaging>
  <url>http://maven.apache.org</url>  
  <dependencies>
  </dependencies>
  <build>
    <finalName>example-entity</finalName>
  </build>
</project>

就这样,以此类推,把其他需要的项目也创建好了。


图-8
第三步,项目建立好,就是项目之间的关系,对于example-service是需要调用example-dao和example-entity中的类的,这时只需要在pom以架包的形式引入即可。
<dependency>
       <groupId>com.example</groupId>
    <artifactId>example-dao</artifactId>
    <version>0.0.1-SNAPSHOT</version>
 </dependency>
 <dependency>
        <groupId>com.example</groupId>
    <artifactId>example-entity</artifactId>
    <version>0.0.1-SNAPSHOT</version>
 </dependency>

对于每个项目都需要的架包,则在父类中引入,如果架包只是某一个项目中才用到的,就只需要在用到的项目中引入即可。
这时最后生成的项目的结构,也就是父子项目。


图-9
第四步,把每个项目中的代码完善一下。

1)连接数据库的配置文件,放在了common项目中。

import javax.sql.DataSource;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
@MapperScan("com.example.dao")
public class DruidDatabaseConfig {

    /**
     * DruidDataSource数据源中默认的是取druid开头的,所以这里需要设置一下前缀prefix
     * 使用com.alibaba的DruidDataSource数据源
     * @return
     *
     */
    @Bean
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource dataSource() {
        return new DruidDataSource();        
    }
}

2)增加配置文件:

spring.datasource.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.entity

pom文件如下:

<?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>com.example</groupId>
    <artifactId>example-root</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>example-common</artifactId>
  <name>example-common</name>
  <packaging>jar</packaging>
  <url>http://maven.apache.org</url>  
  <dependencies>  
  </dependencies>
  <build>
    <finalName>example-common</finalName>
  </build>
</project>

service项目,一个接口,一个实现类;

import java.util.List;
import com.example.entity.Test;

public interface ITestService {

    public void addTest(Test test);
    
    public void updateTest(Test test);
    
    public Test getTest(Test test);
    
    public List<Test> findTests();
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.dao.TestMapper;
import com.example.entity.Test;
import com.example.service.ITestService;

@Service("testServiceImpl")
public class TestServiceImpl implements ITestService {

    @Autowired
    private TestMapper testMapper;
    
    @Override
    public void addTest(Test test) {
        testMapper.insertSelective(test);
    }

    @Override
    public void updateTest(Test test) {
        testMapper.updateByPrimaryKeySelective(test);
    }

    @Override
    public Test getTest(Test test) {
        return testMapper.selectByPrimaryKey(test.getUserUid());
    }

    @Override
    public List<Test> findTests() {
        return null;
    }

}

dao项目,一个mapper类,一个mapper.xml配置文件,特别是xml文件,里面的类名对象名都要写对。这两个文件也有可能是工具生成的,生成的时候,包名一定要设置对了。

import com.example.entity.Test;

public interface TestMapper {
    
    int deleteByPrimaryKey(String userUid);

    int insert(Test record);

    int insertSelective(Test record);

    Test selectByPrimaryKey(String userUid);

    int updateByPrimaryKeySelective(Test record);

    int updateByPrimaryKey(Test record);
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.dao.TestMapper">
  <resultMap id="BaseResultMap" type="com.example.entity.Test">
    <id column="user_uid" jdbcType="VARCHAR" property="userUid" />
    <result column="create_date" jdbcType="DATE" property="createDate" />
    <result column="create_user" jdbcType="VARCHAR" property="createUser" />
    <result column="status" jdbcType="TINYINT" property="status" />
    <result column="update_date" jdbcType="DATE" property="updateDate" />
    <result column="update_user" jdbcType="VARCHAR" property="updateUser" />
    <result column="user_mobile" jdbcType="VARCHAR" property="userMobile" />
    <result column="user_name" jdbcType="VARCHAR" property="userName" />
    <result column="user_pwd" jdbcType="VARCHAR" property="userPwd" />
    <result column="user_birthday" jdbcType="DATE" property="userBirthday" />
  </resultMap>
  <sql id="Base_Column_List">
    user_uid, create_date, create_user, status, update_date, update_user, user_mobile, 
    user_name, user_pwd, user_birthday
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from t_test
    where user_uid = #{userUid,jdbcType=VARCHAR}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
    delete from t_test
    where user_uid = #{userUid,jdbcType=VARCHAR}
  </delete>
  <insert id="insert" parameterType="com.example.entity.Test">
    insert into t_test (user_uid, create_date, create_user, 
      status, update_date, update_user, 
      user_mobile, user_name, user_pwd, 
      user_birthday)
    values (#{userUid,jdbcType=VARCHAR}, #{createDate,jdbcType=DATE}, #{createUser,jdbcType=VARCHAR}, 
      #{status,jdbcType=TINYINT}, #{updateDate,jdbcType=DATE}, #{updateUser,jdbcType=VARCHAR}, 
      #{userMobile,jdbcType=VARCHAR}, #{userName,jdbcType=VARCHAR}, #{userPwd,jdbcType=VARCHAR}, 
      #{userBirthday,jdbcType=DATE})
  </insert>
  <insert id="insertSelective" parameterType="com.example.entity.Test">
    insert into t_test
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="userUid != null">
        user_uid,
      </if>
      <if test="createDate != null">
        create_date,
      </if>
      <if test="createUser != null">
        create_user,
      </if>
      <if test="status != null">
        status,
      </if>
      <if test="updateDate != null">
        update_date,
      </if>
      <if test="updateUser != null">
        update_user,
      </if>
      <if test="userMobile != null">
        user_mobile,
      </if>
      <if test="userName != null">
        user_name,
      </if>
      <if test="userPwd != null">
        user_pwd,
      </if>
      <if test="userBirthday != null">
        user_birthday,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="userUid != null">
        #{userUid,jdbcType=VARCHAR},
      </if>
      <if test="createDate != null">
        #{createDate,jdbcType=DATE},
      </if>
      <if test="createUser != null">
        #{createUser,jdbcType=VARCHAR},
      </if>
      <if test="status != null">
        #{status,jdbcType=TINYINT},
      </if>
      <if test="updateDate != null">
        #{updateDate,jdbcType=DATE},
      </if>
      <if test="updateUser != null">
        #{updateUser,jdbcType=VARCHAR},
      </if>
      <if test="userMobile != null">
        #{userMobile,jdbcType=VARCHAR},
      </if>
      <if test="userName != null">
        #{userName,jdbcType=VARCHAR},
      </if>
      <if test="userPwd != null">
        #{userPwd,jdbcType=VARCHAR},
      </if>
      <if test="userBirthday != null">
        #{userBirthday,jdbcType=DATE},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.example.entity.Test">
    update t_test
    <set>
      <if test="createDate != null">
        create_date = #{createDate,jdbcType=DATE},
      </if>
      <if test="createUser != null">
        create_user = #{createUser,jdbcType=VARCHAR},
      </if>
      <if test="status != null">
        status = #{status,jdbcType=TINYINT},
      </if>
      <if test="updateDate != null">
        update_date = #{updateDate,jdbcType=DATE},
      </if>
      <if test="updateUser != null">
        update_user = #{updateUser,jdbcType=VARCHAR},
      </if>
      <if test="userMobile != null">
        user_mobile = #{userMobile,jdbcType=VARCHAR},
      </if>
      <if test="userName != null">
        user_name = #{userName,jdbcType=VARCHAR},
      </if>
      <if test="userPwd != null">
        user_pwd = #{userPwd,jdbcType=VARCHAR},
      </if>
      <if test="userBirthday != null">
        user_birthday = #{userBirthday,jdbcType=DATE},
      </if>
    </set>
    where user_uid = #{userUid,jdbcType=VARCHAR}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.example.entity.Test">
    update t_test
    set create_date = #{createDate,jdbcType=DATE},
      create_user = #{createUser,jdbcType=VARCHAR},
      status = #{status,jdbcType=TINYINT},
      update_date = #{updateDate,jdbcType=DATE},
      update_user = #{updateUser,jdbcType=VARCHAR},
      user_mobile = #{userMobile,jdbcType=VARCHAR},
      user_name = #{userName,jdbcType=VARCHAR},
      user_pwd = #{userPwd,jdbcType=VARCHAR},
      user_birthday = #{userBirthday,jdbcType=DATE}
    where user_uid = #{userUid,jdbcType=VARCHAR}
  </update>
</mapper>
第五步,测试。

在Controller项目中,新建了一个测试文件:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.entity.Test;
import com.example.service.ITestService;

@RestController
public class TestController {
    
    @Autowired
    private ITestService testServiceImpl;

    @GetMapping("/index")
    public Object index(){
        Test test = new Test();
        test.setUserUid("20190724");
        test.setUserName("teststest");
        testServiceImpl.addTest(test);
        return test;
    }
    
    @GetMapping("/index1")
    public Object index1(){
        Test test = new Test();
        test.setUserUid("20190724");
        test = testServiceImpl.getTest(test);
        return test;
    }
}

测试结果图

总结:
在建立父子项目时,由于包名写错了,报service或mapper找不到的问题,这时,只要根据错误信息对报错的包进行修改就可以了。

父子项目,可以很好地实现对代码的复用,特别是像实体类、service层、工具类的复用。

使用工具生成的文件,一定要制定核对pom文件,pom文件生成时,有时会漏掉一些参数,这个还需要找一篇范文来比对一下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355