当前位置:   article > 正文

mysql jpa自增 分布式_初学Spring-data-jpa+jpa配置+Springboot和Spring-data-jpa做简单操作+分布式服务设置一个永远不重复的ID...

springboot datajpa id自增

关于Spring-data-jpa的配置+Springboot+Spring-data-jpa的简单操作+分布式服务设置一个永远不重复的ID

初学Spring全家桶家族中的Spring-data-jpa发现可以更简单的实现一些基本的增删改查,以下是一些基础操作,希望可以给初学者一些帮助。

spring家族

Spring Boot

spring Cloud

Spring framework

Spring-data

Spring data-jpa(简单的增删改查)

...

1

2

3

4

5

6

jpa配置

jpa的底层是基于hibernate

多表联查的时候会用到一对多,多对一的关系等

springboot一旦是一个web程序,记得配置数据源

1

2

3

4

springdata-jpa一般是不需要自己写sql语句的

springdata-jpa.hibernate.ddl-auto:update/create

如果是使用create:每次都会新建一个对应的表,覆盖原有的表

update:不会覆盖原有的表,只会更新表结构和表数据

当没有设置驼峰命名的时候,默认会以gradeId---->grade_id

1

2

3

4

5

具体代码如下:

#springboot数据源

spring:

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/studentjpa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC

password: root

username: root

#配置spring-data-jpa

jpa:

show-sql: true #控制台输出sql语句

database: mysql #jpa使用的数据库

hibernate:

ddl-auto: update

naming:

physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

server:

port: 8081

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

实体类快速建表

Spring Data Jpa 可以根据实体类 在数据库里自动生成表

实体类的注解

@Data 自动封装属性

@Table(name = "student") 对应数据库中的表,用于指定表的名称

@Entity 注解用于生成数据库表,

1

2

3

4

Id列的注解

@Id 表示这是一个主键。

@GeneratedValue(strategy = )用于根据规则生成主键,

/*Id表示主键 主键有生成策略*/

/*GenerationType.IDENTITY唯一列还自动增长*/

/*GenerationType.AUTO自动增长*/

/*Oracle中是没有自动增长的 设置GenerationType.SEQUENCE 使用序列进行增长*/

/*GeneratedValue 自动增长生成的value值*/

1

2

3

4

5

6

7

8

普通列注解

@Column

1

2

启动后自动建表成功

Dao(数据访问层)接口

DAO的接口:

继承JpaRepository, JpaSpecificationExecutor

JpaRepository 扩展简单的增删改查、批量操作

JpaSpecificationExecutor 用来做负责查询的接口

其他:

Repository 空接口

CrudRepository 增删改查

PagingAndSortingRepository 分页和排序

Specification 是Spring Data JPA提供的一个查询规范,要做复杂的查询,类似hibernate QBC查询

JpaRepository继承PagingAndSortingRepository,CrudRepository:

CrudRepository 提供 save、 delete、 deteleAll、 findAll、 findOne、 count等方法

PagingAndSortingRepository提供排序及分页findAll(Sort) (基于排序的查询)、findAll(Pageable)( 基于分页的查询)

1

2

3

4

5

6

7

8

9

10

11

12

13

Dao层代码

package com.szh.springdatajpa.dao;

import com.szh.springdatajpa.pojo.Student;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import org.springframework.data.jpa.repository.Query;

import java.util.List;

/**

* 学生数据访问层

*

* @author 宋政宏

* @date 2019-05-17

*/

