wisdomsell-day1(智能商贸系统第一天)

wisdomsell-day1(智能商贸系统第一天)

1. 导包

该系统会用到的框架Spring+SpringMVC+SpringDataJpa

SpringDataJpa是springJpa的一个自框架,等于将后者进行了再度封装,而springJpa是对spring进行了再次封装

SpringDataJpa让操作数据库变得更为简单

<?xml version="1.0" encoding="UTF-8"?>

<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.itsource</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>UTF8
	</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><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${
     org.springframework.version}</version></dependency><!-- 上下文支持包(帮我们集成:模板,邮件,任务调度...) --><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${
     org.springframework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${
     org.springframework.version}</version></dependency><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><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${
     org.springframework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${
     org.springframework.version}</version><scope>test</scope></dependency><!-- 引入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><!-- SpringMCV上传需要用到io包--><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><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${
     org.hibernate.version}</version></dependency><!-- SpringDataJpa的支持包 --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>${
     spring-data-jpa.version}</version></dependency><!-- SpringData的擴展包 --><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><!--lang3:工具包 java.lang.--><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包 --><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>

2. 配置jdbc.properties文件

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///pss
jdbc.username=root
jdbc.password=123456

3. 配置applicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<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:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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
">

    <!--扫描dao层-->
    <!--<context:component-scan base-package="com.yyk.aisell.repository" />-->
    <!--扫描service层-->
    <context:component-scan base-package="com.yyk.aisell.service" />

    <!--
        1.domain -> 2.jdbc.properties -> 3.dataSource -> 4.EntityManagerFactory
            -> 5.dao -> 6.service -> 7.集成SpringMVC -> 8.EasyUI
    -->
    <!--引入jdbc.properties  注意:必需写classpath-->
    <context:property-placeholder location="classpath:jdbc.properties" />

    <!--配置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>

    <!--
        配置:EntityManagerFactory
        alt+insert -》 jpa -》 最长的(LocalContainerEntityManagerFactoryBean)
            1.数据源  2.建表策略 3.方言  4.是否显示sql
    -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- packagesToScan:扫描包(JPA在扫描) -->
        <property name="packagesToScan" value="com.yyk.aisell.domain" />
        <!--
            jpaVendorAdapter:JPA的适配器
                JPA是一个ORM规范 -> 别人去实现(hibernate,openjpa,...)
                Spring怎么知道我用的哪一个实现? 告诉Spring用的是Hibernate
        -->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!-- true:相当于update  false:啥都不做 -->
                <property name="generateDdl" value="false" />
                <!-- 方言 -->
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
                <!-- 是否显示SQL -->
                <property name="showSql" value="true" />
            </bean>
        </property>
    </bean>

    <!--创建一个JPA的真的事务对象-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!--支持事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!--Spring data jpa 配置-->
    <jpa:repositories base-package="com.yyk.aisell.repository" transaction-manager-ref="transactionManager"
                      entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>

</beans>

4. 集成SpringDataJpa

注意:对各个类最好都抽取一个父类,这样可以让代码更规范,同时更有扩展性

基本类根据实际情况确定,我这里选择的是Employee员工类

4.1子类

@Entity
@Table(name = "employee")
public class Employee extends BaseDomain {
     private String username;private String password;private String email;private Integer age;public String getUsername() {
     return username;}public void setUsername(String username) {
     this.username = username;}public String getPassword() {
     return password;}public void setPassword(String password) {
     this.password = password;}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;}@Overridepublic String toString() {
     return "Employee{" +"username='" + username + '\'' +", password='" + password + '\'' +", email='" + email + '\'' +", age=" + age +", id=" + id +'}';}
}

4.2抽取的父类

这里要打上注解,才能让jpa知道你这个类的作用

//表示父类,jpa会自动判断,不会持久化到表中

@MappedSuperclass
public class BaseDomain {
     
    @Id
    @GeneratedValue
    protected Long id;
    public Long getId() {
     
        return id;
    }public void setId(Long id) {
     this.id = id;}

}

4.3创建一个接口Repository(相当于dao)

以后用dao还是Repository根据实际情况而定

这里需要在配置文件中开启扫描

entity-manager-factory-ref=“entityManagerFactory”>

创建接口

public interface EmployeeRepository extends JpaRepository

继承JpaRepository jpa就会自动完成CRUD

4.4完成CRUD测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class EmployeeRepositoryTest {
     
    @Autowired
    private EmployeeRepository employeeRepository;
    //查询所有
    @Test
     public void testFindAll()throws Exception{
     
         List<Employee> list = employeeRepository.findAll();
         list.forEach(e-> System.*out*.println(e));
     }
     //查询一条
     @Test
      public void testFindOne()throws Exception{
     
         employeeRepository.findOne(2L);
      }
     //增加
      @Test
      public void testAdd()throws Exception{
     
         Employee employee = new Employee();
         employee.setUsername("嘘嘘嘘");
         employee.setAge(30);
         employee.setEmail("[email protected]");
         employee.setPassword("123456");
         employeeRepository.save(employee);
     }
     //如果有一样的id就是修改,没有就是增加
     @Test
      public void testUpdate()throws Exception{
     
         Employee employee = new Employee();
         employee.setId(274L);
         employee.setUsername("大徐");
         employee.setAge(20);
         employee.setEmail("[email protected]");
         employee.setPassword("88888");
         employeeRepository.save(employee);
      }
     //删除
      @Test
      public void testDelete()throws Exception{
     
         employeeRepository.delete(275L);
      }

4.5完成排序

@Test
 public void testSort()throws Exception{
     
    Sort sort = new Sort(Sort.Direction.*DESC*,"age");
    List<Employee> list = employeeRepository.findAll(sort);
    list.forEach(e-> System.*out*.println(e));
}

4.6完成分页

@Test
 public void testPageList()throws Exception{
     
    //用父类去接收
    Pageable pageable = new PageRequest(0,10);

​    Page<Employee> page = employeeRepository.findAll(pageable);
​    System.*out*.println(page.getTotalPages());
​    page.forEach(e-> System.*out*.println(e));
}

4.7分页+排序

@Test
 public void testPageAndSort()throws Exception{
     
    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));
}

