智能销售系统-项目搭建

1.搭建项目框架(一) Spring+SpringDataJPA+SpringMVC+EasyUI+Maven

2.SpringDataJpa的认识与使用

MyBatis:Apache的一个开源项目(咱们第三个项目使用的框架),上手简单,开发灵活,现在市场占有率高; 但是开发时工作量比较大,需要做很多配置,并且自己要写SQL语句。
Hibernate:一个开放源代码的对象关系映射框架,是完全面向对象的。可以使用面向对象的思路来完成数据库操作。 Hibernate是完备的ORM框架(咱们之前学习JPA,底层就是使用Hibernate完成的)。

在这里插入图片描述
在这里插入图片描述

3.JpaRepository的基本功能

3.1.普通的CRUD

//获取所有数据
@Test
public void testFindAll() throws Exception{
    List<Employee> emps = employeeRepository.findAll();
    for (Employee emp :emps){
        System.out.println(emp);
    }
}
//根据id到一条数据
@Test
public void testFindOne() throws Exception{
    Employee employee = employeeRepository.findOne(1L);
    System.out.println(employee);
}

//添加与修改都使用save(主要看对象有没有id)
@Test
public void testSave() throws Exception{
    Employee employee = new Employee();
    //employee.setId(103L);
    employee.setUsername("张三");
    employee.setPassword("1234");
    employee.setEmail("zhangsha@163.com");
    employeeRepository.save(employee);
}
//删除数据
@Test
public void testDelete() throws Exception{
    employeeRepository.delete(103L);
}
//得到总条数
@Test
public void testCount(){
    System.out.println(employeeRepository.count());
}

3.2.分页排序功能
//进行分页功能
@Test
public void testPage() {
    //1.需要先创建一个page对象(注意:页数是从0开始计算【0就是第1页】)
    Pageable pageable = new PageRequest(0, 10);
    //2.进行查询
    Page<Employee> page = employeeRepository.findAll(pageable);
    System.out.println(page.getTotalElements()); //总条数
    System.out.println(page.getTotalPages()); //总页数
    System.out.println(page.getContent()); //当前页数据
    System.out.println(page.getNumber()); //第几页
    System.out.println(page.getNumberOfElements()); //当前页有多少个数据
    System.out.println(page.getSize()); //每页条数
}

//进行排序功能
@Test
public void testSort() {
    //排序 :第一个参数是排序的规则(DESC/ASC)  后面参数是排序的字符
    Sort sort = new Sort(Sort.Direction.DESC,"username");
    List<Employee> emps = employeeRepository.findAll(sort);
    for (Employee emp : emps) {
        System.out.println(emp);
    }
}

//分页与排序的集成
@Test
public void testPageAndSort() {
    //排序 :第一个参数是排序的规则(DESC/ASC)  后面参数是排序的字符
    Sort sort = new Sort(Sort.Direction.DESC,"username");
    Pageable pageable = new PageRequest(0, 10,sort);
    //2.进行查询
    Page<Employee> page = employeeRepository.findAll(pageable);
    for (Employee employee : page) {
        System.out.println(employee);
    }
}

4.JpaSpecificationExecutor的认识

JpaSpecificationExecutor(JPA规则执行者)是JPA2.0提供的Criteria API的使用封装,可以用于动态生成Query来满足我们业务中的各种复杂场景。
Spring Data JPA为我们提供了JpaSpecificationExecutor接口,只要简单实现toPredicate方法就可以实现复杂的查询。

package org.springframework.data.jpa.repository;

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;

public interface JpaSpecificationExecutor<T> {
   T findOne(Specification<T> spec);
   List<T> findAll(Specification<T> spec);
   Page<T> findAll(Specification<T> spec, Pageable pageable);
   List<T> findAll(Specification<T> spec, Sort sort);
   long count(Specification<T> spec);
}

4.1.单个条件的查询

