概述
entity 表关系
基础注解
@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。
表关系注解
@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 字段映射注解
@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 主键策略注解
@GeneratedValue 主键策略, 定义与id字段处
示例: @GeneratedValue(strategy=GenerationType.AUTO)
------IDENTITY: 采用数据库ID自增长的方式来自增主键字段,Oracle 不支持这种方式;
------AUTO: JPA自动选择合适的策略,是默认选项;
------SEQUENCE: 通过序列产生主键,通过@SequenceGenerator 注解指定序列名,MySql不支持这种方式
------TABLE: 通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。
User 用户类 (具体表关系配置如下)
@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层详解
package 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 对事物的支持,查询超时的设置等
*/
}
传值语法二:及修改删除示例
/**
* 修改
* @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 层调用
package 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 一览
And 并且
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层
@Override
Page<User> findAll(Specification<User> spec, Pageable pageable);
service 层添加
排序字段 : Sort.Direction.DESC, “id”) ,可以定义到controller 层
param : 查询参数
jpa包路径:import org.springframework.data.domain. (别引错)
/**
* @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
/**
* 分页查询
*
* @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
for (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 -- 表关系映射 || 增删改查 || 一个方法实现分页+排序+动态条件查询所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复