/**PageBeginHtml Block Begin **/ /***自定义返回顶部小火箭***/ /*生成博客目录的JS 开始*/ /*生成博客目录的JS 结束*/

SpringBoot 整合 jpa


SpringBoot 整合 jpa


1:项目代码结构图

image


2:pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.alan</groupId>
    <artifactId>SpringBootJpa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBootJpa</name>
    <description>SpringBootJpa</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3:启动类 SpringBootJpaApplication

package com.alan.SpringBootJpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootJpaApplication.class, args);
    }

}



4: 配置文件  application.properties


### 此版本为mysql 5.X 的 sql连接驱动器使用方法###
# spring.datasource.driverClassName=com.mysql.jdbc.Driver
### 此版本为mysql 6.X 以上 的 sql连接驱动器使用方法###
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=123456
#配置数据库连接池信息
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

#配置Spring Jpa 信息
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true


5: 实体类:Users

package com.alan.SpringBootJpa.pojo;

import javax.persistence.*;
import javax.print.attribute.standard.MediaSize;

/*
 *
 *
 * @author: Alan_liu
 * @date 2021/5/26 21:21
 */
@Entity
@Table(name ="t_users")
public class Users {


   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id")
   private Integer id;
   @Column(name = "name")
   private String name;
   @Column(name="age")
   private  Integer age;
   @Column(name = "address")
   private  String  address;


    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}


6: dao层  UsersRepository

package com.alan.SpringBootJpa.dao;
/*
 *  参数一 T:当前需要映射的是实体
 *  参数二 Id:当前映射的实体中的OID的类型
 *
 * @author: Alan_liu
 * @date 2021/5/26 21:26
 */

import com.alan.SpringBootJpa.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UsersRepository  extends JpaRepository<Users,Integer> {


}


测试类:UserRepositoryTest

package com.alan.SpringBootJpa;


import com.alan.SpringBootJpa.dao.UsersRepository;
import com.alan.SpringBootJpa.dao.UsersRepositoryByName;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;


/*
 *  测试类
 *
 * @author: Alan_liu
 * @date 2021/5/26 21:30
 */
@SpringBootTest(classes =SpringBootJpaApplication.class )
public class UserRepositoryTest {
    @Autowired
    private UsersRepository  usersRepository;

    @Test
    public void testSave(){
        Users users=new Users();
        users.setAddress("广东省广州市天河区华南师范大学");
        users.setAge(20);
        users.setName("李四");
        this.usersRepository.save(users);
    }


}



以下是 jar包里的被继承的dao层

/*
 * Copyright 2008-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.jpa.repository;

import java.util.List;

import javax.persistence.EntityManager;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

/**
 * JPA specific extension of {@link org.springframework.data.repository.Repository}.
 *
 * @author Oliver Gierke
 * @author Christoph Strobl
 * @author Mark Paluch
 * @author Sander Krabbenborg
 * @author Jesse Wouters
 */
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.CrudRepository#findAll()
	 */
	@Override
	List<T> findAll();

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
	 */
	@Override
	List<T> findAll(Sort sort);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
	 */
	@Override
	List<T> findAllById(Iterable<ID> ids);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
	 */
	@Override
	<S extends T> List<S> saveAll(Iterable<S> entities);

	/**
	 * Flushes all pending changes to the database.
	 */
	void flush();

	/**
	 * Saves an entity and flushes changes instantly.
	 *
	 * @param entity entity to be saved. Must not be {@literal null}.
	 * @return the saved entity
	 */
	<S extends T> S saveAndFlush(S entity);

	/**
	 * Saves all entities and flushes changes instantly.
	 *
	 * @param entities entities to be deleted. Must not be {@literal null}.
	 * @return the saved entities
	 * @since 2.5
	 */
	<S extends T> List<S> saveAllAndFlush(Iterable<S> entities);

	/**
	 * Deletes the given entities in a batch which means it will create a single query. This kind of operation leaves JPAs
	 * first level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this
	 * method.
	 *
	 * @param entities entities to be deleted. Must not be {@literal null}.
	 * @deprecated Use {@link #deleteAllInBatch(Iterable)} instead.
	 */
	@Deprecated
	default void deleteInBatch(Iterable<T> entities){deleteAllInBatch(entities);}

	/**
	 * Deletes the given entities in a batch which means it will create a single query. This kind of operation leaves JPAs
	 * first level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this
	 * method.
	 *
	 * @param entities entities to be deleted. Must not be {@literal null}.
	 * @since 2.5
	 */
	void deleteAllInBatch(Iterable<T> entities);


	/**
	 * Deletes the entities identified by the given ids using a single query. This kind of operation leaves JPAs first
	 * level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this method.
	 *
	 * @param ids the ids of the entities to be deleted. Must not be {@literal null}.
	 * @since 2.5
	 */
	void deleteAllByIdInBatch(Iterable<ID> ids);

	/**
	 * Deletes all entities in a batch call.
	 */
	void deleteAllInBatch();

	/**
	 * Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is
	 * implemented this is very likely to always return an instance and throw an
	 * {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers
	 * immediately.
	 *
	 * @param id must not be {@literal null}.
	 * @return a reference to the entity with the given identifier.
	 * @see EntityManager#getReference(Class, Object) for details on when an exception is thrown.
	 * @deprecated use {@link JpaRepository#getById(ID)} instead.
	 */
	@Deprecated
	T getOne(ID id);

	/**
	 * Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is
	 * implemented this is very likely to always return an instance and throw an
	 * {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers
	 * immediately.
	 *
	 * @param id must not be {@literal null}.
	 * @return a reference to the entity with the given identifier.
	 * @see EntityManager#getReference(Class, Object) for details on when an exception is thrown.
	 * @since 2.5
	 */
	T getById(ID id);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
	 */
	@Override
	<S extends T> List<S> findAll(Example<S> example);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
	 */
	@Override
	<S extends T> List<S> findAll(Example<S> example, Sort sort);
}
/*
 * Copyright 2008-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

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

/**
 * Extension of {@link CrudRepository} to provide additional methods to retrieve entities using the pagination and
 * sorting abstraction.
 *
 * @author Oliver Gierke
 * @see Sort
 * @see Pageable
 * @see Page
 */
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

	/**
	 * Returns all entities sorted by the given options.
	 *
	 * @param sort
	 * @return all entities sorted by the given options
	 */
	Iterable<T> findAll(Sort sort);

	/**
	 * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
	 *
	 * @param pageable
	 * @return a page of entities
	 */
	Page<T> findAll(Pageable pageable);
}


