1. 程式人生 > >spring boot+ jpa方法大全--jpa關係指定

spring boot+ jpa方法大全--jpa關係指定

dao層
繼承 JpaRepository實現增刪改查
繼承 JpaSpecificationExecutor 實現分頁

替換所有的 Dep

@Component
public interface DepDao extends JpaRepository<Dep, Long>, JpaSpecificationExecutor<Dep> {
}

service方法層
一鍵替換所有的 Dep

public  interface DepService {

    // 1============查詢所有===============
    public List<Dep> listAll(String properties);

    // 2============ id 查詢===============
    public Dep findId(Long id) ;

    // 3============ 多id 查詢==============
    public List findIds(List ids);

    // 4============ 分頁查詢===============
    public Page<Dep> pageAll(Integer page, Integer size, String properties);

    // 5============ 動態條件查詢 ===========
    public List<Dep> findquery(Dep query);

    // 6============ 新增、修改資料==========
    public void save(Dep query);

    // 7============ 新增多條資料============
    public void saveAll(List<Dep> query);

    // 8============ id 刪除資料=============
    public void deleteId(Long id);

    // 9============ 多 id 刪除資料==========
    public void deleteIds(List ids);

    // 10============ 刪除所有資料 ===========
    public void deleteAll();
}

serviceImpl方法實現層
一鍵替換所有的 Dep 和 dep 使用

@Service
public class DepServiceImpl implements DepService {

    @Autowired
    private DepDao depDao;


    //============查詢所有===============
    public List<Dep> listAll(String properties) {
        // 排序(倒序)
        Sort sort = new Sort(Sort.Direction.ASC, properties);
        return depDao.findAll(sort);
    }

    //============ id 查詢===============
    public Dep findId(Long id) {
        Dep dep = depDao.findById(Long.valueOf(id)).get();
        return dep;
    }

    //============ 多id 查詢===============
    public List findIds(List ids) {
        List deps = depDao.findAllById(ids);
        return deps;
    }

    //============ 分頁查詢===============
    public Page<Dep> pageAll(Integer page, Integer size, String properties) {
        // 頁數 / 每頁數量 / 排序規則 / 根據 dep_id 欄位排序
        Pageable pageable = new PageRequest(page, size, Sort.Direction.ASC, properties);
        Page<Dep> pageDep = depDao.findAll(pageable);
        System.out.print(pageDep.getTotalElements() + "-->總資料數" + "--> " +
                pageDep.getTotalPages() + "-->總頁數" + "--> " +
                pageDep.getNumber() + "-->當前頁" + "--> " +
                pageDep.getSize() + "-->每頁條數" + "--> " +
                pageDep.getNumberOfElements() + "-->本頁條數" + "--> " +
                "--> " + "查詢到的資料:" + pageDep.getContent().toString()
        );
        return pageDep;
    }

