springcloud(一)

springcloud(一),第1张

目录

一、搭建父类工程

解析父工程中pom文件的标签:

二、搭建基础模块

Spring Data Jpa的作用

对Order类的解释:

三、搭建用户微服务模块

   一、创建pom.xml,继承父工程,依赖common模块

   二、配置文件内容如下:

四、搭建商品模块

一、配置文件

二、pom文件

三、项目结构

一、启动类(不要忘了扫描entity实体类)

二、控制层(@slf4j注解、@PathVariable的作用)

三、接口层

四、实现类与dao接口

疑问点一:为什么dao接口中并没有任何的方法,但是还是可以调用findById方法?

疑问点二:为什么接口调用方法后还需要调用get( )方法?

​五、搭建订单模块(跟商品模块差不多)

一、pom配置文件

二、项目启动配置文件

三、项目结构

​一、启动类

二、控制层(restTemplate调用product模块的方法)

三、接口层

四、实现类层

思考:为什么项目启动后数据库里面就会自动创建表呢?


一、搭建父类工程

也就是上图所示的shop-parent模块,创建maven项目后将src文件夹删除。

配置pom依赖:将打包方式设置为pom。

为什么要设置为pom?

 

pom.xml文件:

解析父工程中pom文件的标签:

properties:用于统一管理jar包版本

dependencyManagement:子模块继承之后,提供作用:锁定版本+子module不用写groupId和version

将单独的某个依赖设置为pom的作用:

import解决Maven项目单继承问题_明快de玄米61的博客-CSDN博客">使用import解决Maven项目单继承问题_明快de玄米61的博客-CSDN博客



    4.0.0

    com.lay
    shop-parent
    1.0-SNAPSHOT
    
        shop-common
        shop-user
        shop-product
        shop-order
    
    pom
    
    
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.3.RELEASE
    

    
        1.8
        UTF-8
        UTF-8
        Greenwich.RELEASE
        2.1.0.RELEASE
    

    

        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            

            
                com.alibaba.cloud
                spring-cloud-alibaba-dependencies
                ${spring-cloud-alibaba.version}
                pom
                
                import
            

        

    

二、搭建基础模块

创建 shop-common 模块(打包方式为jar),在pom.xml中添加依赖

 




    
        shop-parent
        com.lay
        1.0-SNAPSHOT
    

    4.0.0
    shop-common
    jar

    
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-test
        
        
            org.projectlombok
            lombok
        
        
            com.alibaba
            fastjson
            1.2.56
        
        
            mysql
            mysql-connector-java
            5.1.6
        
        
            junit
            junit
            test
        
    

Spring Data Jpa的作用

在JPA规范基础下提供了 Repository 层的实现 , 能够方便大家在不同的ORM框架之间进行切换而不要更改代码 .

PS : 我们用不同的ORM框架 , 在DAO层写业务代码会稍微有差异 , SpringDataJPA 就是为了解决这个出现的.

ORM:通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质就是将数据从一种形式转换到另外一种形式。

在实际的工程中,推荐采用Spring Data JPA + ORM(如:Hibernate)进行开发,这样在切换不同的ORM提供了方面,同时也使得Repository变得简单。程序低耦合。

MyBatis不是ORM框架,MyBatis只是将数据库中的内容映射为实体。没有将实体映射为数据库中的字段。

common层的结构:

对Order类的解释:

 使用@Entity去注释实体类时,需import javax.persistence.Entity

javax.persistence位于hibernate-jpa-**.jar包里面。

@Entity是指这个类映射到数据库表, 当你不使用这个类(被注解的类)时,后台不会对其进行处理,只有当你从数据库读取数据时,由于你要读取的表映射有实体类(被@Entity注释的), 那么后台应该会自动帮你实例化一个对象, 然后将数据库中的数据填充到对象中!