/*
 * Copyright 2008-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

import java.util.Optional;

/**
 * Interface for generic CRUD operations on a repository for a specific type.
 *
 * @author Oliver Gierke
 * @author Eberhard Wolff
 * @author Jens Schauder
 */
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {

	/**
	 * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
	 * entity instance completely.
	 *
	 * @param entity must not be {@literal null}.
	 * @return the saved entity; will never be {@literal null}.
	 * @throws IllegalArgumentException in case the given {@literal entity} is {@literal null}.
	 */
	<S extends T> S save(S entity);

	/**
	 * Saves all given entities.
	 *
	 * @param entities must not be {@literal null} nor must it contain {@literal null}.
	 * @return the saved entities; will never be {@literal null}. The returned {@literal Iterable} will have the same size
	 *         as the {@literal Iterable} passed as an argument.
	 * @throws IllegalArgumentException in case the given {@link Iterable entities} or one of its entities is
	 *           {@literal null}.
	 */
	<S extends T> Iterable<S> saveAll(Iterable<S> entities);

	/**
	 * Retrieves an entity by its id.
	 *
	 * @param id must not be {@literal null}.
	 * @return the entity with the given id or {@literal Optional#empty()} if none found.
	 * @throws IllegalArgumentException if {@literal id} is {@literal null}.
	 */
	Optional<T> findById(ID id);

	/**
	 * Returns whether an entity with the given id exists.
	 *
	 * @param id must not be {@literal null}.
	 * @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
	 * @throws IllegalArgumentException if {@literal id} is {@literal null}.
	 */
	boolean existsById(ID id);

	/**
	 * Returns all instances of the type.
	 *
	 * @return all entities
	 */
	Iterable<T> findAll();

	/**
	 * Returns all instances of the type {@code T} with the given IDs.
	 * <p>
	 * If some or all ids are not found, no entities are returned for these IDs.
	 * <p>
	 * Note that the order of elements in the result is not guaranteed.
	 *
	 * @param ids must not be {@literal null} nor contain any {@literal null} values.
	 * @return guaranteed to be not {@literal null}. The size can be equal or less than the number of given
	 *         {@literal ids}.
	 * @throws IllegalArgumentException in case the given {@link Iterable ids} or one of its items is {@literal null}.
	 */
	Iterable<T> findAllById(Iterable<ID> ids);

	/**
	 * Returns the number of entities available.
	 *
	 * @return the number of entities.
	 */
	long count();

	/**
	 * Deletes the entity with the given id.
	 *
	 * @param id must not be {@literal null}.
	 * @throws IllegalArgumentException in case the given {@literal id} is {@literal null}
	 */
	void deleteById(ID id);

	/**
	 * Deletes a given entity.
	 *
	 * @param entity must not be {@literal null}.
	 * @throws IllegalArgumentException in case the given entity is {@literal null}.
	 */
	void delete(T entity);

	/**
	 * Deletes all instances of the type {@code T} with the given IDs.
	 *
	 * @param ids must not be {@literal null}. Must not contain {@literal null} elements.
	 * @throws IllegalArgumentException in case the given {@literal ids} or one of its elements is {@literal null}.
	 * @since 2.5
	 */
	void deleteAllById(Iterable<? extends ID> ids);

	/**
	 * Deletes the given entities.
	 *
	 * @param entities must not be {@literal null}. Must not contain {@literal null} elements.
	 * @throws IllegalArgumentException in case the given {@literal entities} or one of its entities is {@literal null}.
	 */
	void deleteAll(Iterable<? extends T> entities);

	/**
	 * Deletes all entities managed by the repository.
	 */
	void deleteAll();
}


/*
 * Copyright 2011-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

import org.springframework.stereotype.Indexed;

/**
 * Central repository marker interface. Captures the domain type to manage as well as the domain type's id type. General
 * purpose is to hold type information as well as being able to discover interfaces that extend this one during
 * classpath scanning for easy Spring bean creation.
 * <p>
 * Domain repositories extending this interface can selectively expose CRUD methods by simply declaring methods of the
 * same signature as those declared in {@link CrudRepository}.
 *
 * @see CrudRepository
 * @param <T> the domain type the repository manages
 * @param <ID> the type of the id of the entity the repository manages
 * @author Oliver Gierke
 */
@Indexed
public interface Repository<T, ID> {

}


/*
 * Copyright 2016-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository.query;

import java.util.Optional;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

/**
 * Interface to allow execution of Query by Example {@link Example} instances.
 *
 * @param <T>
 * @author Mark Paluch
 * @author Christoph Strobl
 * @since 1.12
 */
public interface QueryByExampleExecutor<T> {

	/**
	 * Returns a single entity matching the given {@link Example} or {@literal null} if none was found.
	 *
	 * @param example must not be {@literal null}.
	 * @return a single entity matching the given {@link Example} or {@link Optional#empty()} if none was found.
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the Example yields more than one result.
	 */
	<S extends T> Optional<S> findOne(Example<S> example);

	/**
	 * Returns all entities matching the given {@link Example}. In case no match could be found an empty {@link Iterable}
	 * is returned.
	 *
	 * @param example must not be {@literal null}.
	 * @return all entities matching the given {@link Example}.
	 */
	<S extends T> Iterable<S> findAll(Example<S> example);

	/**
	 * Returns all entities matching the given {@link Example} applying the given {@link Sort}. In case no match could be
	 * found an empty {@link Iterable} is returned.
	 *
	 * @param example must not be {@literal null}.
	 * @param sort the {@link Sort} specification to sort the results by, must not be {@literal null}.
	 * @return all entities matching the given {@link Example}.
	 * @since 1.10
	 */
	<S extends T> Iterable<S> findAll(Example<S> example, Sort sort);

	/**
	 * Returns a {@link Page} of entities matching the given {@link Example}. In case no match could be found, an empty
	 * {@link Page} is returned.
	 *
	 * @param example must not be {@literal null}.
	 * @param pageable can be {@literal null}.
	 * @return a {@link Page} of entities matching the given {@link Example}.
	 */
	<S extends T> Page<S> findAll(Example<S> example, Pageable pageable);

	/**
	 * Returns the number of instances matching the given {@link Example}.
	 *
	 * @param example the {@link Example} to count instances for. Must not be {@literal null}.
	 * @return the number of instances matching the {@link Example}.
	 */
	<S extends T> long count(Example<S> example);

	/**
	 * Checks whether the data store contains elements that match the given {@link Example}.
	 *
	 * @param example the {@link Example} to use for the existence check. Must not be {@literal null}.
	 * @return {@literal true} if the data store contains elements that match the given {@link Example}.
	 */
	<S extends T> boolean exists(Example<S> example);
}


SpringBoot Data Jpa 提供的核心接口: Repository


API 文档

关键字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEqual findByAgeGreaterThanEqual where age >= ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?

StartingWith

findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
NotIn findByIdNotIn(Collection<?> c) where id not  in (?)
True

findByAaaTue

where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)
top findTop100 top 10/where ROWNUM <=10


示例:UsersRepositoryByName


package com.alan.SpringBootJpa.dao;
/*
 *  Repository 接口的方法名称命名查询
 *
 * @author: Alan_liu
 * @date 2021/5/28 21:22
 */
import com.alan.SpringBootJpa.pojo.Users;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;

