<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<org.springframework.version>4.2.5.RELEASEorg.springframework.version>
<org.hibernate.version>4.3.8.Finalorg.hibernate.version>
<spring-data-jpa.version>1.9.0.RELEASEspring-data-jpa.version>
<com.fasterxml.jackson.version>2.5.0com.fasterxml.jackson.version>
<org.slf4j.version>1.6.1org.slf4j.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${org.springframework.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${org.springframework.version}version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-ioartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.2.2version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>${com.fasterxml.jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>${com.fasterxml.jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${com.fasterxml.jackson.version}version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-coreartifactId>
<version>${org.hibernate.version}version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-entitymanagerartifactId>
<version>${org.hibernate.version}version>
dependency>
<dependency>
<groupId>org.springframework.datagroupId>
<artifactId>spring-data-jpaartifactId>
<version>${spring-data-jpa.version}version>
dependency>
<dependency>
<groupId>com.github.wenhaogroupId>
<artifactId>jpa-specartifactId>
<version>3.1.1version>
<exclusions>
<exclusion>
<groupId>*groupId>
<artifactId>*artifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>commons-dbcpgroupId>
<artifactId>commons-dbcpartifactId>
<version>1.2.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.6version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>3.5version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${org.slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${org.slf4j.version}version>
<scope>runtimescope>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.14version>
dependency>
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocityartifactId>
<version>1.6version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-allartifactId>
<version>1.4.0version>
<type>pomtype>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-springartifactId>
<version>1.4.0version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>3.11version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.11version>
dependency>
<dependency>
<groupId>net.coobirdgroupId>
<artifactId>thumbnailatorartifactId>
<version>0.4.6version>
dependency>
<dependency>
<groupId>quartzgroupId>
<artifactId>quartzartifactId>
<version>1.5.2version>
dependency>
<dependency>
<groupId>javax.mailgroupId>
<artifactId>mailartifactId>
<version>1.4.1version>
dependency>
dependencies>
<build>
<finalName>Day1208_aisellfinalName>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<source>1.8source>
<target>1.8target>
configuration>
plugin>
<plugin>
<groupId>org.mortbay.jettygroupId>
<artifactId>jetty-maven-pluginartifactId>
<version>8.1.15.v20140411version>
<configuration>
<stopPort>9966stopPort>
<stopKey>foostopKey>
<webAppConfig>
<contextPath>/contextPath>
webAppConfig>
configuration>
plugin>
plugins>
build>
project>
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///pss
jdbc.username=root
jdbc.password=123456
<beans xmlns="http://www.springframework.org/schema/beans"
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"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
">
<jpa:repositories base-package="com.lty.aisell.repository"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager">
jpa:repositories>
<context:component-scan base-package="com.lty.aisell.service">context:component-scan>
<context:property-placeholder location="classpath:jdbc.properties">context:property-placeholder>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}">property>
<property name="url" value="${jdbc.url}">property>
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.lty.aisell.domain">property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false">property>
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect">property>
<property name="showSql" value="true">property>
bean>
property>
bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager">tx:annotation-driven>
beans>
<property name="maxActive" value="150" />
<property name="minIdle" value="5" />
<property name="maxIdle" value="20" />
<property name="initialSize" value="30" />
<property name="logAbandoned" value="true" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="10" />
<property name="maxWait" value="1000" />
<property name="timeBetweenEvictionRunsMillis" value="10000" />
<property name="numTestsPerEvictionRun" value="10" />
<property name="minEvictableIdleTimeMillis" value="10000" />
<property name="validationQuery" value="SELECT NOW() FROM DUAL" />
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
/*
*泛化:继承关系
*在JPA中,domain的父类必需要加@MappedSuperclass
*非常明确定的告诉JPA,这是一个用于映射的父类,不持久化到表
*/
@MappedSuperclass
public class BaseDoamin {
@Id
@GeneratedValue
protected Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee extends BaseDoamin{
private String username;
private String password;
private String email;
private Integer age;
//省略getter,setter与toString
}
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
*必需继承JpaRepository<1v,2v>
* 第一个泛型:代表类型(对哪一个实体进行操作)
* 第二个泛型:主键类型
*/
public interface EmployeeRepository extends JpaRepository<Employee, Long>{
}
List<Employee> list = employeeRepository.findAll();
getOne
返回一个实体的引用,无结果会抛出异常;findOne
返回一个Optional
对象,可以实现动态查询Employee employee = employeeRepository.findOne(1L);
//根据是否有Id自动确认是添加还是修改
employeeRepository.save(employee);
employeeRepository.delete(274L);
/*
* 第一个参数Sort.Direction.DESC:排序方式(降序)
* 第二个参数:排序属性
*/
Sort sort = new Sort(Sort.Direction.DESC,"age");
List<Employee> list = employeeRepository.findAll(sort);
list.forEach(e -> System.out.println(e));
/**
* page:第几页(页数是从0开始计算,0就是第1页)
* size:每页条数
*/
Pageable pageable = new PageRequest(0, 10);
//分页对象
Page<Employee> page = employeeRepository.findAll(pageable);
page.forEach(e -> System.out.println(e));
//总条数
System.out.println(page.getTotalElements());
//总页数
System.out.println(page.getTotalPages());
//当前页数据
System.out.println(page.getContent());
//第几页
System.out.println(page.getNumber());
//创建排序对象
Sort sort = new Sort(Sort.Direction.DESC, "age");
//创建分页对象
Pageable pageable = new PageRequest(0,10,sort);
Page<Employee> page = employeeRepository.findAll(pageable);
page.forEach(e -> System.out.println(e));
规则如下:
表达式 | 例子 | sql查询语句 |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEqual | … where x.firstname = 1? |
Between | findByStartDateBetween | … where x.startDate between 1? and ?2 |
LessThan(lt) | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual(le) | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
/*根据用户名模糊查询(规范名)*/
Employee findByUsername(String username);
/*根据用户名模糊查询(规范名)*/
List<Employee> findByUsernameLike(String username);
/*根据用户名与邮件进行模糊查询(规范名)*/
List<Employee> findByUsernameLikeAndEmailLike(String username,String email);
}
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
/*根据用户名模糊查询(注解)*/
@Query("select e from Employee e where e.username = ?1")
Employee query01(String username);
/*根据用户名模糊查询(注解)*/
@Query("select e from Employee e where e.username like ?1")
List<Employee> query02(String username);
/*根据用户名与邮件进行模糊查询(注解)*/
// @Query("select e from Employee e where e.username like ?1 and e.email like ?2")
// List query03(String username,String email);
@Query("select e from Employee e where e.username like :username and e.email like :email")
List<Employee> query03(@Param("username") String username, @Param("email")String email);
/*查询所有(原生SQL)*/
@Query(nativeQuery = true,value = "SELECT * FROM employee")
List<Employee> query04();
}
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface EmployeeRepository extends JpaRepository<Employee, Long> ,JpaSpecificationExecutor<Employee>{
}
/*根据用户名进行模糊查询(规则)
* 需要继承JpaSpecificationExecutor<>
* */
@Test
public void testJpaSpecificationExecutor01() throws Exception{
/**
* Predicate : 使以…为依据; where 条件 and 条件 ....
* @param root : 代表了可以查询和操作的实体对象的根
* 获取到实体对应的字段(username,password,age,email...)
* @param criteriaQuery : 代表一个specific的顶层查询对象
* 查询哪些字段,排序是什么(主要是把多个查询的条件连系起来)
* @param criteriaBuilder : 用来构建CriteriaQuery的构建器对象(相当于条件或者说条件组合)
* 主要判断关系(字段是相等,大于,小于like等)
*/
List<Employee> list = employeeRepository.findAll(new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//拿到用户名路径(Path不用加泛型)
Path usernamePath = root.get("username");
//用户名判断条件
Predicate predicate = criteriaBuilder.like(usernamePath,"%1%");
return predicate;
}
});
list.forEach(e-> System.out.println(e));
}
/*根据用户名和邮件进行查询(规则)*/
@Test
public void testJpaSpecificationExecutor02() throws Exception{
List<Employee> list = employeeRepository.findAll(new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//拿到用户名根路径
Path usernamePath = root.get("username");
//拿到邮件根路径
Path emailPath = root.get("email");
//用户名判断条件
Predicate predicate1 = criteriaBuilder.like(usernamePath, "%1%");
//邮件判断条件
Predicate predicate2 = criteriaBuilder.like(emailPath, "%2%");
//把条件结合
Predicate predicate = criteriaBuilder.and(predicate1, predicate2);
return predicate;
}
});
list.forEach(e-> System.out.println(e));
}
@Test
public void testJpaSpecificationExecutorPageSort() throws Exception{
//创建排序对象
Sort sort = new Sort(Sort.Direction.DESC,"age");
//创建分页对象
org.springframework.data.domain.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");
//用户名判断条件
Predicate predicate = criteriaBuilder.like(usernamePath, "%1%");
return predicate;
}
}, pageable);
page.forEach(e-> System.out.println(e));
}
import com.github.wenhao.jpa.Specifications;
/*根据用户名进行模糊查询(wenhao)*/
@Test
public void testJpaSpec01() throws Exception{
Specification<Employee> specification = Specifications.<Employee>and()
.like("username", "%1%")
.build();
List<Employee> list = employeeRepository.findAll(specification);
list.forEach(e-> System.out.println(e));
}
/*根据用户名和邮件进行查询(规则)*/
@Test
public void testJpaSpec02() throws Exception{
Specification<Employee> specification = Specifications.<Employee>and()
.like("username", "%1%")
.like("email","%2%")
.build();
List<Employee> list = employeeRepository.findAll(specification);
list.forEach(e-> System.out.println(e));
}
@Test
public void testJpaSpec02() throws Exception{
//创建排序对象
Sort sort = new Sort(Sort.Direction.DESC,"age");
//创建分页对象
org.springframework.data.domain.Pageable pageable = new PageRequest(0,10,sort);
Specification<Employee> specification = Specifications.<Employee>and()
.like("username", "%1%")
.build();
Page<Employee> page = employeeRepository.findAll(specification, pageable);
page.forEach(e-> System.out.println(e));
}
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
/**
* 创建父类的作用:
* 1.提供一些公共的属性的方法(少写代码)
* 2.制定规范(对子类形成相应的规范)
* 3.为了以后代码的扩展性
*/
public abstract class BaseQuery {
//当前页
private int currentPage = 1;
//每页条数
private int pageSize = 10;
//排序字段(如果这个字段为null,就代表不排序)
private String orderName;
//排序类型 (true = DESC/ false = ASC)
private boolean orderType = false;
//排序的对象创建
public Sort createSort(){
if (StringUtils.isNotBlank(orderName)){
//如果有排序字段返回排序对象
Sort sort = new Sort(orderType ? Sort.Direction.DESC : Sort.Direction.ASC,orderName);
return sort;
}
return null;
}
//每个子类必须有查询规则的方法
public abstract Specification createSpec();
public int getCurrentPage() {
return currentPage;
}
//兼容JPA从0页作为起始页
public int getJPACurrentPage() {
return currentPage-1;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
//省略getter,setter
}
createSpec()
import com.github.wenhao.jpa.Specifications;
import com.lty.aisell.domain.Employee;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
public class EmployeeQuery extends BaseQuery {
//用户名
private String username;
//邮件
private String email;
//年龄
private Integer age;
/*返回查询规则*/
@Override
public Specification createSpec(){
Specification<Employee> specification = Specifications.<Employee>and()
.like(StringUtils.isNoneBlank(username),"username", "%" + username + "%")
.like(StringUtils.isNoneBlank(email),"email", "%" + email + "%")
.gt(age!=null,"age", age)
.build();
return specification;
}
//省略getter,setter
}
/*分页排序查询(wenhao)
* 模拟前台传数据
* */
@Test
public void testJpaSpec() throws Exception{
/*模拟前台传过来的数据*/
EmployeeQuery query = new EmployeeQuery();
query.setUsername("1");
query.setEmail("2");
query.setAge(20);
query.setOrderName("age");
query.setOrderType(true);
//创建排序对象
Sort sort = query.createSort();
//创建分页对象(分页对象从前台传过来)
Pageable pageable = new PageRequest(query.getJPACurrentPage(),query.getPageSize(),sort);
//创建查询对象
Specification specification = query.createSpec();
//功能执行
Page<Employee> page = employeeRepository.findAll(specification, pageable);
page.forEach(e-> System.out.println(e));
}