@Entity定义的对象将会成为被JPA管理的实体,将映射到指定的数据库表。

 @GeneratedValue

           指定主键的生成策略。有如下四个值

 -AUTO主键由程序控制, 是默认选项 ,不设置就是这个

 -IDENTITY 主键由数据库生成, 采用数据库自增长, Oracle不支持这种方式
 
  -SEQUENCE 通过数据库的序列产生主键, MYSQL  不支持
 
  -Table 提供特定的数据库产生主键, 该方式更有利于数据库的移植

package com.lay.shop.entity;
import lombok.Data;
import javax.persistence.*;

//订单
//表明当前的类是实体类(与表对应的类),那么的值就是表名
@Entity(name = "shop_order")
@Data
public class Order {
    //id表示是主键
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)//主键值自动生成
    private Long oid;//订单id
    //当表的列名和属性名不同必须加column注解
    @Column(name = "uid")
    private Integer uid;//用户id
    private String username;//用户名
    private Integer pid;//商品id
    private String pname;//商品名称
    private Double pprice;//商品单价
    private Integer number;//购买数量
}

三、搭建用户微服务模块    一、创建pom.xml继承父工程,依赖common模块    二、配置文件内容如下:
  •  配置端口号和数据库

server:
  port: 8071
spring:
  application:
    name: service-user
    datasource:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/shop?serverTimezone=Asia/Shanghai
      username: root
      password: abc123
      #解决时差问题
      jackson:
        date-format: yyyy-MM-dd HH:mm:ss
        time-zone: GMT+8

四、搭建商品模块 一、配置文件
server:
  port: 8081
spring:
  application:
    name: service-product
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shop?serverTimezone=Asia/Shanghai
    username: root
    password: abc123
    #解决时差问题
    jackson:
      date-format: yyyy-MM-dd HH:mm:ss
      time-zone: GMT+8

  jpa:
    properties:
      hibernate:
        hbm2ddl:
          #在项目启动时会检查对应的数据库中的表是否存在(依据实体类),如果不存在就创建!
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
二、pom文件


    
        shop-parent
        com.lay
        1.0-SNAPSHOT
    
    4.0.0
    shop-product

    
        
            com.lay
            shop-common
            1.0-SNAPSHOT
        

    

三、项目结构

一、启动类(不要忘了扫描entity实体类)
/**
 * @author Dragon code!
 * @create 2022-05-04 15:36
 */
@SpringBootApplication
@EntityScan(basePackages = "com.lay.shop.entity")
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class);
    }
}
二、控制层(@slf4j注解、@PathVariable的作用、@Entity)

想看entity可以看上面,这里能得到product对象全靠Entity注解!(因为这里是hibernate框架)

package com.lay.shop.porduct.controller;

import com.alibaba.fastjson.JSON;
import com.lay.shop.entity.Product;
import com.lay.shop.porduct.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author Dragon code!
 * @create 2022-05-04 15:47
 */
@RestController
//此注解来自于lombok
//用于生成log对象
@Slf4j
public class ProductController {
    @Resource
    private ProductService productService;
    @RequestMapping("/product/{pid}")
    //@PathVariable可以用来映射URL中的占位符到目标方法的参数中
    public Product findByPid(@PathVariable("pid") Integer pid){
        Product product = productService.findByPid(pid);
        log.info("查询结果:"+ JSON.toJSONString(product));
        return productService.findByPid(pid);
    }
}
三、接口层
/**
 * @author Dragon code!
 * @create 2022-05-04 15:42
 */
public interface ProductService {
    Product findByPid(Integer pid);
}
四、实现类与dao接口
/**
 * @author Dragon code!
 * @create 2022-05-04 15:39
 */
//泛型的第二个参数是实体类中主键的名称
public interface ProductDao extends JpaRepository {
}

/**
 * @author Dragon code!
 * @create 2022-05-04 15:43
 */