import java.util.Collection;
import java.util.List;

 public   interface UsersRepositoryByName extends Repository<Users,Integer> {

  /****
   *   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *    *      *  根据  id  全等于的条件进行查询
   *    *      *
   *    *      *  关键字             方法命名                 sql where字句
   *    *      *   Is,Equals       findByIdIs               where id= ?
   *
    *
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 20:25
   */
   List<Users> findByIdIs(@Param("id") Integer id);
    /***
     *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
     *      *  根据  id  全等于的条件进行查询
     *      *
     *      *  关键字             方法命名                 sql where字句
     *      *   Is,Equals       findByIdEquals          where id= ?
     * @return {@link List<Users>}
     * @user Alan_liu
     * @date 2021/5/28 22:14
     */
   List<Users> findByIdEquals(Integer id);

  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  根据  id  全等于的条件进行查询
   *      *
   *      *  关键字             方法命名                 sql where字句
   *      *   Between      findByIdBetween           where id between ? and ?
    * @param startId  开始值
   * @param endId     结束值
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 22:20
   */
    List<Users> findByIdBetween(Integer startId,Integer endId);

  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  根据  id  全等于的条件进行查询
   *      *
   *      *  关键字             方法命名                 sql where字句
   *      *   LessThan      findByIdLessThan          where id <= ?

   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 22:22
   */
   List<Users>  findByIdLessThan(Integer id);
  /****
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  根据  id  全等于的条件进行查询
   *      *
   *      *  关键字             方法命名                 sql where字句
   *      *   LessThanEquals      findByIdLessThanEqual          where id <= ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 20:45
   */
   List<Users>   findByIdLessThanEqual ( Integer id);

  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  根据  id  全等于的条件进行查询
   *      *
   *      *  关键字             方法命名                 sql where字句
   *      *   GreaterThan      findByIdGreaterThan          where id > ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 22:49
   */
   List<Users>  findByIdGreaterThan( Integer id);
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                     方法命名                       sql where字句
   *      *   GreaterThanEqual      findByAgeGreaterThanEqual       where age >= ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 22:51
   */
    List<Users> findByAgeGreaterThanEqual(Integer age);
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字          方法命名             sql where字句
   *      *   After      findByIdAfter       where id > ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 22:52
   */
   List<Users> findByIdAfter(Integer id);

  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字          方法命名             sql where字句
   *      *   Before      findByIdBefore       where id < ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 22:58
   */
   List<Users> findByIdBefore(Integer id);

  /***
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字          方法命名             sql where字句
   *      *   IsNull      findByNameIsNull     where name is null
   */
   List<Users> findByNameIsNull();

  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   isNotNull,NotNull      findByNameNotNull     where name is not null
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 20:23
   */
   List<Users> findByNameNotNull();

  /***
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   Like                findByNameLike           where name like ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 21:45
   */
  List<Users> findByNameLike(String name );
  /**
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   NotLike                findByNameNotLike        where name not like ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 14:35
   */
   List<Users> findByNameNotLike(String name );
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   StartingWith        findByNameStartingWith       where name like '?%'
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 14:36
   */
   List<Users> findByNameStartingWith(String name );
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   EndingWith        findByNameEndingWith       where name like '%?'
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 14:37
   */
   List<Users> findByNameEndingWith(String name );
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   Containing        findByNameContaining       where name like '%?%'
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 14:38
   */
   List<Users> findByNameContaining(String name );

  /**
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   OrderBy        findByIdOrderByXDesc       where id=? order by id desc

   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 14:40
   */
   List<Users>  findByIdOrderByIdDesc(Integer id );
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名     sql where字句
   *      *   Not        findByNameNot              where name <> ?
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 14:41
   */
   List<Users> findByNameNot(String name  );


  /**
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   In        findByIdIn(Collection<?> c)       where id in (?)
   */
   List<Users> findByIdIn(Collection<?> c) ;

   /***
    *
    *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
    *      *  关键字                    方法命名                   sql where字句
    *      *   NotIn        findByIdNotIn(Collection<?> c)      where id not  in (?)
    * @return {@link List<Users>}
    * @user Alan_liu
    * @date 2021/5/29 17:36
    */
   List<Users> findByIdNotIn(Collection<?> c) ;
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字                    方法命名                   sql where字句
   *      *   True        findByIdTrue        where id = true
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 17:37
   */
   List<Users>   findByIdTrue() ;
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字        方法命名                   sql where字句
   *      *   False        findByAaaFalse             where aaa = false
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 17:37
   */
   List<Users> findByIdFalse() ;

  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字        方法命名                   sql where字句
   *      *   IgnoreCase        findByNameIgnoreCase      where UPPER(name)=UPPER(?)
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 17:38
   */
   List<Users> findByNameIgnoreCase(String name) ;
  /***
   *
   *      *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   *      *  关键字        方法命名       sql where字句
   *      *   top        findTop100    	top 10/where ROWNUM <=10
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/29 17:38
   */
   List<Users>  findTopByName(String name) ;

  /***
     *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
     * 根据名字查询 sql的查询条件值为全等于
     *      *  关键字             方法命名                 sql where字句
     *      *                  findByName             where name= ?
     * @return {@link List<Users>}
     * @user Alan_liu
     * @date 2021/5/28 21:25
     */
     List<Users> findByNameEquals(String name);



    /**
     *  说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
     *  根据  name 和年龄 全等于的条件进行查询
     *
     *  关键字             方法命名                 sql where字句
     *  And         findByNameAndAgeEquals      where name= ? and age =?
     */
   List<Users>  findByNameAndAgeEquals(String name ,Integer age);

  /**
   * 说明:方法的名称必须要遵循 驼峰式命名;其命名格式:findBy(关键字)+属性名称(首字母要大写)+查询条件(字母大写)
   * 根据 用户名或者是年龄进行 全等于的条件值查询
   *
   *      *  关键字             方法命名                 sql where字句
   *      *  Or         findByNameOrAgeEquals      where name= ? or age=?
   *
   * @return {@link List<Users>}
   * @user Alan_liu
   * @date 2021/5/28 21:40
   */
    List<Users> findByNameOrAgeEquals(String name , Integer age);



}


被继承接口:Repository

/*
 * Copyright 2011-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

import org.springframework.stereotype.Indexed;

/**
 * Central repository marker interface. Captures the domain type to manage as well as the domain type's id type. General
 * purpose is to hold type information as well as being able to discover interfaces that extend this one during
 * classpath scanning for easy Spring bean creation.
 * <p>
 * Domain repositories extending this interface can selectively expose CRUD methods by simply declaring methods of the
 * same signature as those declared in {@link CrudRepository}.
 *
 * @see CrudRepository
 * @param <T> the domain type the repository manages
 * @param <ID> the type of the id of the entity the repository manages
 * @author Oliver Gierke
 */
@Indexed
public interface Repository<T, ID> {

}


测试类:UsersRepositoryByNameTest

package com.alan.SpringBootJpa;

/*
 * @author: Alan_liu
 * @date 2021/5/29 19:03
 */

import com.alan.SpringBootJpa.dao.UsersRepositoryByName;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
@SpringBootTest(classes =SpringBootJpaApplication.class )
public class UsersRepositoryByNameTest {
    @Autowired
    private UsersRepositoryByName usersRepositoryByName;
    @Test
    public  void testFindByNameEquals(){
        List<Users> list=this.usersRepositoryByName.findByNameEquals("李四");
        System.out.println(list.toString());
    }

    @Test
    public  void testFindByNameAndAgeEquals(){
        List<Users> list=this.usersRepositoryByName.findByNameAndAgeEquals("李四",20);
        System.out.println(list.toString());
    }

    @Test
    public  void testFindByNameOrAgeEquals(){
        List<Users> list=this.usersRepositoryByName.findByNameOrAgeEquals("李四",21);
        System.out.println(list.toString());
    }

    @Test
    public  void testFindByNameLike(){
        List<Users> list=this.usersRepositoryByName.findByNameLike("李%");
        System.out.println(list.toString());
    }

}


398ba7aeb5e7e532c032742309db377

1ccc8d41a5b335c4717d3cef41632f7

3182c0edd9e63e3b2cf5010ab38480f


72df778792aed95b2fe4e008560d34e

991c613c455c8f361d4e5b6384e87a9


示例:UsersRepositoryQueryAnnotation


