entity 表关系
基础注解
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23@JsonIgnore 将不需要返回的属性上添加忽略,多为复杂表关系属性排除使用 @Transient 表明为成员变量,不和数据库字段做映射 @Id 表明为主键,定义与Id上 @Table(name = "ws_user") 类名与数据库表名的关系映射,定义与类上 @Entity 表明为实体类,定义与类上 配置里面如果定义了jpa 为 update,会自动建表,@Transient 注解的字段不会被创建 --------1、数据库不存在表会自动创建表 --------2、数据库不存在某些字段数据库会自动创建该字段 --------3、指定了外键关系会自动在数据库中生成外键 @DynamicInsert --------设置为true,设置为true,表示insert对象的时候,生成动态的insert语句, --------如果这个字段的值是null就不会加入到insert语句当中.默认false。 --------比如希望数据库插入日期或时间戳字段时,在对象字段为空的情况下,表字段能自动填写当前的sysdate。 @DynamicUpdate --------设置为true,设置为true,表示update对象的时候,生成动态的update语句, --------如果这个字段的值是null就不会被加入到update语句中,默认false。
表关系注解
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23@OneToOne 一对一 @OneToMany 一对多 @ManyToOne 多对一 @ManyToMany 多对多 表关系注解属性详细说明 ----- cascade: 表示默认的级联操作策略,可以指定为ALL(全部),默认为无级联操作 -------- ALL (下方全部)@ManyToMany(cascade=CascadeType.ALL) -------- PERSIST(级联保存), -------- MERGE (级联更新), -------- REFRESH(级联刷新) -------- REMOVE (级联删除) ----- fetch: 表示抓取策略,默认为 , -------- EAGER(急记载,立即记载)--> 默认:FetchType.EAGER -------- LAZY (懒加载) ----- optional: 表示否允许该字段为null,该属性应该根据数据库表的外键约束来确定 -------- true 默认 -------- false
@Column 字段映射注解
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@Column 注解属性说明,指定生成的表字段名和长度,不指定默认255长度且表字段名同属性名一致 ------ 特殊字段关系映射示例,如 desc等mysql 关键字 @Column(name = "`desc`") private String desc; ------ 指定字段 tradeNo 长度为50,且值不能为null 示例 @Column(name = "tradeNo", length = 50, nullable = false) ------ 指定字段 tradeNo 长度为50,且值可以为null 示例 @Column(name = "tradeNo", length = 50, nullable = true) ------ 指定字段totalAmount(长度)为10,小数点位数为2位,且值不能为null 示例 @Column(name = "totalAmount", precision = 10, scale = 2, nullable = false)
@GeneratedValue 主键策略注解
复制代码
1
2
3
4
5
6
7
8
9@GeneratedValue 主键策略, 定义与id字段处 示例: @GeneratedValue(strategy=GenerationType.AUTO) ------IDENTITY: 采用数据库ID自增长的方式来自增主键字段,Oracle 不支持这种方式; ------AUTO: JPA自动选择合适的策略,是默认选项; ------SEQUENCE: 通过序列产生主键,通过@SequenceGenerator 注解指定序列名,MySql不支持这种方式 ------TABLE: 通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。
User 用户类 (具体表关系配置如下)
复制代码
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@Entity // 该注解声明一个实体类,与数据库中的表对应 @Table(name = "ws_user") //生成数据库的表名 public class User { @Id // 表明主键id @GeneratedValue // 主键的生成策略(看最下方注释具体说明) private Long userId; private String username; private String password; //======================= 用户 - [ 一对一 ] - 用户详情 ================ // @JoinColumn(name = "user_id") //外键关联 @PrimaryKeyJoinColumn //主键关联 @OneToOne(cascade=CascadeType.ALL) //ALL 级联/添加/更新/删除(看最下方注释具体说明) // 用户详情类 private UserDetail detail; //======================= 用户 - [ 一对多 ] - 收获地址 =============== //外键关联,指定一的一端的id 做外键 @JoinColumn(name = "user_id") @OneToMany(cascade=CascadeType.ALL) // 地址类 private List<Address> addresses; //======================= 用户 - [ 多对一 ] - 部门 ================ //外键关联,指定一的一端的id 做外键 @JoinColumn(name = "dep_id") @ManyToOne(cascade=CascadeType.ALL) // 部门类 private Dep dep; //======================= 用户 - [ 多对多 ] - 角色 =================== //name指中间表的表名,joinColumns指当前实体在中间表的字段,inverserJoinCloumns指关联的另外一个实体在中间表的字段名 @JoinTable(name="ws_user_role",joinColumns=@JoinColumn(name="user_id"),inverseJoinColumns=@JoinColumn(name="role_id")) @ManyToMany(cascade=CascadeType.ALL) //角色类 private List<Role> roles; set,get 方法自行添加........
dao层详解
复制代码
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
40package ws.cn.jpa.dao; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Component; import ws.cn.jpa.entity.User; /** * Created by Administrator on 2018/10/2/002. * JpaRepository<User,Long> 说明: * User 实体类 * Long 实体类主建的数据类型 */ @Component public interface UserDao extends JpaRepository<User,Long>,JpaSpecificationExecutor<User> { //自定义 sql 语句(语法一) @Query(value = "SELECT * FROM USER WHERE id = ?1", nativeQuery = true) User selectId(Integer id); /* * 我们在这里直接继承 JpaRepository,CrudRepository,PagingAndSortingRepository,JpaSpecificationExecutor * 这里面已经有很多现成的方法 * 这也是JPA的一大优点 * * (1) CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法 * (2) PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法 * (3)JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法 * (4)JpaSpecificationExecutor: 实现条件查询 * * 注解说明 * @Query: 自定义sql , 接口方法上使用 * @Modifying : 接口方法上如涉及到删除和修改在需要加上@Modifying * @Transactional : 也可以根据需要添加 @Transactional 对事物的支持,查询超时的设置等 */ }
传值语法二:及修改删除示例
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/** * 修改 * @return */ @Transactional @Modifying(clearAutomatically = true) @Query(value = "UPDATE Hero hero SET hero.equip=:equip WHERE hero.id= :id and hero.uid = :uid ") int upd(@Param("id") long id, @Param("uid") long uid, @Param("equip") String equip); /** * 删除 * */ @Modifying @Transactional @Query(value="delete from Hero e where uid=:uid and e.id in (:ids)") int deleteByIds(@Param("uid")long uid,@Param("ids")List<Long> ids);
数据操作详解
直接controller 层测试了
此处直接调用的 dao 层,请自行把复杂代码防止 service层在用 contrller 层调用
复制代码
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
165
166package ws.cn.jpa.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import ws.cn.jpa.dao.UserDao; import ws.cn.jpa.entity.User; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2018/10/2/002. */ @RestController public class UserController { @Autowired private UserDao userDao; //============查询所有=============== @GetMapping("/listuser") public List<User> findAll() { // Sort 第一个属性为排序规则, 第二个属性为按照那个字段来排序 Sort sort = new Sort(Sort.Direction.DESC, "userId"); //findAll() 可以不带sort属性,默认排序 return userDao.findAll(sort); } //============ id 查询=============== @GetMapping("/findById") public User findById(Long id) { id = 3L; //模拟 id User user = userDao.findById(Long.valueOf(id)).get(); return user; } //============ 多id 查询=============== @GetMapping("/findAllById") public List findAllById(List<Long> ids) { // 模拟 id List list = new ArrayList(); list.add(Long.valueOf(2)); list.add(Long.valueOf(3)); List users = userDao.findAllById(list); return users; } //============ 分页查询=============== @GetMapping("/pageuser") public Page<User> pageuser() { // 开始页数 / 每页数量 / 排序规则 / 根据id排序 Pageable pageable = new PageRequest(0, 2, Sort.Direction.DESC, "id"); Page<User> page = userDao.findAll(pageable); System.out.println(page.getTotalElements() + "-->总数据数"+"/r/n"+ page.getTotalPages() + "-->总页数"+"/r/n"+ page.getNumber() + "-->当前页"+"/r/n"+ page.getSize() + "-->每页条数"+"/r/n"+ page.getNumberOfElements() + "-->本页条数"+"/r/n"+ "查询到的数据:" + page.getContent() ); return page; } //============ 动态条件查询 =============== /* * username = 666 and password = 666 * username = 666 or password = 666 **/ @GetMapping("/queryStudent") public List<User> queryStudent(User user) { user.setUsername("666"); user.setPassword("666"); //生成条件 Specification specification = new Specification() { @Override public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { // and 条件 List<Predicate> ands = new ArrayList<>(); if (user.getUsername() != null && !"".equals(user.getUsername())) { ands.add(criteriaBuilder.equal(root.<String>get("username"), user.getUsername())); } if (user.getUsername() != null && !"".equals(user.getUsername())) { ands.add(criteriaBuilder.equal(root.<String>get("password"), user.getPassword())); } // or 条件 List<Predicate> ors = new ArrayList<>(); ors.add(criteriaBuilder.like(root.<String>get("username"), "%"+"9"+"%")); //模糊查询 like ors.add(criteriaBuilder.like(root.<String>get("password"), "%"+"9"+"%")); //模糊查询 like Predicate and = criteriaBuilder.and(ands.toArray(new Predicate[ands.size()])); //and 连接的条件集 Predicate or = criteriaBuilder.or(ors.toArray(new Predicate[ors.size()])); //or 连接的条件集 List<Predicate> predicate = new ArrayList<>(); //条件集集合 predicate.add(and); //添加 and 的条件集 predicate.add(or); //添加 or 的条件集 //return criteriaBuilder.and(predicate.toArray(new Predicate[predicate.size()]));// and 连接条件集 return criteriaBuilder.or(predicate.toArray(new Predicate[predicate.size()])); // or 连接条件集 } }; List userDaoAll = userDao.findAll(specification); return userDaoAll; } //============ 添加、修改数据=============== @GetMapping("/adduser") public void addUser(User user) { userDao.save(user); } //============ 添加多条数据=============== @GetMapping("/saveAll") public void saveAll() { List<User> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { User user = new User("mm" + i, "123456"); list.add(user); } //保存实体集合 userDao.saveAll(list); } //============ id 删除数据=============== @GetMapping("/deleteId") public void deleteuser(Long id) { userDao.deleteById(id); } //============ 多 id 删除数据=============== @GetMapping("/deleteIds") public void deleteAll(List<Long> ids) { List list = new ArrayList(); list.add(Long.valueOf(7)); list.add(Long.valueOf(8)); list.add(Long.valueOf(9)); userDao.deleteAll(list); } //============ 删除所有数据 =============== @GetMapping("/deleteAll") public void deleteAll(Long id) { userDao.deleteAll(); } }
一个方法实现分页+排序+动态条件查询
动态查询大致 API 一览
复制代码
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
32And 并且 Or 或 Is,Equals 等于 Between 两者之间 LessThan 小于 LessThanEqual 小于等于 GreaterThan 大于 GreaterThanEqual 大于等于 After 之后(时间) > Before 之前(时间) < IsNull 等于Null IsNotNull,NotNull 不等于Null Like 模糊查询。查询件中需要自己加 % NotLike 不在模糊范围内。查询件中需要自己加 % StartingWith 以某开头 EndingWith 以某结束 Containing 包含某 OrderBy 排序 Not 不等于 In 某范围内 NotIn 某范围外 True 真 False 假 IgnoreCase 忽略大小写
添加分页方法接口–dao层
复制代码
1
2
3@Override Page<User> findAll(Specification<User> spec, Pageable pageable);
service 层添加
排序字段 : Sort.Direction.DESC, “id”) ,可以定义到controller 层
param : 查询参数
jpa包路径:import org.springframework.data.domain. (别引错)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/** * @param page 页数 * @param size 记录数 * @param param 查询条件 */ public Page<User> Page(int page,int size,Map<String, Object> param) { return dao.userDao.findAll(new Specification<User>() { private static final long serialVersionUID = 1L; @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { // TODO Auto-generated method stub List<Predicate> list = new ArrayList<>(); // 查询条件拼接 for (String key : param.keySet()) { list.add(cb.like(root.get(key).as(String.class), ("%"+param.get(key)+"%").toString())); } Predicate[] p = list.toArray(new Predicate[0]); return cb.and(p); } },PageRequest.of(page-1, size,Sort.Direction.DESC, "id")); }
controller
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/** * 分页查询 * * @return */ @RequestMapping("/user") String list() { // 查询条件 Map<String, Object> param = new HashMap<String, Object>(8); param.put("name", "张三"); param.put("account", getString("account","666")); // 查询 Page<User> page = service.userService.Page(1,20,param), }
查询条件拼接 / 部分示例如下(精准/模糊/ 时间)
具体看api
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18for (String key : param.keySet()) { } 遍历拼接每一个参数 //模糊查询 list.add(cb.eq(root.get(key).as(String.class), ("%"+param.get(key)+"%").toString())); //精准查询 //list.add(cb.equal(root.get(key).as(String.class), (param.get(key)).toString())); //时间段查询 // list.add(cb.between(root.get("time"), mapTime.get("startTime"), mapTime.get("overTime"))); //大于或等于传入时间 // list.add(cb.greaterThanOrEqualTo(root.get("commitTime").as(String.class), stime)); // 小于或等于传入时间 // list.add(cb.lessThanOrEqualTo(root.get("commitTime").as(String.class), etime));
最后
以上就是悲凉跳跳糖最近收集整理的关于JPA -- 表关系映射 || 增删改查 || 一个方法实现分页+排序+动态条件查询的全部内容,更多相关JPA内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复