4.8根据条件查询

可以查阅文档

//根据用户名进行查询(规范名)
Employee findByUsername(String username);

//根据用户名模糊查询(规范名)
List findByUsernameLike(String username);

//根据用户名和邮件模糊查询(规范名)
List findByUsernameLikeAndEmailLike(String username,String email);

4.9注解Query查询

//根据用户名查询,用jpql查询
@Query(“Select o from Employee o where username=?1”)
Employee query01(String username);
//根据用户名模糊查询
@Query(“select o from Employee o where o.username like ?1”)
List query02(String username);

//根据用户名和邮件模糊查询
@Query(“select o from Employee o where o.username like ?1 and o.email like ?2”)
List query03(String username,String email);

**5.**JpaSpecificationExecutor

是一个JPA的规范执行者

JPA2.0提供的Criteria API的使用封装

是为了让某些完全不喜欢写sql语句的人直接完全用面向对象的方式去操作

需要我们的repositor去继承JpaSpecificationExecutor接口

5.1根据用户名模糊查询

//根据用户名进行模糊查询
@Test
public void testJpaSpecificationExecutor01()throws Exception{
/** 规则需要自己来定义 root 代表根 cq这里不如cb好用 cb主要是判断关系,连接起来 */

List<Employee> list =  employeeRepository.findAll(new Specification<Employee>() {
     
        @Override
        public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
     
            //1.拿到用户名
            Path username = root.get("username");
            //2.用户名进行判断
            Predicate predicate = cb.like(username, "%1%");
            return predicate;
        }
    });
   list.forEach(e-> System.*out*.println(e));
 }

5.2多条件模糊查询

//根据邮件和用户名进行查询
 @Test
 public void testJpaSpecificationExecutor02()throws Exception{
     
     List<Employee> list =  employeeRepository.findAll(new Specification<Employee>() {
     
         @Override
         public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
     
             //1.拿到用户名
             Path username = root.get("username");
             //拿到邮件,反正需要什么根,就去拿什么根
             Path email = root.get("email");
             Path age = root.get("age");
             //2.用户名进行判断
             Predicate predicate1 = cb.like(username, "%1%");
             Predicate predicate2 = cb.like(email, "%2%");
             Predicate predicate3 = cb.gt(age, 20);
             //将两个文件结合起来
             Predicate predicate = cb.and(predicate1, predicate2,predicate3);
             return predicate;
         }
     });
     list.forEach(e-> System.*out*.println(e));
 }

5.3分页+排序+查询

//查询+分页
@Test
public void testJpaSpecificationExecutor03()throws Exception{
     
    */***     ** 除了中间核心的需要修改外,其他上面的代码都是相同的,所以,专门有一个框架将它们抽取了出来*     ** 这就是最开始导入一个名字叫做扩展包的原因*     **/*    Sort sort = new Sort(Sort.Direction.*DESC*, "age");
    Pageable pageable = new PageRequest(0,10,sort);
    Page<Employee> list =  employeeRepository.findAll(new Specification<Employee>() {
     
        @Override
        public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
     
            //1.拿到用户名
            Path username = root.get("username");//2.用户名进行判断
​            Predicate predicate = cb.like(username, "%1%");return predicate;}},pageable);
​    list.forEach(e-> System.*out*.println(e));
}

6.Jpa-Spec