package com.alan.SpringBootJpa.dao;
/*
 * Repository @query 的查询使用方法
 *
 * @author: Alan_liu
 * @date 2021/5/29 18:54
 */

import com.alan.SpringBootJpa.pojo.Users;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;

import javax.persistence.criteria.CriteriaBuilder;
import java.util.List;

/**
 * Repository @query 的查询使用方法
 */
public interface UsersRepositoryQueryAnnotation extends Repository<Users,Integer> {


    /***
     *
     *  注意:from Users  where name = ?1
     *    这个 “?1”的1 表示是获取入参的第一个参数
     * @return {@link List<Users>}
     * @throws
     * @user Alan_liu
     * @date 2021/5/29 18:59
     */
    @Query(" from Users  where name = ?1")
    List<Users> queryByNameUseHQL(String  name);

    /***
     *
     *   nativeQuery :表示 该sql 是否是标准的 sql语句。
     *    默认值为false 。执行的时候会告诉底层这是一个非标准的sql语句,底层会去执行hibernate解析hql语句 为标准的sql语句
     *    true 标准该sql 为标准的sql语句
      * @param name
     * @return {@link List<Users>}
     * @throws
     * @user Alan_liu
     * @date 2021/5/29 21:06
     */
    @Query( value="SELECT  * FROM  t_users where name=?1 ",nativeQuery = true)
    List<Users> queryByNameUseSQL(String name);

    /**
     *
     *   nativeQuery :表示 该sql 是否是标准的 sql语句。
     *    默认值为false 。执行的时候会告诉底层这是一个非标准的sql语句,底层会去执行hibernate解析hql语句 为标准的sql语句
     *    true 标准该sql 为标准的sql语句
     *
     *  注意:SELECT  * FROM  t_users where name=?1 and  id=?2
     *    这个 “?1”的1 表示是获取入参的第一个参数  “?2” 的2 表示获取入参的第二个参数
     * @return {@link List<Users>}
     * @throws
     * @user Alan_liu
     * @date 2021/5/29 21:28
     */
    @Query( value="SELECT  * FROM  t_users where name=?1 and  id=?2 ",nativeQuery = true)
    List<Users> queryByNameAndIdUseSQL(String name,Integer id);

    /***
     *
     *
     * @user Alan_liu
     * @date 2021/5/29 21:36
     */
    @Query("update Users set name =?1 where id=?2 ")
    @Modifying //需要执行一个更新操作
    void updateUsersNameById(String name ,Integer id);

    /***
     *
     *   nativeQuery :表示 该sql 是否是标准的 sql语句。
     *    默认值为false 。执行的时候会告诉底层这是一个非标准的sql语句,底层会去执行hibernate解析hql语句 为标准的sql语句
     *    true 标准该sql 为标准的sql语句
     * @param name
     * @return {@link List<Users>}
     * @throws
     * @user Alan_liu
     * @date 2021/5/29 21:06
     */
    @Query( value="SELECT  * FROM  t_users where id=?1 ",nativeQuery = true)
    List<Users> queryByIdUseSQL(Integer id);

}


测试示例:UsersRepositoryQueryAnnotationTest

package com.alan.SpringBootJpa;

import com.alan.SpringBootJpa.dao.UsersRepositoryQueryAnnotation;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;

import javax.transaction.Transactional;
import java.util.List;

/*
 *  UsersRepositoryQueryAnnotation 接口的测试类
 *
 * @author: Alan_liu
 * @date 2021/5/29 18:58
 */
@SpringBootTest(classes =SpringBootJpaApplication.class )
public class UsersRepositoryQueryAnnotationTest {

    @Autowired
    private UsersRepositoryQueryAnnotation usersRepositoryQueryAnnotation;

    /***
     * Repository --@query 测试
     *   HQL 测试
      * @param
     * @return {@link void}
     * @throws
     * @user Alan_liu
     * @date 2021/5/29 19:59
     */
    @Test
    public  void testQueryByNameUseHQL(){
        List<Users> list=this.usersRepositoryQueryAnnotation.queryByNameUseHQL("李思");
        System.out.println(list.toString());
    }

    @Test
    public  void testQueryByNameUseSQL(){
        List<Users> list=this.usersRepositoryQueryAnnotation.queryByNameUseSQL("李四");
        System.out.println(list.toString());
    }

    @Test
    public  void testQueryByNameAndIdUseSQL(){
        List<Users> list=this.usersRepositoryQueryAnnotation.queryByNameAndIdUseSQL("李四",8);
        System.out.println(list.toString());
    }
    /***
     *  测试更新情况
     *
     * @user Alan_liu
     * @date 2021/5/29 21:39
     */
    @Test
    @Transactional   //增加事务处理注解  当  @Transactional 与 @Test 的注解一起使用时,update ,insert 等sql操作事务是自动回滚的
    @Rollback(value = false)  //取消自动回滚机制
    public  void testUpdateUsersNameById(){
        List<Users> listName=this.usersRepositoryQueryAnnotation.queryByNameAndIdUseSQL("李四",8);
        System.out.println("“----更新前数据结果情况:-------”"+listName.toString());
        this.usersRepositoryQueryAnnotation.updateUsersNameById("李五",8);
        List<Users> listId=this.usersRepositoryQueryAnnotation.queryByIdUseSQL(8);
        System.out.println("“----更新后数据结果情况:-------”"+listId.toString());
    }
}


ccd14fb7d246c237b2fcb10303b8fe4

ca0373e1d7917fe6ebf6a25de11668d

dc034ab6970903cbc863ab7e100fd6c

3d5236ebd66b82ff7fdf387b1908c62


SpringBoot Data Jpa 提供的核心接口: CrudRepository 接口



示例:UsersRepositoryCrudRepository

package com.alan.SpringBootJpa.dao;
/*
 *  CrudRepository 接口:主要是完成一些增删改查的操作。
 *  注意:CrudRepository 接口继承了 Repository 接口
 *
 * @author: Alan_liu
 * @date 2021/5/29 22:03
 */

import com.alan.SpringBootJpa.pojo.Users;
import org.springframework.data.repository.CrudRepository;
/**
 *  CrudRepository 的所有方法
 *  save(s) <s extends T >:s
 *  save(Iterables<s>)<S extends T> :Iterables<S>
 *  findOne(ID):T
 *  exists(ID):boolean
 *  findAll():Iterable<T>
 *  findAll(Iterable<ID>):Iterable<T>
 *  count()
 *  delete(ID):void
 *  delete(T):void
 *  delete(Iterable<? extends T>):void
 *  deleteAll():void
 *
 */
public interface UsersRepositoryCrudRepository extends CrudRepository<Users,Integer> {


}


测试类:UsersRepositoryCrudRepositoryTest

package com.alan.SpringBootJpa;/*
 * Todo
 *
 * @author: Alan_liu
 * @date 2021/5/29 22:17
 */

import com.alan.SpringBootJpa.dao.UsersRepositoryCrudRepository;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Optional;

@SpringBootTest(classes =SpringBootJpaApplication.class )
public class UsersRepositoryCrudRepositoryTest {
    @Autowired
    private UsersRepositoryCrudRepository usersRepositoryCrudRepository;

    @Test
    public void testCrudRepositorySave(){
        Users users=new Users();
        users.setAddress("广东省广州市天河区华南师范大学");
        users.setAge(35);
        users.setName("李九");
        this.usersRepositoryCrudRepository.save(users);
    }