    //============ 動態條件查詢 (根據需求自定義)===============
    /*
     *  depname = 666 and  password = 666
     *  depname = 666 or   password = 666
     **/
    public List<Dep> findquery(Dep query) {
        //生成條件
        Specification specification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                // and 條件
                List<Predicate> ands = new ArrayList<>();
              /*  if (dep.getDepname() != null && !"".equals(dep.getDepname())) {
                    ands.add(criteriaBuilder.equal(root.<String>get("depname"), dep.getDepname()));
                }
                if (dep.getDepname() != null && !"".equals(dep.getDepname())) {
                    ands.add(criteriaBuilder.equal(root.<String>get("password"), dep.getPassword()));
                }*/
                // or 條件
                List<Predicate> ors = new ArrayList<>();
                ors.add(criteriaBuilder.like(root.<String>get("depname"), "%" + "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 depDaoAll = depDao.findAll(specification);
        return depDaoAll;
    }


    //============ 新增、修改資料===============
    public void save(Dep query) {
        depDao.save(query);
    }


    //============ 新增多條資料===============
    public void saveAll(List<Dep> querys) {
       /* List<Dep> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Dep dep = new Dep("mm" + i, "123456");
            list.add(deps);
        }*/
        //儲存實體集合
        depDao.saveAll(querys);
    }

    //============ id 刪除資料===============
    public void deleteId(Long id) {
        depDao.deleteById(id);
    }

    //============ 多 id 刪除資料===============
    public void deleteIds(List ids) {
        depDao.deleteAll(ids);
    }

    //============ 刪除所有資料 ===============
    public void deleteAll() {
        depDao.deleteAll();
    }
}

controller

一鍵替換所有的 Dep 和 dep 使用
@ResponseBody :定義在方法上返回 json 字串
多刪除和多新增方法自定義

/**
 * Created by Administrator on 2018/10/2/002.
 */
@RequestMapping("/dep")
@Controller           //返回值頁面跳轉 url
//@RestController     //所有方法返回值 json 資料
public class DepController {
    //帶 Flush 的方法為sql 立即生效

    @Autowired
    private DepService depService;

    // 1============查詢所有===============
    @GetMapping("/listAll")
    public String listAll(Model model) {
        List<Dep> deps = depService.listAll("depId");
        model.addAttribute("deps",deps);
        return  "dep/main";
    }
    // 2============ 分頁查詢===============
    @GetMapping("/pageAll")
    public String pageAll(Model model, Integer page, Integer size) {
        page = 0;  //頁數(0開始)
        size = 5;  //記錄數
        Page<Dep> pages = depService.pageAll(page, size, "userId");
        model.addAttribute("deps", pages.getContent());
        model.addAttribute("page", pages);
        return "dep/main";
    }
    // 3============ 新增、修改資料===============
    @PostMapping("/save")
    public String save(Dep dep) {
        depService.save(dep);
        return "redirect:/dep/listAll";
    }
    // 4============ 跳修改頁 id 查詢===============
    @GetMapping("/updateId")
    public String updateId(Model model,Long id) {
        Dep dep = depService.findId(id);
        model.addAttribute("dep",dep);
        return "dep/update";
    }
    // 5============ id 刪除資料===============
    @GetMapping("/deleteId")
    public String deleteId(Long id) {
        depService.deleteId(id);
        return "redirect:/dep/listAll";
    }
    // 6============ 動態條件查詢 ===============
    @GetMapping("/findquery")
    public String findquery(Model model,Dep dep) {
        List deps = depService.findquery(dep);
        model.addAttribute("deps",deps);
        return "dep/main";
    }
}

netity 實體資料類

主要體現了 jpa 的關係指定

@Table(name = "ws_user")   //生成資料庫的表名
@Entity  // 該註解宣告一個實體類,與資料庫中的表對應
public class User {

    @Id               //  表明主鍵id
    @GeneratedValue   //  主鍵的生成策略(看最下方註釋具體說明)
    private Long userId;

    private String username;

    private String password;


    //======================= 使用者 - [ 一對一 ] - 使用者詳情 ================


    //@PrimaryKeyJoinColumn                 //主鍵關聯
    @JoinColumn(name = "detail_id")        //外來鍵關聯
    @OneToOne(cascade=CascadeType.ALL)   //ALL 級聯/新增/更新/刪除(看最下方註釋具體說明)
    private UserDetail detail;


    //======================= 使用者 - [ 一對多 ] - 收穫地址 ===============

    //外來鍵關聯,指定一的一端的id 做外來鍵
    @JoinColumn(name = "user_id")
    @OneToMany(cascade=CascadeType.ALL)   //ALL 級聯/新增/更新/刪除
    private List<Address> addresses;


    //======================= 使用者 - [ 多對一 ] - 部門  ================

    //外來鍵關聯,指定一的一端的id 做外來鍵
    @JoinColumn(name = "dep_id")
    @ManyToOne(cascade=CascadeType.MERGE)  // 只級聯更新
    private Dep dep;


    //======== 使用者 - [ 多對多 ] - 角色 ===================

    //name指中間表的表名,joinColumns指當前實體在中間表的欄位,inverserJoinCloumns指關聯的另外一個實體在中間表的欄位名
    @JoinTable(name="ws_user_role",[email protected](name="user_id"),[email protected](name="role_id"))
    @ManyToMany(cascade=CascadeType.MERGE) // 只級聯更新
    private List<Role> roles;

    
    //======== 使用者 - [ 一對一 ] - qq 登陸資訊 ===================
   
    @JoinColumn(name = "qquser_id")      //外來鍵關聯
    @OneToOne(cascade=CascadeType.MERGE)
    private QQUserInfo qqUserInfo;


更多說明

// ================================= 表關係註解說明  ================================
/*
      @OneToOne      一對一
      @OneToMany     一對多
      @ManyToOne     多對一
      @ManyToMany    多對多  */

/*     上訴關係指定後新增的屬性(級聯比較重要,要了解使用)
       cascade:表示預設的級聯操作策略,可以指定為ALL(全部),預設為無級聯操作
            PERSIST(級聯儲存),
            MERGE  (級聯更新),
            REFRESH(級聯重新整理)
            REMOVE (級聯刪除)
       fetch:表示抓取策略,預設為FetchType.EAGER ,
            EAGER(急記載,立即記載)
            LAZY(懶載入)
       optional:是否允許該欄位為null,該屬性應該根據資料庫表的外來鍵約束來確定,預設為true
       */

// ================================= 屬性註解 @Column 說明  ================================

      

/*     @Transient 註解,表明為成員變數,不和資料庫欄位做對映(定義資料接收使用)
 *     @JsonIgnore   //將不需要返回的屬性上新增忽略(指定關係後資料迴圈套qian做屬性排除使用)
 *    
 *     @Column: 指定生成的表字段名和長度,不指定預設255長度且表字段名同屬性名一致
 *
 *     指定欄位 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:   通過表產生主鍵,框架藉由表模擬序列產生主鍵,使用該策略可以使應用更易於資料庫移植。
     **/