我们发现在测试的时候,除了查询的条件不一样,前面的都是一样的,那么为了简化代码,某些人就写了个框架Jpa-Spec用来简化JpaSpecificationExecutor

6.1根据用户名模糊查询

//根据用户名进行模糊查询
@Test
 public void testJpaSpecTest01()throws Exception{
     
    //拿到查询规则
       Specification<Employee> spec = Specifications.<Employee>*and*().like("username", "%1%")
               .like("email","%2%")
               .gt("age",20)
               .build();
       //进行查询
       List<Employee> list = employeeRepository.findAll(spec);
       list.forEach(e-> System.*out*.println(e));
   }

6.2多条件查询

//多条件查询 
@Test
  public void testJpaSpecTest02()throws Exception{
     
     //1.创建排序对象
     Sort sort = new Sort(Sort.Direction.*DESC*, "age");
     //2.创建分页对象
    Pageable pageable = new PageRequest(0,10,sort);
     //3.创建查询对象
     Specification<Employee> spec = Specifications.<Employee>*and*().like("username", "%1%")
             .like("email","%2%")
             .gt("age",20)
             .build();
     Page<Employee> list = employeeRepository.findAll(spec,pageable);
     list.forEach(e-> System.*out*.println(e));
  }

6.3分页+排序+查询

//分页+排序+查询
    @Test
        public void testJpaSpecTest03()throws Exception{
     
    //假设前台传过来了数据
    EmployeeQuery employeeQuery = new EmployeeQuery();
    //如果前台并没有传过来
    employeeQuery.setUsername("1");
    employeeQuery.setEmail("2");
    employeeQuery.setAge(20);
    //1.创建排序对象
    Sort sort = new Sort(Sort.Direction.*DESC*, "age");
    //2.创建分页对象
    Pageable pageable = new PageRequest(0,10,sort);
    //3.创建查询对象
    Specification<Employee> spec = Specifications.<Employee>*and*()
            .like(StringUtils.*isNotBlank*(employeeQuery.getUsername()),"username", "%"+employeeQuery.getUsername()+"%")
            .like(StringUtils.*isNotBlank*(employeeQuery.getEmail()),"email", "%"+employeeQuery.getEmail()+"%")
            .gt(employeeQuery.getAge()!=null,"age",employeeQuery.getAge())
            .build();
    Page<Employee> page = employeeRepository.findAll(spec,pageable);
    page.forEach(e-> System.*out*.println(e));
}

7.Query抽取(查询抽取)

查询的内容,以及按什么排序,都是前台传过来的,我们只负责接收就行

7.1子类

public class EmployeeQuery extends BaseQuery {
     
    private String username;private Integer age;private String email;//将它抽取到子类中,子类都要实现这个方法,所以让父类有这个方法,其他子类去重写@Overridepublic 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;}public String getUsername() {
     return username;}public void setUsername(String username) {
     this.username = username;}public Integer getAge() {
     return age;}public void setAge(Integer age) {
     this.age = age;}public String getEmail() {
     return email;}public void setEmail(String email) {
     this.email = email;}
}

7.2父类

让子类都要有creatSpec方法,父类提供一个抽象的方法

public abstract class BaseQuery {
     
    //因为是前台传过来的,所以是从1开始
    private int currentPage=1;
    private int pageSize=10;
    public abstract Specification creatSpec();public int getCurrentPage() {
     return currentPage;}*/***     ** 这里可以选择创建一个新的方法,让页数减1,或者直接在上面当前页数减1,主要都是为了兼容jpa*     ** 在项目中最好增加方法,而不要去改动别人的方法*     ** 如何排序以及按什么排序也是前台给的*     **/*    //排序字段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 int getJpaCurrentPage() {
     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 getOrderName() {
     return orderName;}public void setOrderName(String orderName) {
     this.orderName = orderName;}public boolean isOrderType() {
     return orderType;}public void setOrderType(boolean orderType) {
     this.orderType = orderType;}
}

7.3测试

@Test
public void testJpaSpecTest04()throws Exception{
     
    //假设前台传过来了数据
    EmployeeQuery employeeQuery = new EmployeeQuery();
    //如果前台并没有传过来
    employeeQuery.setUsername("1");
    employeeQuery.setEmail("2");
    //employeeQuery.setAge(20);
    employeeQuery.setOrderName("age");
    //1.创建排序对象
    Sort sort = employeeQuery.createSort();//2.创建分页对象
​    Pageable pageable = new PageRequest(employeeQuery.getJpaCurrentPage(),employeeQuery.getPageSize(),sort);//3.创建查询对象
​    Specification spec = employeeQuery.creatSpec();
​    Page<Employee> page = employeeRepository.findAll(spec,pageable);
​    page.forEach(e-> System.*out*.println(e));
}

你可能感兴趣的:(wisdomsell-day1(智能商贸系统第一天))