    @Test
    public void testCrudRepositoryUpdate(){
        Users users=new Users();
        users.setAddress("广东省广州市天河区华南师范大学1");
        users.setAge(40);
        users.setName("李九九");
        users.setId(11);
        this.usersRepositoryCrudRepository.save(users);
    }

    @Test
    public void testCrudRepositoryFindOne(){
        Optional<Users> list= this.usersRepositoryCrudRepository.findById(11);
        System.out.println(list.toString());
    }

    @Test
    public void testCrudRepositoryFindAll(){
        List<Users> list= (List<Users>) this.usersRepositoryCrudRepository.findAll();
        for(Users u:list){
            System.out.println(u);
        }
    }

    @Test
    public void testCrudRepositoryDeleteById(){
         this.usersRepositoryCrudRepository.deleteById(11);
    }

}

82e67baa6c56a99065f1a7ff80dcbc9daac41cb8b44897eaee41086c45623f966662a4be086c9babfc7cd4b311e7ad004ada05d3d6d900b8e17d1597de64db128e8c3f9ae2271d83286c6d5f184



SpringBoot Data Jpa 提供的核心接口: PagingAndSortingRepository 接口



PagingAndSortingRepository


/*
 * Copyright 2008-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

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

/**
 * Extension of {@link CrudRepository} to provide additional methods to retrieve entities using the pagination and
 * sorting abstraction.
 *
 * @author Oliver Gierke
 * @see Sort
 * @see Pageable
 * @see Page
 */
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

	/**
	 * Returns all entities sorted by the given options.
	 *
	 * @param sort
	 * @return all entities sorted by the given options
	 */
	Iterable<T> findAll(Sort sort);

	/**
	 * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
	 *
	 * @param pageable
	 * @return a page of entities
	 */
	Page<T> findAll(Pageable pageable);
}


示例:UsersRepositoryPagingAndSortingRepository


package com.alan.SpringBootJpa.dao;
/*
 *
 * @author: Alan_liu
 * @date 2021/5/29 23:12
 */

import com.alan.SpringBootJpa.pojo.Users;
import org.springframework.data.repository.PagingAndSortingRepository;

/***
 *
 *
 * @user Alan_liu
 * @date 2021/5/29 23:14
 */
public interface UsersRepositoryPagingAndSortingRepository extends PagingAndSortingRepository<Users,Integer> {

}


测试:UsersRepositoryPagingAndSortingRepositoryTest


package com.alan.SpringBootJpa;/*
 *
 *
 * @author: Alan_liu
 * @date 2021/5/29 23:15
 */

import com.alan.SpringBootJpa.dao.UsersRepositoryPagingAndSortingRepository;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.util.List;

@SpringBootTest(classes =SpringBootJpaApplication.class )
public class UsersRepositoryPagingAndSortingRepositoryTest {

    @Autowired
    private UsersRepositoryPagingAndSortingRepository usersRepositoryPagingAndSortingRepository;

    /***
     *
     *  排序测试
     * @throws
     * @user Alan_liu
     * @date 2021/5/30 12:13
     */
    @Test
    public void testUsersRepositoryPagingAndSortingRepositorySort(){
        //Order 定义排序规则
        //sort 对象封装了排序规则
        List<Users> list=(List<Users>) this.usersRepositoryPagingAndSortingRepository.findAll(Sort.by(Sort.Direction.DESC,"id"));
        for(Users u:list){
            System.out.println(u.toString());
        }
    }
    /***
     *
     *  分页
     * @param
     * @return {@link void}
     * @throws
     * @user Alan_liu
     * @date 2021/5/30 12:32
     */
    @Test
    public void testUsersRepositoryPagingAndSortingRepositoryPaging(){
        //pageable :封装了分页的参数,当前页,每页显示的条数。注意:它的当前页是从0开始的
        //pageable(page,size) page:当前页,size:每页显示的条数
        Pageable pageable=PageRequest.of(0,10) ;
        Page<Users> usersPage=this.usersRepositoryPagingAndSortingRepository.findAll(pageable);
        System.out.println("数据总条数:"+usersPage.getTotalElements());
        System.out.println("数据总页数:"+usersPage.getTotalPages());
        List<Users> list =usersPage.getContent();//获取出现数据信息
        for(Users u:list){
            System.out.println(u.toString());
        }
    }
    /***
     *
     *  排序 加 分页
      * @param
     * @return {@link void}
     * @throws
     * @user Alan_liu
     * @date 2021/5/30 12:32
     */
    @Test
    public void testUsersRepositoryPagingAndSortingRepositoryPagingAndSort(){
        //pageable :封装了分页的参数,当前页,每页显示的条数。注意:它的当前页是从0开始的
        //pageable(page,size) page:当前页,size:每页显示的条数
        Sort sort = Sort.by(Sort.Direction.DESC,"id");
        Pageable pageable=PageRequest.of(0,10,sort) ;
        Page<Users> usersPage=this.usersRepositoryPagingAndSortingRepository.findAll(pageable);
        System.out.println("数据总条数:"+usersPage.getTotalElements());
        System.out.println("数据总页数:"+usersPage.getTotalPages());
        List<Users> list =usersPage.getContent();//获取出现数据信息
        for(Users u:list){
            System.out.println(u.toString());
        }
    }

}

66309c7b84382ed92071b9dfe99ff6072e5e1f0f55752c949ab5e45a303ad3

16bfd24cd3d627fda721441cd3f845e


SpringBoot Data Jpa 提供的核心接口:  JpaRepository 接口


JpaRepository

/*
 * Copyright 2008-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.jpa.repository;

import java.util.List;

import javax.persistence.EntityManager;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

/**
 * JPA specific extension of {@link org.springframework.data.repository.Repository}.
 *
 * @author Oliver Gierke
 * @author Christoph Strobl
 * @author Mark Paluch
 * @author Sander Krabbenborg
 * @author Jesse Wouters
 */
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.CrudRepository#findAll()
	 */
	@Override
	List<T> findAll();

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
	 */
	@Override
	List<T> findAll(Sort sort);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
	 */
	@Override
	List<T> findAllById(Iterable<ID> ids);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
	 */
	@Override
	<S extends T> List<S> saveAll(Iterable<S> entities);

	/**
	 * Flushes all pending changes to the database.
	 */
	void flush();

	/**
	 * Saves an entity and flushes changes instantly.
	 *
	 * @param entity entity to be saved. Must not be {@literal null}.
	 * @return the saved entity
	 */
	<S extends T> S saveAndFlush(S entity);

	/**
	 * Saves all entities and flushes changes instantly.
	 *
	 * @param entities entities to be deleted. Must not be {@literal null}.
	 * @return the saved entities
	 * @since 2.5
	 */
	<S extends T> List<S> saveAllAndFlush(Iterable<S> entities);

	/**
	 * Deletes the given entities in a batch which means it will create a single query. This kind of operation leaves JPAs
	 * first level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this
	 * method.
	 *
	 * @param entities entities to be deleted. Must not be {@literal null}.
	 * @deprecated Use {@link #deleteAllInBatch(Iterable)} instead.
	 */
	@Deprecated
	default void deleteInBatch(Iterable<T> entities){deleteAllInBatch(entities);}

	/**
	 * Deletes the given entities in a batch which means it will create a single query. This kind of operation leaves JPAs
	 * first level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this
	 * method.
	 *
	 * @param entities entities to be deleted. Must not be {@literal null}.
	 * @since 2.5
	 */
	void deleteAllInBatch(Iterable<T> entities);


	/**
	 * Deletes the entities identified by the given ids using a single query. This kind of operation leaves JPAs first
	 * level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this method.
	 *
	 * @param ids the ids of the entities to be deleted. Must not be {@literal null}.
	 * @since 2.5
	 */
	void deleteAllByIdInBatch(Iterable<ID> ids);

	/**
	 * Deletes all entities in a batch call.
	 */
	void deleteAllInBatch();

	/**
	 * Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is
	 * implemented this is very likely to always return an instance and throw an
	 * {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers
	 * immediately.
	 *
	 * @param id must not be {@literal null}.
	 * @return a reference to the entity with the given identifier.
	 * @see EntityManager#getReference(Class, Object) for details on when an exception is thrown.
	 * @deprecated use {@link JpaRepository#getById(ID)} instead.
	 */
	@Deprecated
	T getOne(ID id);

	/**
	 * Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is
	 * implemented this is very likely to always return an instance and throw an
	 * {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers
	 * immediately.
	 *
	 * @param id must not be {@literal null}.
	 * @return a reference to the entity with the given identifier.
	 * @see EntityManager#getReference(Class, Object) for details on when an exception is thrown.
	 * @since 2.5
	 */
	T getById(ID id);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
	 */
	@Override
	<S extends T> List<S> findAll(Example<S> example);

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
	 */
	@Override
	<S extends T> List<S> findAll(Example<S> example, Sort sort);
}