public interface StudentDao extends JpaRepository, JpaSpecificationExecutor {

/*nativeQuery 原声的sql语句查询*/

/*根据姓名模糊查询*/

@Query(value = "select * from student where name like concat('%',?,'%')",nativeQuery = true)

List selByName(String name);

/*查询前两行信息*/

List findTop2By();

/*根据姓名模糊查询*/

List findByNameContaining(String name);

/*根据姓名或性别模糊查询*/

//List findByNameLikeOrSexNotIn()

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

Service层(实现层)的接口和类

interface接口

Service接口中有新增,修改,查询,根据id查询,根据id删除,根据姓名模糊查询,查询前俩行信息,模糊查询,分页查询等方法

1

package com.szh.springdatajpa.service;

import com.szh.springdatajpa.pojo.Student;

import org.springframework.data.domain.Page;

import java.util.List;

/**

* 学生实现层接口

*

* @author 宋政宏

* @date 2019-05-17

*/

public interface StudentService {

/*新增学生信息*/

Student add(Student student);

/*修改学生信息*/

Student upd(Student student);

/*查询所有学生信息*/

ListselAll();

/*根据id查询学生信息*/

Student selById(Integer id);

/*根据id删除学生信息*/

String del(Integer id);

/*根据姓名模糊查询*/

List selByName(String name);

/*查询前俩行信息*/

List findTop2();

/*模糊查询*/

List findByNameLike(String name);

/*分页查询*/

Page findByPage(Integer pageNum, Integer size);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

Impl类

package com.szh.springdatajpa.service.impl;

import com.szh.springdatajpa.dao.StudentDao;

import com.szh.springdatajpa.pojo.Student;

import com.szh.springdatajpa.service.StudentService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.PageRequest;

import org.springframework.stereotype.Service;

import java.util.List;

import java.util.Optional;

/**

* 学生实现类

*

* @author 宋政宏

* @date 2019-05-17

*/

@Service

public class StudentServiceImpl implements StudentService {

@Autowired

private StudentDao studentDao;

/*新增学生信息*/

@Override

public Student add(Student student) {

Student add = studentDao.save(student);

return add;

}

/*修改学生信息*/

@Override

public Student upd(Student student) {

//有id的时候是修改,没有id的时候是新增

Student upd = studentDao.save(student);

return upd;

}

/*查询所有学生信息*/

@Override

public List selAll() {

List sa = studentDao.findAll();

return sa;

}

/*根据id查询学生信息*/

@Override

public Student selById(Integer id) {

Optional selbyid = studentDao.findById(id);

return selbyid.get();

}

/*根据id删除学生信息*/

@Override

public String del(Integer id) {

studentDao.deleteById(id);

return "删除成功";

}

/*根据姓名模糊查询*/

@Override

public List selByName(String name) {

return studentDao.selByName(name);

}

/*查询前两条信息*/

@Override

public List findTop2(){

return studentDao.findTop2By();

}

/*模糊查询*/

@Override

public List findByNameLike(String name){

return studentDao.findByNameContaining(name);

}

/*分页查询*/

@Override

public Page findByPage(Integer pageNum,Integer size){

PageRequest pageRequest = PageRequest.of(pageNum - 1, size);

return studentDao.findAll(pageRequest);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

Controller(控制层)类

@RestController:@Controller+@ResponseBody 以json数据进行返回

1

package com.szh.springdatajpa.controller;

import com.szh.springdatajpa.pojo.Student;

import com.szh.springdatajpa.service.StudentService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.*;

import java.util.List;

/**

*学生控制层

*

* @author 宋政宏

* @date 2019-05-17

*/

@RestController

public class StudentController {

@Autowired

private StudentService studentService;

/**

* 新增学生信息

* @param student

* @return

*/

@PostMapping("/student")

public Student add(Student student){

return studentService.add(student);

}

/**

* 修改学生信息

* @param student

* @return

*/

@PutMapping("/update")

public Student upd(Student student){

return studentService.upd(student);

}

/**

* 查询所有学生信息

* @param

* @return

*/

@GetMapping("/selAll")

public List selAll(){

return studentService.selAll();

}

/**

* 根据id查询学生信息

* @param id

* @return

*/

@GetMapping("/selById/{id}")

public Student selById(@PathVariable("id")Integer id){

return studentService.selById(id);

}

/**

* 删除学生信息

* @param id

* @return

*/

@DeleteMapping("/delete/{id}")

public String delete(@PathVariable("id") Integer id){

return studentService.del(id);

}

/**

* 根据姓名模糊查询

*

* @param name

* @return

*/

@GetMapping("/selByName")

public List selByName(String name){

return studentService.selByName(name);

}

/**

* 查询前两行学生信息

*

* @param

* @return

*/

@GetMapping("/findTop2")

public List findTop2(){

return studentService.findTop2();

}

/**

* 模糊查询

*

* @param

* @return

*/

@GetMapping("/findByNameLike")

public List findByNameLike(String name){

return studentService.findByNameLike(name);

}

@GetMapping("/findByPage")

public List findByPage(Integer pageNum,Integer size){

Page page = studentService.findByPage(pageNum, size);

//return "总条数是"+page.getTotalElements();

return page.getContent();

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

最后运行项目打开Postman工具测试功能!

查询成功!

设置一个永远不重复的ID

解决高并发id的问题

UUID 分布式服务自己设置Id

1

2

SpringdatajpaApplication运行类自定义Bean属性

/*自定义Bean属性*/

@Bean

public IdWorker idWorker(){

return new IdWorker(1,1);

}

1

2

3

4

5

6

新建util包创建IdWorker类

IdWorker类的代码:

package com.changan.springdatajpa.util;

import java.lang.management.ManagementFactory;

import java.net.InetAddress;

import java.net.NetworkInterface;

/**

*

名称:IdWorker.java

*

描述:分布式自增长ID

*

 
 

* Twitter的 Snowflake JAVA实现方案

*

* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:

* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000

* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,

* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),

* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。

* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),

* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。

*

* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))

*

* @author Polim

*/

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();

}

/**

*

* 获取 maxWorkerId

*

*/

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);

}

/**

*

* 数据标识id部分

*

*/

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) {

System.out.println(" getDatacenterId: " + e.getMessage());

}

return id;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

然后修改上面Service层(实现层)的Impl类

这是Impl类中新增Id处理

1

最后大功告成,运行项目。

---------------------

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/739630
推荐阅读
相关标签
  

闽ICP备14008679号