idea创建多模块项目

280 阅读4分钟

创建父项目

#使用spring initializr创建项目
#勾选依赖:
Developer Tools
    Spring Boot DevTools
    Lombok
Web
    Spring Web
SQL
    JDBC API
    Spring Data JPA
    MySQL Driver
#修改项目打包方式
<packaging>pom</packaging>
#把java目录移到web模块下,项目启动由web模块进行管理
#删除没用的文件夹及文件
src、.mvn、.gitignore、mvnw、mvnw.cmd

创建web子模块

#New Module,不选择模板,选择父项目
#在父项目的pom文件中会自动添加模块信息
<modules>
    <module>demo-web</module>
</modules>
#pom文件添加打包方式
<packaging>jar</packaging>#同理添加entity、service、serviceImpl、dao子模块

修改项目依赖

#将各子模块作为依赖,引入到项目中(没有引入web模块,因为web模块会依赖其他模块,但是其他模块不会依赖web模块)
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>com.example</groupId>
			<artifactId>demo-entity</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.example</groupId>
			<artifactId>demo-service</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.example</groupId>
			<artifactId>demo-serviceImpl</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.example</groupId>
			<artifactId>demo-dao</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</dependencyManagement>
注:dependencyManagement对依赖进行管理,可以使子模块在引用管理中的依赖时,不用再设置版本号。
#修改web模块pom文件
<dependencies>
	<dependency>
		<groupId>com.example</groupId>
		<artifactId>demo-entity</artifactId>
	</dependency>
	<dependency>
		<groupId>com.example</groupId>
		<artifactId>demo-service</artifactId>
	</dependency>
	<dependency>
		<groupId>com.example</groupId>
		<artifactId>demo-serviceImpl</artifactId>
	</dependency>
</dependencies>
#修改service模块pom文件
<dependencies>
	<dependency>
		<groupId>com.example</groupId>
		<artifactId>demo-entity</artifactId>
	</dependency>
</dependencies>
#修改serviceImpl模块文件
<dependencies>
	<dependency>
		<groupId>com.example</groupId>
		<artifactId>demo-entity</artifactId>
	</dependency>
	<dependency>
		<groupId>com.example</groupId>
		<artifactId>demo-dao</artifactId>
	</dependency>
	<dependency>
		<groupId>com.example</groupId>
		<artifactId>demo-service</artifactId>
	</dependency>
</dependencies>
#修改entity和dao模块pom
<dependencies>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<scope>runtime</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-jdbc</artifactId>
	</dependency>
</dependencies>
注:同时删除父项目对应数据库相关依赖,由于父项目中设置的依赖,子模块中会自动继承,无需重复引用,但是并不是每个子模块都会需要连接和操作数据库的依赖,故将其删除。

修改启动配置

由于项目是从web模块启动,所以需要添加build配置
<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<excludes>
					<exclude>
						<groupId>org.projectlombok</groupId>
						<artifactId>lombok</artifactId>
					</exclude>
				</excludes>
			</configuration>
		</plugin>
	</plugins>
</build>
注:删除父项目中对应的build配置

编写代码

#entity模块代码
package com.example.entity.common;
import lombok.Data;
@Data
public class Response<T> {
    private int coce;
    private String message;
    private T data;
    public Response(int coce, String message, T data) {
        this.coce = coce;
        this.message = message;
        this.data = data;
    }
}

package com.example.entity;
import lombok.Data;
import javax.persistence.*;
import java.sql.Timestamp;
@Data
@Entity
@Table(name = "stuinfo")
public class StuInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;//id,键值,自增
    private int stu_id;//学生id
    private String name;//姓名
    private int gender;//性别
    private int age;//年龄
    private int grade_num;//年级
    private int class_num;//班级
    private int status;//状态,1-数据有效,2-数据删除
    private Timestamp createtime;//创建时间
    private Timestamp updatetime;//更新时间
}

#dao模块代码
package com.example.dao;
import com.example.entity.StuInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface StuInfoDao extends JpaRepository<StuInfo,Long> {
}