示例:UsersJpaRepository

package com.alan.SpringBootJpa.dao;
/*
 *
 *
 * @author: Alan_liu
 * @date 2021/5/30 13:55
 */

import com.alan.SpringBootJpa.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UsersJpaRepository extends JpaRepository<Users,Integer>  {

}


测试:UsersJpaRepositoryTest


package com.alan.SpringBootJpa;/*
 * Todo
 *
 * @author: Alan_liu
 * @date 2021/5/30 13:56
 */

import com.alan.SpringBootJpa.dao.UsersJpaRepository;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;

import java.util.List;

@SpringBootTest(classes =SpringBootJpaApplication.class )
public class UsersJpaRepositoryTest {

    @Autowired
    private UsersJpaRepository usersJpaRepository;


    /***
     *
     *  排序测试
     * @throws
     * @user Alan_liu
     * @date 2021/5/30 12:13
     */
    @Test
    public void testUsersJpaRepositoryTestSort(){
        //Order 定义排序规则
        //sort 对象封装了排序规则
        //注意:该处不需要进行 list<Users>类型强转
        List<Users> list= this.usersJpaRepository.findAll(Sort.by(Sort.Direction.DESC,"id"));
        for(Users u:list){
            System.out.println(u.toString());
        }
    }

}


b1da16f888687e743bab3356e6fc503



SpringBoot Data Jpa 提供的核心接口:JpaSpecificationExecutor  接口


JpaSpecificationExecutor 接口:

/*
 * Copyright 2008-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.jpa.repository;

import java.util.List;
import java.util.Optional;

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;
import org.springframework.lang.Nullable;

/**
 * Interface to allow execution of {@link Specification}s based on the JPA criteria API.
 *
 * @author Oliver Gierke
 * @author Christoph Strobl
 */
public interface JpaSpecificationExecutor<T> {

	/**
	 * Returns a single entity matching the given {@link Specification} or {@link Optional#empty()} if none found.
	 *
	 * @param spec can be {@literal null}.
	 * @return never {@literal null}.
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one entity found.
	 */
	Optional<T> findOne(@Nullable Specification<T> spec);

	/**
	 * Returns all entities matching the given {@link Specification}.
	 *
	 * @param spec can be {@literal null}.
	 * @return never {@literal null}.
	 */
	List<T> findAll(@Nullable Specification<T> spec);

	/**
	 * Returns a {@link Page} of entities matching the given {@link Specification}.
	 *
	 * @param spec can be {@literal null}.
	 * @param pageable must not be {@literal null}.
	 * @return never {@literal null}.
	 */
	Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);

	/**
	 * Returns all entities matching the given {@link Specification} and {@link Sort}.
	 *
	 * @param spec can be {@literal null}.
	 * @param sort must not be {@literal null}.
	 * @return never {@literal null}.
	 */
	List<T> findAll(@Nullable Specification<T> spec, Sort sort);

	/**
	 * Returns the number of instances that the given {@link Specification} will return.
	 *
	 * @param spec the {@link Specification} to count instances for. Can be {@literal null}.
	 * @return the number of instances.
	 */
	long count(@Nullable Specification<T> spec);
}


示例:UsersJpaSpecificationExecutor

package com.alan.SpringBootJpa.dao;


import com.alan.SpringBootJpa.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/*
 *  该接口主要提供了多条件查询的支持,并且可以在查询中添加分页与排序。
 * 注意: JpaSpecificationExecutor 是单独存在。完全独立
 * @author: Alan_liu
 * @date 2021/5/30 14:34
 */
public interface UsersJpaSpecificationExecutor extends JpaSpecificationExecutor<Users>  ,JpaRepository<Users,Integer> {


}


测试:UsersJpaSpecificationExecutorTest  复杂查询


package com.alan.SpringBootJpa;/*
 * Todo
 *
 * @author: Alan_liu
 * @date 2021/5/30 20:26
 */

import com.alan.SpringBootJpa.dao.UsersJpaSpecificationExecutor;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@SpringBootTest(classes =SpringBootJpaApplication.class )
public class UsersJpaSpecificationExecutorTest {
    @Autowired
    private UsersJpaSpecificationExecutor usersJpaSpecificationExecutor;