@Service
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductDao productDao;

    @Override
    public Product findByPid(Integer pid) {
        return productDao.findById(pid).get();
    }
}
疑问点一:为什么dao接口中并没有任何的方法,但是还是可以调用findById方法?


 答:其实是跟之前使用的通用mapper是一个道理,此时的dao接口继承于JpaRepository

        那么该接口的泛型第一个参数为要 *** 作的实体类,第二个参数为该实体类的主键类型

疑问点二:为什么接口调用方法后还需要调用get( )方法?

Spring Data JPA中的getOne,findOne以及findById_Tiger_Paul的博客-CSDN博客
答:其实通过jpa模板方法得到的结果是Optional类型的对象

       Java中的java.util.Optional类的get()方法用于获取此Optional实例的值

     (也就是泛型指定的实体类的对象)

如果此Optional实例中不存在任何值,则此方法将引发NullPointerException。
 

启动项目:查看是否正常执行(成功)




五、搭建订单模块(跟商品模块差不多) 一、pom配置文件


    
        shop-parent
        com.lay
        1.0-SNAPSHOT
    
    4.0.0
    shop-order

   
       
           com.lay
           shop-common
           1.0-SNAPSHOT
       
   

二、项目启动配置文件
server:
  port: 8091
spring:
  application:
    name: service-order
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shop?serverTimezone=Asia/Shanghai
    username: root
    password: abc123
    #解决时差问题
    jackson:
      date-format: yyyy-MM-dd HH:mm:ss
      time-zone: GMT+8

  jpa:
    properties:
      hibernate:
        hbm2ddl:
          #在项目启动时会检查对应的数据库中的表是否存在(依据实体类),如果不存在就创建!
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

三、项目结构


一、启动类
  • 同样是别忘了扫描实体类。
  • 项目集成restTemplate模板所以启动类添加初始化方法,并将其交给容器管理,达到一启动项目就创建对象的效果
/**
 * @author Dragon code!
 * @create 2022-05-04 16:43
 */
@SpringBootApplication
@EntityScan(basePackages = "com.lay.shop.entity")
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

二、控制层(restTemplate调用product模块的方法)

注入restTemplate模板对象

作用是可以直接在后台发出基于http协议的rest风格的请求


那么控制层要做的是通过rest请求传id查询到一个product的对象,然后将其封装order对象里面,其他信息随便给,模拟产生订单!

重点在于getForObject方法()

一是请求,而是返回值的类型

/**
 * @author Dragon code!
 * @create 2022-05-04 16:46
 */
@RestController
@Slf4j
public class OrderController {
    @Resource
    private OrderService orderService;
    @Resource
    //可以发出基于http协议的rest风格的请求
    private RestTemplate restTemplate;
    @RequestMapping("/order/prod/{pid}")
    public Order save(@PathVariable Integer pid){
        log.info("准备调用商品服务查询商品信息");
        Product product = restTemplate.getForObject("http://localhost:8081/product/" + pid, Product.class);
        log.info("商品微服务返回的商品"+ JSON.toJSONString(product));
        log.info("创建订单对象");
        Order order = new Order();
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
        order.setPid(product.getPid());
        order.setUsername("测试用户");
        orderService.save(order);
        return order;
    }
}


三、接口层
/**
 * @author Dragon code!
 * @create 2022-05-04 16:44
 */
public interface OrderService {
    void save(Order order);
}

四、实现类层
/**
 * @author Dragon code!
 * @create 2022-05-04 16:45
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderDao orderDao;
    @Override
    public void save(Order order) {
        orderDao.save(order);
    }
}

同样的mapper层是利用的jpa的方法

/**
 * @author Dragon code!
 * @create 2022-05-04 16:44
 */
public interface OrderDao extends JpaRepository {
}

最后效果:成功访问

数据插入成功

思考:为什么项目启动后数据库里面就会自动创建表呢?

@Entity注解配合项目启动配置文件中的jpa配置达到底层采用hibernate根据实体类建表的效果!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/872172.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存