#service模块代码
package com.example.service;
import com.example.entity.StuInfo;
public interface StuService {
    Boolean save(StuInfo stuInfo);
}
#serviceImpl模块代码
package com.example.serviceImpl;
import com.example.dao.StuInfoDao;
import com.example.entity.StuInfo;
import com.example.service.StuService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
@Service
@Log4j2
public class StuServiceImpl implements StuService {
    @Autowired
    private StuInfoDao stuInfoDao;
    @Override
    public Boolean save(StuInfo stuInfo) {
        stuInfo.setStatus(1);
        stuInfo.setCreatetime(new Timestamp(System.currentTimeMillis()));
        stuInfo.setUpdatetime(new Timestamp(System.currentTimeMillis()));
        stuInfoDao.save(stuInfo);
         return Boolean.TRUE;
    }
}
注:
@Service,标注该类为接口实现类,可供spring扫描注入
@Log4j2,日志工具
@Autowired,将StuInfoDao进行注入

#web模块代码
package com.example.demoparent.controllor;
import com.example.entity.StuInfo;
import com.example.entity.common.Response;
import com.example.service.StuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/stu")
public class StuInfoControllor {
    @Autowired
    private StuService stuService;

    @PostMapping("/addStu")
    public Response<Boolean> addStu(@RequestBody StuInfo stuInfo) {
        if (stuService.save(stuInfo)) {
            return new Response<>(200, "保存成功", Boolean.TRUE);
        } else {
            return new Response<>(400, "保存失败", Boolean.FALSE);
        }
    }
}
application.yml
spring:
  profiles:
    active: dev
application-dev.yml
server:
  port: 8081

spring:
  datasource:
    #url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&serverTimezone=UTC
    #url: jdbc:mysql://localhost:3306/demo_db?serverTimezone=UTC&useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true
    username: root
    password: root_123

  jpa:
    database: mysql
    show-sql: true
    hibernate:
      ddl-auto: create
      naming:
        implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

修改启动类****DemoParentApplication

package com.example.demoparent;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication(scanBasePackages = "com.example")
//@SpringBootApplication(scanBasePackages = "com.example",exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
@ComponentScan({"com.example"})
@EnableJpaRepositories("com.example")
@EntityScan("com.example.entity")
public class DemoParentApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoParentApplication.class, args);
    }
}
注:
在Springboot应用开发中使用JPA时,通常在 程序启动类 所在包或者其子包的某个位置定义我们的Entity 和 Repository,这样基于Springboot的自动配置,无需额外配置,我们定义的Entity和Repository即可被发现和使用。
@EntityScan 用来扫描和发现指定包及其子包中的Entity定义。其用法如下:
@EntityScan(basePackages = {"com.department.entities","come.employee.entities"})
如果多处使用@EntityScan,它们的basePackages 集合能覆盖所有被Repository使用的Entity即可,集合有交集也没有关系。但是如果不能覆盖被Repository使用的Entity,应用程序启动是会出错,比如:
Not a managed type: com.customer.entities.Customer

@EnableJpaRepositories 用来扫描和发现指定包及其子包中的 Repository 定义。其用法如下:
@EnableJpaRepositories(basePackages = {"com.department.repositories","come.employee.repositories"})
如果多处使用@EnableJpaRepositories,它们的basePackages集合不能有交集,并且要能覆盖所有需要的Repository定义。
如果有交集,相应的Repository会被尝试反复注册,从而遇到如下错误:
The bean ‘OrderRepository’, defined in xxx, could not be registered. A bean with that name has already been defined in xxx and overriding is disabled.
如果不能覆盖所有需要的Repository定义,会遇到启动错误:
Parameter 0 of method setCustomerRepository in com.service.CustomerService required a bean of type ‘come.repo.OrderRepository’ that could not be found.

清理、安装、运行、测试

clean-install-run/debug
postman:http://localhost:8081/stu/addStu
{    "id": "1",    "stu_id": "2",    "age": "3",    "class_num": "4",    "gender": "5",    "grade_num": "6",    "name": "7"}

遇到的问题

application.yml需要放在启动项目,不然编译不被识别

参考文献

https://www.jb51.net/article/210892.htm