    @Test
    public  void testJpaSpecificationExecutor(){
        List<Users> list=this.usersJpaSpecificationExecutor.findAll(Sort.by(Sort.Direction.DESC,"id"));
        for(Users u:list){
            System.out.println(u.toString());
        }
    }
    /***
     *
     * JpaSpecificationExecutor   Specification   Predicate  单个条件查询测试
     * @user Alan_liu
     * @date 2021/5/30 20:44
     */
    @Test
    public  void testJpaSpecificationExecutorSpec(){
        /**
         *  Specification<Users> 封装了一个查询的对象
         *
         *
         */
        Specification<Users> spec=new Specification<Users>() {

            /***
             *  Predicate :封装了单个的查询条件
             * @param root  查询对象的属性的封装
             * @param query 封装了需要执行查询中的各个部分的信息: select   from  order  by 等信息
             * @param cb  CriteriaBuilder:查询条件的构造器  定义不同的查询条件的
             * @return {@link Predicate}
             * @user Alan_liu
             * @date 2021/5/30 20:36
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                  // where  name = "张山"
                /***
                 *参数一: 查询条件属性
                 * 参数二:条件值
                 */
                Predicate pre=cb.equal(root.get("name"),"张山");
                return pre;
            }
        };
        List<Users> list=this.usersJpaSpecificationExecutor.findAll(spec);
        for(Users u:list){
            System.out.println(u.toString());
        }
    }
    /***
     *
     * JpaSpecificationExecutor   Specification   Predicate  多个条件查询测试
     * @user Alan_liu
     * @date 2021/5/30 20:44
     */
    @Test
    public  void testJpaSpecificationExecutorSpecMore(){
        /**
         *  Specification<Users> 封装了一个查询的对象
         *
         *
         */
        Specification<Users> spec=new Specification<Users>() {

            /***
             *  Predicate :封装了单个的查询条件
             * @param root  查询对象的属性的封装
             * @param query 封装了需要执行查询中的各个部分的信息: select   from  order  by 等信息
             * @param cb  CriteriaBuilder:查询条件的构造器  定义不同的查询条件的
             * @return {@link Predicate}
             * @user Alan_liu
             * @date 2021/5/30 20:36
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // where name ='张山' and  age=20
                List<Predicate> list=new ArrayList<>();
                list.add(cb.equal(root.get("name"),"张山"));
                list.add(cb.equal(root.get("age"),20));
                Predicate[] arr=new Predicate[list.size()];
                return cb.and(list.toArray(arr));
            }
        };
        List<Users> list=this.usersJpaSpecificationExecutor.findAll(spec);
        for(Users u:list){
            System.out.println(u.toString());
        }
    }
    /***
     *
     * JpaSpecificationExecutor   Specification   Predicate  多个条件查询测试
     * @user Alan_liu
     * @date 2021/5/30 20:44
     */
    @Test
    public  void testJpaSpecificationExecutorSpecMoreTow(){
        /*
         *  Specification<Users> 封装了一个查询的对象
         */
        Specification<Users> spec=new Specification<Users>() {
            /***
             *  Predicate :封装了单个的查询条件
             * @param root  查询对象的属性的封装
             * @param query 封装了需要执行查询中的各个部分的信息: select   from  order  by 等信息
             * @param cb  CriteriaBuilder:查询条件的构造器  定义不同的查询条件的
             * @return {@link Predicate}
             * @user Alan_liu
             * @date 2021/5/30 20:36
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // where (name ='张山' and  age=20) or id=10
                return cb.or(cb.and(cb.equal(root.get("name"),"张山"),cb.equal(root.get("age"),20) ),cb.equal(root.get("id"),10) );
            }
        };
        List<Users> list=this.usersJpaSpecificationExecutor.findAll(spec);
        for(Users u:list){
            System.out.println(u.toString());
        }
    }
    /***
     *
     * JpaSpecificationExecutor   Specification   Predicate  Sort  多个条件查询测试 并排序
     * @user Alan_liu
     * @date 2021/5/30 20:44
     */
    @Test
    public  void testJpaSpecificationExecutorSpecMoreSort(){
        /*
         *  Specification<Users> 封装了一个查询的对象
         */
        Specification<Users> spec=new Specification<Users>() {
            /***
             *  Predicate :封装了单个的查询条件
             * @param root  查询对象的属性的封装
             * @param query 封装了需要执行查询中的各个部分的信息: select   from  order  by 等信息
             * @param cb  CriteriaBuilder:查询条件的构造器  定义不同的查询条件的
             * @return {@link Predicate}
             * @user Alan_liu
             * @date 2021/5/30 20:36
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // where (name ='张山' and  age=20) or id=10
                return cb.or(cb.and(cb.equal(root.get("name"),"张山"),cb.equal(root.get("age"),20) ),cb.equal(root.get("id"),10) );
            }
        };
        List<Users> list=this.usersJpaSpecificationExecutor.findAll(spec,Sort.by(Sort.Direction.DESC,"id"));
        for(Users u:list){
            System.out.println(u.toString());
        }
    }

    /***
     *
     * JpaSpecificationExecutor   Specification   Predicate  Sort  Pageable  多个条件查询测试 并排序  分页
     * @user Alan_liu
     * @date 2021/5/30 20:44
     */
    @Test
    public  void testJpaSpecificationExecutorSpecMoreSortPageable(){

        //pageable :封装了分页的参数,当前页,每页显示的条数。注意:它的当前页是从0开始的
        //pageable(page,size) page:当前页,size:每页显示的条数
        Sort sort = Sort.by(Sort.Direction.DESC,"id");
        Pageable pageable= PageRequest.of(0,10,sort) ;
        /*
         *  Specification<Users> 封装了一个查询的对象
         */
        Specification<Users> spec=new Specification<Users>() {
            /***
             *  Predicate :封装了单个的查询条件
             * @param root  查询对象的属性的封装
             * @param query 封装了需要执行查询中的各个部分的信息: select   from  order  by 等信息
             * @param cb  CriteriaBuilder:查询条件的构造器  定义不同的查询条件的
             * @return {@link Predicate}
             * @user Alan_liu
             * @date 2021/5/30 20:36
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // where (name ='张山' and  age=20) or id=10
                return cb.or(cb.and(cb.equal(root.get("name"),"张山"),cb.equal(root.get("age"),20) ),cb.equal(root.get("id"),10) );
            }
        };
       //将条件和分页给findAll,进行查询
        Page<Users> userPage = this.usersJpaSpecificationExecutor.findAll(spec, pageable);
        System.out.println("数据总条数:"+userPage.getTotalElements());
        System.out.println("数据总页数:"+userPage.getTotalPages());
        List<Users> list =userPage.getContent();//获取出现数据信息
        for(Users u:list){
            System.out.println(u.toString());
        }
    }

}


ff34e44d4538a8a50b25c430c2e30a0d20def066bd0477a89f4b74cd46b39adab1db8ba84c520d1e3f8b875de05c9

a2c70925c80166823e681ef868ba8ef98f90801092812956812de0e2333732e6155066006385e11dc75afa294b36e02c12c9eb7d6e2c183224bb0aae38677ab2e60a78811aa598446f5ac40ea78


jpa 关联映射操作

1:一对多的关联关系

需求:角色与用户的一对多的关联关系。

角色:一方

用户:多方

Roles

package com.alan.SpringBootJpa.pojo;/*
 * Todo
 *
 * @author: Alan_liu
 * @date 2021/5/30 21:41
 */

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "t_roles")
public class Roles {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "roleid")
    private Integer roleid;
    @Column(name = "rolename")
    private String  rolename;

    @OneToMany(mappedBy ="roles" )
    private Set<Users> users=new HashSet<Users>();

    public Set<Users> getUsers() {
        return users;
    }

    public void setUsers(Set<Users> users) {
        this.users = users;
    }

    public Integer getRoleid() {
        return roleid;
    }

    public void setRoleid(Integer roleid) {
        this.roleid = roleid;
    }

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }

}


Users


package com.alan.SpringBootJpa.pojo;

import javax.persistence.*;

/*
 *
 *
 * @author: Alan_liu
 * @date 2021/5/26 21:21
 */
@Entity
@Table(name ="t_users")
public class Users {


   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id")
   private Integer id;
   @Column(name = "name")
   private String name;
   @Column(name="age")
   private  Integer age;
   @Column(name = "address")
   private  String  address;

   @ManyToOne(cascade =CascadeType.PERSIST) /**保存用户数据的时候同时保存角色数据信息**/
   //JoinColumn :维护外键
   @JoinColumn(name = "roles_id")
   private Roles roles;

    public Roles getRoles() {
        return roles;
    }

    public void setRoles(Roles roles) {
        this.roles = roles;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}


测试 一对多的关联关系:OneToManyTest


package com.alan.SpringBootJpa;

import com.alan.SpringBootJpa.dao.UsersRepository;
import com.alan.SpringBootJpa.pojo.Roles;
import com.alan.SpringBootJpa.pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.transaction.Transactional;
import java.util.Optional;
import java.util.Set;

/* 一对多关联关系测试
 * @author: Alan_liu
 * @date 2021/5/30 21:54
 */
@SpringBootTest(classes =SpringBootJpaApplication.class )
public class OneToManyTest {

    @Autowired
    private UsersRepository usersRepository;

    /***
     * 一对多关联关系的添加
     *  操作逻辑步骤:
     *  ① 创建一个用户
     *  ② 创建一个角色
     *  ③ 设置关联
     *  ④ 保存
     *
     * @user Alan_liu
     * @date 2021/5/30 21:56
     */
    @Test
    public void testSave(){
        //① 创建一个用户
        Users users=new Users();
        users.setAddress("北京市");
        users.setAge(32);
        users.setName("李刚");
        //② 创建一个角色
        Roles roles=new Roles();
        roles.setRolename("管理员");
        //③ 设置关联
        roles.getUsers().add(users);
        users.setRoles(roles);
        //④ 保存
        this.usersRepository.save(users);
    }
    @Test
    public void  testFind(){
        Optional<Users> optional =this.usersRepository.findById(12);
        System.out.println(optional.get().getId());
        Roles roles = optional.get().getRoles();
        System.out.println(roles.getRolename());
    }

}

12354fa981d2c742a7eb69644023872543ad53c26e7fd38b311003c15eab82a70aa3951905ed2ae298ed05ac00c1d







2:多对多的关联关系

需求:角色与菜单多对多关联关系

角色:多方

菜单:多方


application.properties


### 此版本为mysql 5.X 的 sql连接驱动器使用方法###
# spring.datasource.driverClassName=com.mysql.jdbc.Driver
### 此版本为mysql 6.X 以上 的 sql连接驱动器使用方法###
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=123456
#配置数据库连接池信息
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

#配置Spring Jpa 信息
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.open-in-view=true
#处理 懒加载问题:因为hibernate默认的懒加载策略:默认lazy为true 引起的异常
#使用的是springboot的jpa,增加以下的配置内容
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true


Roles

package com.alan.SpringBootJpa.pojo;/*
 * Todo
 *
 * @author: Alan_liu
 * @date 2021/5/30 21:41
 */

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "t_roles")
public class Roles {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "roleid")
    private Integer roleid;
    @Column(name = "rolename")
    private String  rolename;

    @OneToMany(mappedBy ="roles" )
    private Set<Users> users=new HashSet<Users>();

    //@JoinTable:映射中间表
    //joinColumns  :当前表中个主键所关联的中间表的外键字段
    //inverseJoinColumns :另外一方的主键 ,中间表的另外一个关联关系字段
    @ManyToMany(cascade = CascadeType.PERSIST/*,fetch =FetchType.EAGER  立即加载*/)
    @JoinTable(name="t_roles_menus",joinColumns = @JoinColumn(name="role_id"),inverseJoinColumns = @JoinColumn(name="menu_id"))
    private Set<Menus> menusSet =new HashSet<Menus>();

    public Set<Menus> getMenusSet() {
        return menusSet;
    }

    public void setMenusSet(Set<Menus> menusSet) {
        this.menusSet = menusSet;
    }

    public Set<Users> getUsers() {
        return users;
    }

    public void setUsers(Set<Users> users) {
        this.users = users;
    }

    public Integer getRoleid() {
        return roleid;
    }

    public void setRoleid(Integer roleid) {
        this.roleid = roleid;
    }

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }

    @Override
    public String toString() {
        return "Roles{" +
                "roleid=" + roleid +
                ", rolename='" + rolename +
                ", users=" + users +"}";
    }
}



Menus

package com.alan.SpringBootJpa.pojo;


import javax.annotation.Generated;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

/*
 * @author: Alan_liu
 * @date 2021/5/30 22:32
 */
@Entity
@Table(name = "t_menus")
public class Menus {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="menusid")
    private Integer menusid;//菜单id
    @Column(name="menusname")
    private String menusname;//菜单名称
    @Column(name="menusurl")
    private String menusurl;//菜单url路径
    @Column(name="fatherid")
    private Integer fatherid;//父节点id

    @ManyToMany(mappedBy ="menus" )
    private Set<Roles> roles=new HashSet<Roles>();

    public Set<Roles> getRoles() {
        return roles;
    }

    public void setRoles(Set<Roles> roles) {
        this.roles = roles;
    }

    public Integer getMenusid() {
        return menusid;
    }

    public void setMenusid(Integer menusid) {
        this.menusid = menusid;
    }

    public String getMenusname() {
        return menusname;
    }

    public void setMenusname(String menusname) {
        this.menusname = menusname;
    }

    public String getMenusurl() {
        return menusurl;
    }

    public void setMenusurl(String menusurl) {
        this.menusurl = menusurl;
    }

    public Integer getFatherid() {
        return fatherid;
    }

    public void setFatherid(Integer fatherid) {
        this.fatherid = fatherid;
    }


}


测试示例:ManyToManyTest


package com.alan.SpringBootJpa;
/*
 *
 * @author: Alan_liu
 * @date 2021/6/1 23:06
 */

import com.alan.SpringBootJpa.dao.RolesRepository;
import com.alan.SpringBootJpa.pojo.Menus;
import com.alan.SpringBootJpa.pojo.Roles;
import com.alan.SpringBootJpa.pojo.Users;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.print.attribute.standard.Media;
import javax.security.auth.kerberos.KerberosPrincipal;
import java.awt.*;
import java.util.Optional;
import java.util.Set;

/*
 *  多对多的关联关系测试
 * @author: Alan_liu
 * @date 2021/5/30 21:54
 */
@SpringBootTest(classes =SpringBootJpaApplication.class )
public class ManyToManyTest {
    @Autowired
    private RolesRepository rolesRepository;

    /***
     *
     *
     * @throws
     * @user Alan_liu
     * @date 2021/6/1 23:11
     */
    @Test
    public void testSave(){
        //创建角色对象
        Roles r=new Roles();
        r.setRolename("项目经理");

        //创建菜单对象
        Menus menus=new Menus();
        menus.setMenusname("xxxxx管理系统");
        menus.setFatherid(0);

        Menus menus1=new Menus();
        menus1.setFatherid(1);
        menus1.setMenusname("项目管理");

        //关联
        r.getMenusSet().add(menus);
        r.getMenusSet().add(menus1);
        menus.getRoles().add(r);
        menus1.getRoles().add(r);
        //保存
        this.rolesRepository.save(r);
    }

    /**
     * 查询操作
     * 此处处理延迟加载的问题方案:
     *    方案1:在 application.properties 配置文件中增加  spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
     *    方案2:在 rolesjava类的 private Set<Menus> menusSet =new HashSet<Menus>(); 的注解上增加fetch =FetchType.EAGER 开启立即加载
     *    如 * @ManyToMany(cascade = CascadeType.PERSIST,fetch =FetchType.EAGER)
     */
    @Test
    public void testFind(){
        Roles roles=  this.rolesRepository.getById(2);
        System.out.println(roles.getRolename());
        Set<Menus> rolesMenusSet =roles.getMenusSet();
        for(Menus menus1:rolesMenusSet) {
            System.out.println(menus1);
        }
    }


}


GG$569_][HL$CA3D8)WOGLD

1~S(S14HX(19CEJDPFLE{43













posted @ 2021-05-29 17:51  一品堂.技术学习笔记  阅读(435)  评论(0编辑  收藏  举报