@Test
public void testFind() {
    /**
*官方解释:
     * Root<T> root:代表了可以查询和操作的实体对象的根,
     *              可以通过它的 Path<Y> get(String attributeName); 这个方法拿到我们要操作的字段
     *              注意:只可以拿到对应的T的字段(Employee)
     * CriteriaQuery<?> query:代表一个specific的顶层查询对象
     *              包含查询的各个部分,比如select,from,where,group by ,order by 等
     *              简单理解 就是它提供 了查询ROOT的方法(where,select,having)
     * CriteriaBuilder cb:用来构建CriteriaQuery的构建器对象(相当于条件或者说条件组合)
     *              构造好后以Predicate的形式返回
     */
/**
* 非官方理解:
 * 查询的时候就需要给一个标准(规范)
 *  -》 根据规范(这个规范我们可以先简单理解为查询的条件)进行查询
 *
 *      Root:查询哪个表(定位到表和字段-> 用于拿到表中的字段)
 *            可以查询和操作的实体的根
 *              Root接口:代表Criteria查询的根对象,Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似
 *             Root<Employee> 相当于 from Employee
 *             Root<Product> 相当于  from Product
 *      CriteriaQuery:查询哪些字段,排序是什么(主要是把多个查询的条件连系起来)
 *      CriteriaBuilder:字段之间是什么关系,如何生成一个查询条件,每一个查询条件都是什么方式
 *                      主要判断关系(和这个字段是相等,大于,小于like等)
 *      Predicate(Expression):单独每一条查询条件的详细描述 整个 where xxx=xx and yyy=yy ...
 */
    List<Employee> emps = employeeRepository.findAll(
            new Specification<Employee>() {
                @Override
                public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    Path path = root.get("username");//拿到要做查询的字段
                    Predicate p = cb.like(path, "%1%");//like代表做模糊查询,后面就是它的条件值
                    return p;
                }
            }
    );
    for (Employee emp : emps) {
        System.out.println(emp);
    }
}

4.2.多个条件查询

@Test
public void testFind02() {
    Specification spec = new Specification<Employee>() {
        @Override
        public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
            //加上第一个条件: username like '%1%'
            Path path1 = root.get("username");
            Predicate p1 = cb.like(path1, "%1%");
            //加上第二个条件: email like '%2%'
            Path path2 = root.get("email");
            Predicate p2 = cb.like(path2,"%2%");
            //加上第二个条件: age < 20
            Path path3 = root.get("age");
            Predicate p3 = cb.lt(path3, 20);
           //下面是加上or的条件的方案
           //Predicate p3 = cb.or(p1,p2);

            //把两个查询条件放到query对象中去(条件使用where)
            CriteriaQuery where = query.where(p1, p2, p3);
            //返回查询条件
            return where.getRestriction();
        }
    };

    List<Employee> emps = employeeRepository.findAll(spec);
    for (Employee emp : emps) {
        System.out.println(emp);
    }

}

4.3.条件查询+分页排序

@Test
public void testFind03() {
    Specification spec = new Specification<Employee>() {
        @Override
        public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
            //加上条件: username like '%1%'
            Path path1 = root.get("username");
            Predicate p1 = cb.and(cb.like(path1, "%1%"));
            //把两个查询条件放到query对象中去(条件使用where)
            CriteriaQuery where = query.where(p1);
            //返回查询条件
            return where.getRestriction();
        }
    };

    //排序 :第一个参数是排序的规则(DESC/ASC)  后面参数是排序的字符
    Sort sort = new Sort(Sort.Direction.DESC,"username");
    Pageable pageable = new PageRequest(0, 10,sort);

    Page<Employee> page = employeeRepository.findAll(spec, pageable);
    for (Employee emp : page) {
        System.out.println(emp);
    }
}

5.Query查询条件

咱们每一个项目是做过高级查询与分页的,大家应该都清楚,查询的数据是从前端由客户输入(或者选择)传到后台的。那么,我们需要注意的情况有哪些呢?
1 用户传的数据有0-n个(我们需要去判断)
2 咱们必需要准备一个对象接收用户传过来的数据(使用Query对象)
3 分页的条件对我们来说也是封装到Query对象中的
接下来,我们要准备我们的Query对象:

6.1.BaseQuery:公共的分页条件

package cn.itsource.pss.query;
/**
 * 公共的条件与规范
 */
public abstract class BaseQuery {

    //当前页(从1开始)
    private int currentPage = 1;
    //每页条数
    private int pageSize = 10;

    //排序方式 ASC/DESC
    private String orderByType ="ASC";
    //排序字段
    private String orderByName;

    public int getCurrentPage() {
        return currentPage;
    }
    /**
     * 专门准备的方法,因为前台用户传的是从第1页开始,而我们后台分页又是从0开的
     * @return
     */
    public int getJpaPage() {
        return currentPage - 1;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }
    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public String getOrderByType() {
        return orderByType;
    }

    public void setOrderByType(String orderByType) {
        this.orderByType = orderByType;
    }

    public String getOrderByName() {
        return orderByName;
    }

    public void setOrderByName(String orderByName) {
        this.orderByName = orderByName;
    }
}

6.2.EmployeeQuery:Employee特有的一些条件

package cn.itsource.pss.query;

public class EmployeeQuery extends BaseQuery {

    private String username;//姓名
    private String email;//邮件
    private Integer age;//年龄

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值