首页 > 技术文章 > SpringDataJpa 应用

BoofieWoo 2020-08-16 08:35 原文

SpringDataJpa

1.导入pom依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2.配置yml文件

spring:
application:
  name: ihrm-company
datasource:
  url: jdbc:mysql://localhost:3306/xxxx?serverTimezone=GMT%2B8
  driver-class-name: com.mysql.cj.jdbc.Driver
  username: root
  password: root
   
jpa:
    database: MySQL
    show-sql: true
    open-in-view: true

3.编写实体类

/**
* lombok 插件 : 使用注解的形式替换getter setter,构造方法
* 如何使用插件
* 1.安装插件(在工程中引入响应的插件坐标即可)
* <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
  <version>1.16.16</version>
    </dependency>
* 2.使用注解配置
*   配置到实体类上
*   @setter     : setter方法
*   @getter     :getter方法
*   @NoArgsConstructor   无参构造
*   @AllArgsConstructor 满参构造
*   @Data       : setter,getter,构造方法
*
* 使用jpa操作数据
* 配置实体类和数据库表的映射关系:jpa注解
* 1.实体类和表的映射关系
* 2.字段和属性的映射关系
* i。主键属性的映射
* ii。普通属性的映射
*/
@Entity
@Table(name = "t_表名")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
   @Id
   private String id;
   private String name;
   private Integer age;
   @JsonFormat(pattern = "yyyy-MM-dd")
   private Date bitth;
}

4.在启动类里添加注解:@EntityScan("com.xxx.entity")

在数据库中创建yml中连接的数据库xxxx,启动主启动类,会自动在xxxx下创建--“t_表名”的表

5.使用教程

创建接口,以访问数据库

public interface UserDao extends JpaRepository<User,String>,JpaSpecificationExecutor<User>{
}

6.创建service接口,供controller进行CRUD访问数据库

@Service
public class UserService {
   @Resource
   private UserDao userDao;

   public User findOne(String id){
       return userDao.findById(id).get();
  }
   public void deleteById(String id){
       userDao.deleteById(id);
  }
   public void update(User user){
       User temp = userDao.findById(user.getId()).get();
       BeanUtils.copyProperties(user,temp);
       userDao.save(temp);
  }
   public List<User> findAll(){
       return userDao.findAll();
  }
   public void save(User user){
       user.setId(IdWorker.generateID());
       user.setAuditState("0");
       user.setState(0);
       userDao.save(user);
  }

}

注解:由于Jpa 未能自动提供主键生成策略,可以采用雪花算法(Snowflake)进行补充,创建utils.IdWorker

//雪花算法代码实现
public class IdWorker {
   // 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
   private final static long twepoch = 1288834974657L;
   // 机器标识位数
   private final static long workerIdBits = 5L;
   // 数据中心标识位数
   private final static long datacenterIdBits = 5L;
   // 机器ID最大值
   private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
   // 数据中心ID最大值
   private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
   // 毫秒内自增位
   private final static long sequenceBits = 12L;
   // 机器ID偏左移12位
   private final static long workerIdShift = sequenceBits;
   // 数据中心ID左移17位
   private final static long datacenterIdShift = sequenceBits + workerIdBits;
   // 时间毫秒左移22位
   private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

   private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
   /* 上次生产id时间戳 */
   private static long lastTimestamp = -1L;
   // 0,并发控制
   private long sequence = 0L;

   private final long workerId;
   // 数据标识id部分
   private final long datacenterId;

   public IdWorker(){
       this.datacenterId = getDatacenterId(maxDatacenterId);
       this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
  }
   /**
    * @param workerId
    *           工作机器ID
    * @param datacenterId
    *           序列号
    */
   public IdWorker(long workerId, long datacenterId) {
       if (workerId > maxWorkerId || workerId < 0) {
           throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
      }
       if (datacenterId > maxDatacenterId || datacenterId < 0) {
           throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
      }
       this.workerId = workerId;
       this.datacenterId = datacenterId;
  }
   /**
    * 获取下一个ID
    *
    * @return
    */
   public synchronized long nextId() {
       long timestamp = timeGen();
       if (timestamp < lastTimestamp) {
           throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
      }

       if (lastTimestamp == timestamp) {
           // 当前毫秒内,则+1
           sequence = (sequence + 1) & sequenceMask;
           if (sequence == 0) {
               // 当前毫秒内计数满了,则等待下一秒
               timestamp = tilNextMillis(lastTimestamp);
          }
      } else {
           sequence = 0L;
      }
       lastTimestamp = timestamp;
       // ID偏移组合生成最终的ID,并返回ID
       long nextId = ((timestamp - twepoch) << timestampLeftShift)
               | (datacenterId << datacenterIdShift)
               | (workerId << workerIdShift) | sequence;

       return nextId;
  }

   private long tilNextMillis(final long lastTimestamp) {
       long timestamp = this.timeGen();
       while (timestamp <= lastTimestamp) {
           timestamp = this.timeGen();
      }
       return timestamp;
  }

   private long timeGen() {
       return System.currentTimeMillis();
  }

   /**
    * <p>
    * 获取 maxWorkerId
    * </p>
    */
   protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
       StringBuffer mpid = new StringBuffer();
       mpid.append(datacenterId);
       String name = ManagementFactory.getRuntimeMXBean().getName();
       if (!name.isEmpty()) {
           /*
            * GET jvmPid
            */
           mpid.append(name.split("@")[0]);
      }
       /*
        * MAC + PID 的 hashcode 获取16个低位
        */
       return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
  }

   /**
    * <p>
    * 数据标识id部分
    * </p>
    */
   protected static long getDatacenterId(long maxDatacenterId) {
       long id = 0L;
       try {
           InetAddress ip = InetAddress.getLocalHost();
           NetworkInterface network = NetworkInterface.getByInetAddress(ip);
           if (network == null) {
               id = 1L;
          } else {
               byte[] mac = network.getHardwareAddress();
               id = ((0x000000FF & (long) mac[mac.length - 1])
                       | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
               id = id % (maxDatacenterId + 1);
          }
      } catch (Exception e) {
           e.printStackTrace();
      }
       return id;
  }

   public static String generateID(){
       return new IdWorker().nextId()+"";
  }
}



推荐阅读