(一)导包

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>cn.lzj</groupId>
  <artifactId>AiSell</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>AiSell Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <org.springframework.version>4.2.5.RELEASE</org.springframework.version>
    <org.hibernate.version>4.3.8.Final</org.hibernate.version>
    <spring-data-jpa.version>1.9.0.RELEASE</spring-data-jpa.version>
    <com.fasterxml.jackson.version>2.5.0</com.fasterxml.jackson.version>
    <org.slf4j.version>1.6.1</org.slf4j.version>
  </properties>
  <dependencies>

    <!-- Spring的核心包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>

    <!--Spring的上下文包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <!--Spring上下文支持包:支持以后Spring的邮件发送,定时器,模板-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>

    <!--Spring支持事务包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>

    <!--Spring的JDBC-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>

    <!--Spring的切面包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>

    <!--Spring的测试包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${org.springframework.version}</version>
      <!--代表测试只能在test包中使用-->
      <scope>test</scope>
    </dependency>

    <!--Spring的web前端的支持包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>

    <!--SpringMVC上传需要用到i的o包-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.3.2</version>
    </dependency>
    <!-- 文件上传用到的包 -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.2.2</version>
    </dependency>

    <!-- SpringMVC的json支持包 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${com.fasterxml.jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${com.fasterxml.jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${com.fasterxml.jackson.version}</version>
    </dependency>

    <!-- hibernate的支持包 -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>${org.hibernate.version}</version>
    </dependency>
    <!--hibernate对于jpa的支持包-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>${org.hibernate.version}</version>
    </dependency>

    <!-- SpringData的支持包 -->
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-jpa</artifactId>
      <version>${spring-data-jpa.version}</version>
    </dependency>
    <!-- SpringDataJPA的扩展包 -->
    <dependency>
      <groupId>com.github.wenhao</groupId>
      <artifactId>jpa-spec</artifactId>
      <version>3.1.1</version>

      <!--去掉所有的依赖,避免下载一些不必要的包 -->
      <exclusions>
        <exclusion>
          <groupId>*</groupId>
          <artifactId>*</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>1.2.2</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>

    <!--long3包,对JDK中原生的long包进行了封装,功能强大-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.5</version>
    </dependency>
    <!-- 测试包 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <!-- 这个scope 只能作用在编译和测试时,同时没有传递性。表示在运行的时候不添加此jar文件 -->
      <scope>provided</scope>
    </dependency>
    <!-- 日志文件 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${org.slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${org.slf4j.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
    </dependency>
    <!-- 代码生成器模版技术 -->
    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity</artifactId>
      <version>1.6</version>
    </dependency>
    <!-- shiro的支持包,进行权限的管理 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-all</artifactId>
      <version>1.4.0</version>
      <type>pom</type>
    </dependency>
    <!-- shiro与Spring的集成包 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.4.0</version>
    </dependency>

    <!-- poi支持的jar包,可以通过java代码操作办公软件 -->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.11</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.11</version>
    </dependency>
    <!-- 图片压缩功能 -->
    <!-- 缩略图 -->
    <dependency>
      <groupId>net.coobird</groupId>
      <artifactId>thumbnailator</artifactId>
      <version>0.4.6</version>
    </dependency>

    <!-- 定时调度,实现定时执行代码-->
    <dependency>
      <groupId>quartz</groupId>
      <artifactId>quartz</artifactId>
      <version>1.5.2</version>
    </dependency>
    <!-- 邮件支持 -->
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4.1</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>aisell</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>8.1.15.v20140411</version>
        <configuration>
          <stopPort>9966</stopPort>
          <stopKey>foo</stopKey>
          <webAppConfig>
            <contextPath>/</contextPath>
          </webAppConfig>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

(二)在spring的xml文件中进行配置

① 添加dataJpa的头

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
">

集成 Spring+SpringMVC+SpringDataJPA(SSSDJ)
②进行连接池、事务、包扫描等配置

<!--引入jdbc.propertides文件(必需加classpath) -->
    <context:property-placeholder location="classpath:jdbc.properties" />

    <!--Spring进行包的扫描,扫描项目的包-->
    <context:component-scan base-package="cn.lzj.aisell"/>

    <!--配置DataSource连接池-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--
        LocalContainerEntityManagerFactoryBean:就是一个FactoryBean对象,返回EntityManagerFactory对象给我们
        集成JPA:目的就是EntityManagerFactory对象
            配置JDBC的四大金刚,数据库方言,建表策略,显示SQL等信息
     -->

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!--配置连接信息-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置包的扫描(Scan),认识JPA的注解 -->
        <property name="packagesToScan" value="cn.lzj.aisell.domain" />
        <!--
            配置适配器 Spring+JPA(ORM规范) -> 到底用的是哪一个框架来完成的
                    JPA是有很多实现(Hibernate,OpenJPA,...)
         -->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!--方言(确定数据库)-->
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
                <!--建表策略-->
               <!-- <property name="generateDdl" value="false" />-->
                <!--支持SQL显示-->
                <property name="showSql" value="true" />
            </bean>
        </property>
    </bean>

    <!--Spring对于JPA的事务支持-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <!--支持事务-->
    <tx:annotation-driven/>

    <!--SpringDataJpa去扫描repository包
        若自定义接口继承了JpaRepository接口,就自动完成CRUD以及分页等功能
    -->
    <jpa:repositories base-package="cn.lzj.aisell.repository"
                      entity-manager-factory-ref="entityManagerFactory"
                      transaction-manager-ref="transactionManager" />

(三)新建仓库层,测试

  • ① 在仓库中新建一个接口,继承JpaRepository,此时SpringDataJpa就已经为我们实现了基本的CRUD的操作
/**
 * 泛型参数一: 要操作的类型(对Employee对象做CRUD)
 * 泛型参数二: 主键的类型
 */
public interface EmployeeRepository extends JpaRepository<Employee,Long> {
}
  • ② 此时就可以在测试类中,进行普通CRUD的操作

employeeRepository.findAll();
employeeRepository.findOne(Long id);

employeeRepository.save(具体对象); //添加或者修改都为sav(因为底层已经封装好是perssis还是merge方法)
employeeRepository.delete(id/对象);

employeeRepository.findAll(Pageable) -> 分页
Pageable pageable = new PageRequest(0, 5); //0就是第一页

employeeRepository.findAll(Sort) -> 排序
Sort sort = new Sort(Sort.Direction.DESC,“username”);

如果要把分页和排序结合起来: new PageRequest(0, 5,sort);

  • ③ 实现高级查询

1.名称规则
findByUsername(String username) -> 根据名称查询。相当于 username = ?
findByUsernameLike(String username) -> 模糊查询:username like ?
findByUsernameLikeAndEmailLike(String username) -> 多条件模糊查询:username like ? and email like ?

  • ④ Query注解

    @Query(“jpql的语句”)
    //自定义JSQL —> 注意: ?后面必须写序号

    @Query(“select o from Employee o where o.username = ?1”)
    List find01(String name);

    //自定义JSQL,使用对象的方式 —> 一般不用此操作,麻烦

    @Query(“select o from Employee o where o.username like :username and o.email like :email”)
    List find02(@Param((“username”)) String username, @Param(“email”) String email);

    @Query(nativeQuery = true,value=“select * from employee”)

  • ⑤ 高级查询+分页-----> JpaSpecificationExecutor

让Repository继承JpaSpecificationExecutor接口,不用写SQL,也能完成CRUD的操作

EmployeeRepository extends JpaRepository<Employee,Long>,
JpaSpecificationExecutor

/**
     * 使用JPA2.0进行数据的高级查询+分页查询+排序
     *          criteriaBuilder.and(p1, p2);  添加多个条件
     */
    @Test
    public void testJpaSpecificationExecutor03()throws Exception{
        Sort sort = new Sort(Sort.Direction.DESC,"age");
        //创建分页对象
        Pageable pageable = new PageRequest(0,10,sort);
        Page<Employee> page = employeeRepository.findAll(new Specification<Employee>() {
            @Override
            public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //获取查询的字段
                Path usernamePath = root.get("username");
                Path emilePath = root.get("age");
                Predicate p1 = criteriaBuilder.like(usernamePath, "%1%");
                Predicate p2 = criteriaBuilder.gt(emilePath, 20);
                Predicate p = criteriaBuilder.and(p1, p2);
                return p;
            }
        },pageable);
        page.forEach(e -> System.out.println(e));
    }
  • ⑥ 使用jpa-spec插件实现高级查询+分页+排序

jpa-spec插件兼容Spring Data Jpa 和JPA2.1接口,对动态生成Query功能进一步封装,使用这个插件,需要引入其jar包(之前导包的时候,已经进行导入)其有以下部分功能:

① Equal/NotEqual/Like/NotLike/In/NotIn支持可变参数, Equal/NotEqual 支持空(Null)值。
② 每个条件支持关联查询。
③ 支持自定义条件查询。
④ 条件构建器。
⑤ 支持分页和排序。

	/**
     * 使用jpa-spec插件实现分页+排序+高级查询
     */
    @Test
    public void testSpec02()throws Exception{
        Sort sort = new Sort(Sort.Direction.DESC,"age");
        Pageable pageable = new PageRequest(0, 10);
        Specification<Employee> spec = Specifications.<Employee>and()
                .like("username", "%1%")
                .like("email", "%2%")
                .gt("age", 20)
                .build();

        Page<Employee> page = employeeRepository.findAll(spec,pageable);
        page.forEach(e -> System.out.println(e));
    }
  • ⑦ 抽取Query对象,使用jpa-spec插件实现高级查询+分页

因为一般的CRUD,都是通过前台传入的参数,传到后台,后台在进行拼接SQL,若用户没有传入参数,则为null。所以应该准备一个Query对象,专门接收用户传入的数据

抽取baseQuery

/**
 * 父类:
 *      抽取子类所共有的代码
 *      规范子类的代码
 */
public abstract class BaseQuery {

    //当前页
    private int currentPage = 1;
    //每页条数
    private int pageSize = 10;
    //排序的类型(升序与降序) ASC/DESC
    private boolean orderByType = true;
    //排序的字段 age/username/...
    private String orderByName;

    //抽象方法,要求子类必需有一个拿出到查询条件的方法
    public abstract Specification creatSpec();

    public Sort createSort(){
        if(orderByType){
            return new Sort(Sort.Direction.DESC,orderByName);
        }
        return new Sort(Sort.Direction.ASC,orderByName);
    }
    
    省略get/set方法...........
}

Query对象

//Query对象,负责接收前台所传入的参数
public class EmployeeQuery extends BaseQuery{

    private String username;
    private String email;
    private Integer age;
    /**
     *  使用Spec插件,接收前台所传入的参数,进行高级查询
     */
    @Override
    public Specification creatSpec() {
        Specification<Employee> spec = Specifications.<Employee>and()
                .like(StringUtils.isNotBlank(username),"username", "%"+username+"%")
                .like(StringUtils.isNotBlank(email),"email","%"+email+"%")
                .gt(age!=null,"age",age)
                .build();
        return spec;
    }
    
省略get、set方法.....
}
	/**
	测试
     * 自定义Query对象,负责接收前台所传入的参数
     * 使用jpa-spec插件实现分页+排序+高级查询
     */
    @Test
    public void testSpec03()throws Exception{
        EmployeeQuery query = new EmployeeQuery();
        //高级查询
        query.setAge(18);
        query.setOrderByName("age");
        //排序类型为降序
        query.setOrderByType(true);
        Sort sort = query.createSort();
        Pageable pageable = new PageRequest(query.getJpaPage(), query.getPageSize(),sort);

        Specification spec = query.creatSpec();
        Page<Employee> page = employeeRepository.findAll(spec,pageable);
        page.forEach(e -> System.out.println(e));
    }

相关文章:

  • 2021-09-15
  • 2021-12-29
  • 2022-01-23
  • 2021-10-15
  • 2022-12-23
猜你喜欢
  • 2021-12-07
  • 2021-12-17
  • 2022-12-23
  • 2022-12-23
  • 2021-10-26
  • 2022-12-23
  • 2021-07-30
相关资源
相似解决方案