SpringData

涉及技术介绍

Hibernate

Your relational data. Objectively. - Hibernate ORM

Object/Relational Mapping
Hibernate ORM enables developers to more easily write applications whose data outlives the application process. As an Object/Relational Mapping (ORM) framework, Hibernate is concerned with data persistence as it applies to relational databases (via JDBC). Unfamiliar with the notion of ORM? Read here.

JPA Provider
In addition to its own “native” API, Hibernate is also an implementation of the Java Persistence API (JPA) specification. As such, it can be easily used in any environment supporting JPA including Java SE applications, Java EE application servers, Enterprise OSGi containers, etc.

Idiomatic persistence
Hibernate enables you to develop persistent classes following natural Object-oriented idioms including inheritance, polymorphism, association, composition, and the Java collections framework. Hibernate requires no interfaces or base classes for persistent classes and enables any class or data structure to be persistent.

High Performance
Hibernate supports lazy initialization, numerous fetching strategies and optimistic locking with automatic versioning and time stamping. Hibernate requires no special database tables or fields and generates much of the SQL at system initialization time instead of at runtime.

Hibernate consistently offers superior performance over straight JDBC code, both in terms of developer productivity and runtime performance.

Scalability
Hibernate was designed to work in an application server cluster and deliver a highly scalable architecture. Hibernate scales well in any environment: Use it to drive your in-house Intranet that serves hundreds of users or for mission-critical applications that serve hundreds of thousands.

Reliable
Hibernate is well known for its excellent stability and quality, proven by the acceptance and use by tens of thousands of Java developers.

Extensibility
Hibernate is highly configurable and extensible.

JPA 标准

Java Persistence API - Wikipedia

The Java Persistence API (JPA) is a Java application programming interface specification that describes the management of relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition.

Persistence in this context covers three areas:

Hibernate JPA

Hibernate3.2 以后根据JPA 规范提供了一套操作持久层的 API

Spring Data

Spring Data

Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store.

It makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services. This is an umbrella project which contains many subprojects that are specific to a given database. The projects are developed by working together with many of the companies and developers that are behind these exciting technologies.

Spring Data JPA

Spring Data JPA

Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use data access technologies.

Implementing a data access layer of an application has been cumbersome for quite a while. Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring Data JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that’s actually needed. As a developer you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.

Spring Data Redis

Spring Data Redis

Spring Data Redis, part of the larger Spring Data family, provides easy configuration and access to Redis from Spring applications. It offers both low-level and high-level abstractions for interacting with the store, freeing the user from infrastructural concerns.

Spring 整合 Hibernate

导入jar包

spring jar包

spring-ioc

spring-beans-4.2.0.RELEASE.jar

spring-context-4.2.0.RELEASE.jar

spring-core-4.2.0.RELEASE.jar

spring-expression-4.2.0.RELEASE.jar

spring-aop

aopalliance.jar

aspectjrt.jar

aspectjweaver.jar

spring-aop-4.2.0.RELEASE.jar

spring-aspects-4.2.0.RELEASE.jar

spring-jdbc

spring-jdbc-4.2.0.RELEASE.jar

spring-tx-4.2.0.RELEASE.jar

spring-orm

spring-orm-4.2.0.RELEASE.jar

spring-test

spring-test-4.2.0.RELEASE.jar

apache-logging

commons-logging-1.1.1.jar

hibernate jar包

hibernate-core

antlr-2.7.7.jar

dom4j-1.6.1.jar

geronimo-jta_1.1_spec-1.1.1.jar

hibernate-commons-annotations-5.0.1.Final.jar

hibernate-core-5.0.7.Final.jar

hibernate-jpa-2.1-api-1.0.0.Final.jar

jandex-2.0.0.Final.jar

javassist-3.18.1-GA.jar

jboss-logging-3.3.0.Final.jar

mysqql-driver

mysql-connector-java-5.1.7-bin.jar

c3p0连接池

c3p0-0.9.2.1.jar

hibernate-c3p0-5.0.7.Final.jar

mchange-commons-java-0.2.3.4.jar

1560590752790

spring整合hibernate

编写配置文件

  • 配置读取properties文件的工具类
  • 配置c3p0数据库连接池
  • 配置Hibernate的SeesionFactory
  • 配置Hibernate的事务管理器
  • 配置开启注解事务处理
  • 配置springIOC的注解扫描

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    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/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置读取properties文件的工具类 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置c3p0数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="driverClass" value="${jdbc.driver.class}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 配置Hibernate的SeesionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- hibernateProperties属性:配置与hibernate相关的内容,如显示sql语句,开启正向工程 -->
        <property name="hibernateProperties">
            <props>
                <!-- 显示当前执行的sql语句 -->
                <prop key="hibernate.show_sql">true</prop>
                <!-- 开启正向工程 -->
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <!-- 扫描实体所在的包 -->
        <property name="packagesToScan">
            <list>
                <value>com.bjsxt.pojo</value>
            </list>
        </property>
    </bean>

    <!-- 配置Hibernate的事务管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 配置开启注解事务处理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- 配置springIOC的注解扫描 -->
    <context:component-scan base-package="com.bjsxt"/>
</beans>

hibernate完成CRUD

创建数据库

1560591084871

编写实体类

Users.java

package com.bjsxt.pojo;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="t_users")
public class Users implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)//strategy=GenerationType.IDENTITY 自增长
    @Column(name="userid")
    private Integer userid;

    @Column(name="username")
    private String username;

    @Column(name="userage")
    private Integer userage;

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getUserage() {
        return userage;
    }

    public void setUserage(Integer userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "Users [userid=" + userid + ", username=" + username + ", userage=" + userage + "]";
    }

}

修改配置文件

添加 HibernateTemplate,修改applicationContext.xml配置文件

    <!-- 配置HiberanteTemplate对象 -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

编写接口

UsersDao.java

package com.bjsxt.dao;

import java.util.List;

import com.bjsxt.pojo.Users;

public interface UsersDao {

    void insertUsers(Users users);
    void updateUsers(Users users);
    void deleteUsers(Users users);
    Users selectUsersById(Integer userid);

}

编写实现类

UsersDaoImpl.java

package com.bjsxt.dao.impl;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

@Repository
public class UsersDaoImpl  implements UsersDao {

    @Autowired
    private HibernateTemplate hibernateTemplate;

    @Override
    public void insertUsers(Users users) {
        this.hibernateTemplate.save(users);
    }

    @Override
    public void updateUsers(Users users) {
        this.hibernateTemplate.update(users);

    }

    @Override
    public void deleteUsers(Users users) {
        this.hibernateTemplate.delete(users);

    }

    @Override
    public Users selectUsersById(Integer userid) {
        return this.hibernateTemplate.get(Users.class, userid);
    }

}

编写测试代码

UsersDaoImplTest.java

package com.bjsxt.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsersDaoImplTest {

    @Autowired
    private UsersDao usersDao;


    /**
     * 添加用户
     */
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void testInsertUsers(){
        Users users = new Users();
        users.setUserage(20);
        users.setUsername("张三");
        this.usersDao.insertUsers(users);
    }

    /**
     * 更新用户
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testUpdateUsers(){
        Users users = new Users();
        users.setUserid(2);
        users.setUserage(22);
        users.setUsername("李四");
        this.usersDao.updateUsers(users);
    }

    /**
     * 根据userid查询用户
     */
    @Test
    public void testSelectUsersById(){
        Users users = this.usersDao.selectUsersById(2);
        System.out.println(users);
    }

    /**
     * 删除用户
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testDeleteUsers(){
        Users users = new Users();
        users.setUserid(2);
        this.usersDao.deleteUsers(users);
    }

}

HQL查询

HQL:Hibernate Query Language
HQL的语法:就是将原来的 sql语句中的表与字段名称换成对象与属性的名称就可以了

修改接口

添加查询方法

List<Users> selectUserByName(String username);

修改实现类

实现查询方法

    @Override
    public List<Users> selectUserByName(String username) {
        //getCurrentSession:当前session必须要有事务边界,且只能处理唯一的一个事务。当事务提交或者回滚后session自动失效
        //openSession:每次都会打开一个新的session.加入每次使用多次。则获得的是不同session对象。使用完毕后我们需要手动的调用colse方法关闭session
    Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
    //sql:select * from t_users where username = 
    Query query = session.createQuery("from Users where username = :abc");
    Query queryTemp = query.setString("abc",username);
        return queryTemp.list();
    }

编写测试代码

测试HQL查询

    /**
     * HQL测试
     */
    @Test
    @Transactional
    public void testSelectUserByName(){
        List<Users> list = this.usersDao.selectUserByName("张三");
        for (Users users : list) {
            System.out.println(users);
        }
    }

SQL查询

修改接口

添加查询方法

    List<Users> selectUserByNameUseSQL(String username);

修改实现类

实现查询方法

    @Override
    public List<Users> selectUserByNameUseSQL(String username) {
        Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
        Query query = session.createSQLQuery("select * from t_users where username = ?").addEntity(Users.class).setString(0, username);
        return query.list();
    }

编写测试代码

测试SQL查询

    /**
     * SQL测试
     */
    @Test
    @Transactional
    public void testSelectUserByNameUseSQL(){
        List<Users> list = this.usersDao.selectUserByNameUseSQL("张三");
        for (Users users : list) {
            System.out.println(users);
        }
    }

QBC查询

QBC:Query By Criteria

修改接口

添加查询方法

    List<Users> selectUserByNameUseCriteria(String username);

修改实现类

实现接口查询方法

    @Override
    public List<Users> selectUserByNameUseCriteria(String username) {
        Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
        //sql:select * from t_users where username = 张三
        Criteria c = session.createCriteria(Users.class);
        c.add(Restrictions.eq("username", username));
        return c.list();
    }

编写测试代码

测试QBC查询

    /**
     * Criteria测试
     */
    @Test
    @Transactional
    public void testSelectUserByNameUseCriteria(){
        List<Users> list = this.usersDao.selectUserByNameUseCriteria("张三");
        for (Users users : list) {
            System.out.println(users);
        }
    }

Spring整合Hibernate JPA

JPA:Sun公司提供了一对对于持久层操作的标准(接口+文档)
Hibernate:Gavin King开发的一套对于持久层操作的自动的ORM框架。
Hibernate JPA:是在Hibernate3.2版本那种提供了对于 JPA的标准的实现。提供了一套按
JPA 标准来实现持久层开发的 API

导入jar包

在项目中导入 HIbernateJPA相关的 jar

hibernate-entitymanager-5.0.7.Final.jar

修改配置文件

修改applicationContext.xml配置文件

  • 配置读取properties文件的工具类
  • 配置c3p0数据库连接池
  • Spring整合JPA 配置EntityManagerFactory
  • 配置jpa的事务管理器
  • 配置开启注解事务处理
  • 配置springIOC的注解扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    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/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置读取properties文件的工具类 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置c3p0数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="driverClass" value="${jdbc.driver.class}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- Spring整合JPA  配置EntityManagerFactory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVedorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!-- hibernate相关的属性的注入 -->
                <!-- 配置数据库类型 -->
                <property name="database" value="MYSQL"/>
                <!-- 正向工程 自动创建表 -->
                <property name="generateDdl" value="true"/>
                <!-- 显示执行的SQL -->
                <property name="showSql" value="true"/>
            </bean>
        </property>
        <!-- 扫描实体的包 -->
        <property name="packagesToScan">
            <list>
                <value>com.bjsxt.pojo</value>
            </list>
        </property>
    </bean>

    <!-- 配置jpa的事务管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-- 配置开启注解事务处理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- 配置springIOC的注解扫描 -->
    <context:component-scan base-package="com.bjsxt"/>
</beans>

Hibernate JPA的CRUD

编写实体类

Users.java

package com.bjsxt.pojo;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="t_users")
public class Users implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)//strategy=GenerationType.IDENTITY 自增长
    @Column(name="userid")
    private Integer userid;

    @Column(name="username")
    private String username;

    @Column(name="userage")
    private Integer userage;

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getUserage() {
        return userage;
    }

    public void setUserage(Integer userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "Users [userid=" + userid + ", username=" + username + ", userage=" + userage + "]";
    }

}

编写接口

UsersDao.java

package com.bjsxt.dao;

import java.util.List;

import com.bjsxt.pojo.Users;

public interface UsersDao {

    void insertUsers(Users users);
    void updateUsers(Users users);
    void deleteUsers(Users users);
    Users selectUsersById(Integer userid);

}

编写实现类

UsersDaoImpl.java

package com.bjsxt.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

@Repository
public class UsersDaoImpl  implements UsersDao {

    @PersistenceContext(name="entityManagerFactory")
    private EntityManager entityManager;

    @Override
    public void insertUsers(Users users) {
        this.entityManager.persist(users);
    }

    @Override
    public void updateUsers(Users users) {
        this.entityManager.merge(users);
    }

    @Override
    public void deleteUsers(Users users) {
        Users  u = this.selectUsersById(users.getUserid());
        this.entityManager.remove(u);
    }

    @Override
    public Users selectUsersById(Integer userid) {
        return this.entityManager.find(Users.class, userid);
    }
}

编写测试代码

UsersDaoImplTest.java

package com.bjsxt.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsersDaoImplTest {

    @Autowired
    private UsersDao usersDao;


    /**
     * 添加用户
     */
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void testInsertUsers(){
        Users users = new Users();
        users.setUserage(24);
        users.setUsername("王小丽");
        this.usersDao.insertUsers(users);
    }

    /**
     * 更新用户
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testUpdateUsers(){
        Users users = new Users();
        users.setUserid(5);
        users.setUserage(22);
        users.setUsername("王五");
        this.usersDao.updateUsers(users);
    }

    /**
     * 根据userid查询用户
     */
    @Test
    public void testSelectUsersById(){
        Users users = this.usersDao.selectUsersById(4);
        System.out.println(users);
    }

    /**
     * 删除用户
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testDeleteUsers(){
        Users users = new Users();
        users.setUserid(4);
        this.usersDao.deleteUsers(users);
    }
}

HQL查询

修改接口

添加HQL查询方法

    List<Users> selectUserByName(String username);

修改实现类

实现HQL查询接口方法

    @Override
    public List<Users> selectUserByName(String username) {
        return this.entityManager.createQuery(" from Users where username = :abc").setParameter("abc", username).getResultList();
    }

修改测试代码

测试HQL查询

    /**
     * HQL测试
     */
    @Test
    @Transactional
    public void testSelectUserByName(){
        List<Users> list = this.usersDao.selectUserByName("王五");
        for (Users users : list) {
            System.out.println(users);
        }
    }

SQL查询

修改接口

添加SQL查询方法

    List<Users> selectUserByNameUseSQL(String username);

修改实现类

实现SQL查询接口方法

    @Override
    public List<Users> selectUserByNameUseSQL(String username) {
        //在Hibernate JPA中 如果通过?方式来帮顶参数,那么他的查数是从1开始的。而hibernate中是从0开始的。
        return this.entityManager.createNativeQuery("select * from t_users where username = ?", Users.class).setParameter(1, username).getResultList();
    }

修改测试代码

测试SQL查询

    /**
     * SQL测试
     */
    @Test
    @Transactional
    public void testSelectUserByNameUseSQL(){
        List<Users> list = this.usersDao.selectUserByNameUseSQL("王五");
        for (Users users : list) {
            System.out.println(users);
        }
    }

QBC查询

修改接口

添加QBC查询方法

    List<Users> selectUserByNameUseCriteria(String username);

修改实现类

实现QBC查询接口方法

    @Override
    public List<Users> selectUserByNameUseCriteria(String username) {
        //CriteriaBuilder对象:创建一个CriteriaQuery,创建查询条件。
        CriteriaBuilder builber = this.entityManager.getCriteriaBuilder();
        //CriteriaQuery对象:执行查询的Criteria对象
        //select  * from t_users
        CriteriaQuery<Users> query = builber.createQuery(Users.class);
        //获取要查询的实体类的对象
        Root<Users> root = query.from(Users.class);
        //封装查询条件
        Predicate cate = builber.equal(root.get("username"), username);
        //select * from t_users where username = 张三
        query.where(cate);
        //执行查询
        TypedQuery<Users> typeQuery = this.entityManager.createQuery(query);
        return typeQuery.getResultList();
    }

修改测试代码

测试QBC查询

    /**
     * Criteria测试
     */
    @Test
    @Transactional
    public void testSelectUserByNameUseCriteria(){
        List<Users> list = this.usersDao.selectUserByNameUseCriteria("王五");
        for (Users users : list) {
            System.out.println(users);
        }
    }

Spring Data JPA

Spring Data JPA:Spring Data JPAspring data项目下的一个模块。提供了一套基于JPA
标准操作数据库的简化方案。底层默认的是依赖 Hibernate JPA来实现的。
Spring Data JPA的技术特点:我们只需要定义接口并集成Spring Data JPA中所提供的接
口就可以了。不需要编写接口实现类。

入门

导入jar包

spring整合hibernate、hibernate JPA的基础jar包上添加

  • spring-data-commons-1.11.0.RELEASE.jar
  • spring-data-jpa-1.9.0.RELEASE.jar
  • slf4j-api-1.6.1.jar
  • slf4j-log4j12-1.7.2.jar
  • log4j-1.2.16.jar

1560736030901

修改配置文件

  • JPA命名空间xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  • Spring Data JPA 的配置<jpa:repositories base-package="com.bjsxt.dao"/>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/data/jpa 
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- 配置读取properties文件的工具类 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置c3p0数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="driverClass" value="${jdbc.driver.class}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- Spring整合JPA  配置EntityManagerFactory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!-- hibernate相关的属性的注入 -->
                <!-- 配置数据库类型 -->
                <property name="database" value="MYSQL"/>
                <!-- 正向工程 自动创建表 -->
                <property name="generateDdl" value="true"/>
                <!-- 显示执行的SQL -->
                <property name="showSql" value="true"/>
            </bean>
        </property>
        <!-- 扫描实体的包 -->
        <property name="packagesToScan">
            <list>
                <value>com.bjsxt.pojo</value>
            </list>
        </property>
    </bean>

    <!-- 配置Hibernate的事务管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-- 配置开启注解事务处理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- 配置springIOC的注解扫描 -->
    <context:component-scan base-package="com.bjsxt"/>

    <!-- Spring Data JPA 的配置 -->
    <!-- base-package:扫描dao接口所在的包 -->
    <jpa:repositories base-package="com.bjsxt.dao"/>
</beans>

编写DAO

package com.bjsxt.dao;


import org.springframework.data.jpa.repository.JpaRepository;

import com.bjsxt.pojo.Users;

public interface UsersDao extends JpaRepository<Users, Integer> {


}

编写测试代码

  • JUnit单元测试,事务默认是回滚的
package com.bjsxt.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsersDaoImplTest {

    @Autowired
    private UsersDao usersDao;


    /**
     * 添加用户
     */
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void testInsertUsers(){
        Users users = new Users();
        users.setUserage(24);
        users.setUsername("张三");
        this.usersDao.save(users);
    }

}

接口继承结构

1560737840689

运行原理

  • 入门编写测试代码时,我们注入了接口UsersDao,自己并没有实现save但是可以直接调用,实际上通过工厂对象JpaRepositoryFactory帮我们生成了代理对象
    @PersistenceContext(name="entityManagerFactory")
    private EntityManager em;
    @Test
    public void test1(){
    //org.springframework.data.jpa.repository.support.SimpleJpaRepository@fba8bf
    //System.out.println(this.usersDao);
    //class com.sun.proxy.$Proxy29 代理对象 是基于 JDK 的动态代理方式创建的
    //System.out.println(this.usersDao.getClass());
    JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
    //getRepository(UsersDao.class);可以帮助我们为接口生成实现类。而这个实现类是 SimpleJpaRepository 的对象
    //要求:该接口必须要是继承 Repository 接口
    UsersDao ud = factory.getRepository(UsersDao.class);
    System.out.println(ud);
    System.out.println(ud.getClass());
    }

Repository接口

Repository 接口是 Spring Data JPA 中为我我们提供的所有接口中的顶层接口
Repository提供了两种查询方式的支持

  • 基于方法名称命名规则查询
  • 基于@Query 注解查询

方法名称命名规则查询

  • 规则:findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
关键字 方法命名 sql where 子句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equal findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEqual findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEqual findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike whre 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(?)

编写接口

UsersDao.java

  package com.bjsxt.dao;


  import java.util.List;

  import org.springframework.data.jpa.repository.JpaRepository;
  import org.springframework.data.repository.Repository;

  import com.bjsxt.pojo.Users;

  /**
   * Repository接口讲解
   * @author Administrator
   *
   */
  public interface UsersDao extends Repository<Users, Integer> {

      List<Users> findByUsernameIs(String string);
      List<Users> findByUsernameLike(String string);
      List<Users> findByUsernameAndUserageGreaterThanEqual(String name,Integer age);
  }

编写测试类

RepositoryTest.java

  package com.bjsxt.test;

  import java.util.List;

  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.test.context.ContextConfiguration;
  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

  import com.bjsxt.dao.UsersDao;
  import com.bjsxt.pojo.Users;

  /**
   * Repository接口测试
   * @author Administrator
   *
   */
  @RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration("classpath:applicationContext.xml")
  public class RepositoryTest {

      @Autowired
      private UsersDao usersDao;

      /**
       * 需求:使用用户名作为查询条件
       */
      @Test
      public void test1(){
          /**
           * 判断相等的条件,有三种表示方式
           * 1,什么都不写,默认的就是做相等判断
           * 2,Is
           * 3,Equal
           */
          List<Users> list = this.usersDao.findByUsernameIs("王五");
          for (Users users : list) {
              System.out.println(users);
          }
      }

      /**
       * 需求:根据用户姓名做Like处理
       * Like:条件关键字
       */
      @Test
      public void test2(){
          List<Users> list = this.usersDao.findByUsernameLike("王%");
          for (Users users : list) {
              System.out.println(users);
          }
      }

      /**
       * 需求:查询名称为王五,并且他的年龄大于等于22岁
       */
      @Test
      public void test3(){
          List<Users> list = this.usersDao.findByUsernameAndUserageGreaterThanEqual("王五", 22);
          for (Users users : list) {
              System.out.println(users);
          }
      }
  }

@Query 注解的查询

JPQL语句查询

JPQL:通过 HibernateHQL演变过来的。他和 HQL语法及其相似

编写接口
  • @Query(value="from Users where username = ?")—>表:实体对象,字段:属性

UsersDao.java

package com.bjsxt.dao;


import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;

import com.bjsxt.pojo.Users;

/**
 * Repository接口讲解
 * @author Administrator
 *
 */
public interface UsersDao extends Repository<Users, Integer> {

    //使用@Query注解查询
    @Query(value="from Users where username = ?")
    List<Users> queryUserByNameUseJPQL(String name);

    @Query("from Users where username like ?")
    List<Users> queryUserByLikeNameUseJPQL(String name);

    @Query("from Users where username = ? and userage >= ?")
    List<Users> queryUserByNameAndAge(String name,Integer age);
}
编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * Repository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 测试@Query查询 JPQL
     */
    @Test
    public void test4(){
        List<Users> list = this.usersDao.queryUserByNameUseJPQL("王五");
        for (Users users : list) {
            System.out.println(users);
        }
    }

    /**
     * 测试@Query查询 JPQL
     */
    @Test
    public void test5(){
        List<Users> list = this.usersDao.queryUserByLikeNameUseJPQL("王%");
        for (Users users : list) {
            System.out.println(users);
        }
    }

    /**
     * 测试@Query查询 JPQL
     */
    @Test
    public void test6(){
        List<Users> list = this.usersDao.queryUserByNameAndAge("王五", 22);
        for (Users users : list) {
            System.out.println(users);
        }
    }

}

SQL语句查询

  • 原生SQL书写方式,nativeQuery=true表示不转义SQL
编写接口

UsersDao.java

package com.bjsxt.dao;


import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;

import com.bjsxt.pojo.Users;

/**
 * Repository接口讲解
 * @author Administrator
 *
 */
public interface UsersDao extends Repository<Users, Integer> {

    //使用@Query注解查询SQL
    //nativeQuery:默认的是false.表示不开启sql查询。是否对value中的语句做转义。
    @Query(value="select * from t_users where username = ?",nativeQuery=true)
    List<Users> queryUserByNameUseSQL(String name);

    @Query(value="select * from t_users where username like ?",nativeQuery=true)
    List<Users> queryUserByLikeNameUseSQL(String name);

    @Query(value="select * from t_users where username = ? and userage >= ?",nativeQuery=true)
    List<Users> queryUserByNameAndAgeUseSQL(String name,Integer age);
}
编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * Repository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 测试@Query查询 SQL
     */
    @Test
    public void test7(){
        List<Users> list = this.usersDao.queryUserByNameUseSQL("王五");
        for (Users users : list) {
            System.out.println(users);
        }
    }

    /**
     * 测试@Query查询 SQL
     */
    @Test
    public void test8(){
        List<Users> list = this.usersDao.queryUserByLikeNameUseSQL("王%");
        for (Users users : list) {
            System.out.println(users);
        }
    }

    /**
     * 测试@Query查询 SQL
     */
    @Test
    public void test9(){
        List<Users> list = this.usersDao.queryUserByNameAndAgeUseSQL("王五", 22);
        for (Users users : list) {
            System.out.println(users);
        }
    }
}

@Query注解的更新

编写接口

package com.bjsxt.dao;


import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;

import com.bjsxt.pojo.Users;

/**
 * Repository接口讲解
 * @author Administrator
 *
 */
public interface UsersDao extends Repository<Users, Integer> {

    @Query("update Users set userage = ? where userid = ?")
    @Modifying //@Modifying当前语句是一个更新语句
    void updateUserAgeById(Integer age,Integer id);

}

编写测试类

package com.bjsxt.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * Repository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 测试@Query update
     */
    @Test
    @Transactional
    @Rollback(false)
    public void test10(){
        this.usersDao.updateUserAgeById(24, 5);
    }
}

CrudRepository接口

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.repository.CrudRepository;

import com.bjsxt.pojo.Users;

/**
 * CrudRepository接口讲解
 * @author Administrator
 *
 */
public interface UsersDao extends CrudRepository<Users, Integer> {

}

编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * CrudRepository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 添加单条数据
     */
    @Test
    public void test1(){
        Users user = new Users();
        user.setUserage(21);
        user.setUsername("赵小丽");
        this.usersDao.save(user);
    }

    /**
     * 批量添加数据
     */
    @Test
    public void test2(){
        Users user = new Users();
        user.setUserage(21);
        user.setUsername("赵小丽");

        Users user1 = new Users();
        user1.setUserage(25);
        user1.setUsername("王小虎");

        List<Users> list= new ArrayList<>();
        list.add(user);
        list.add(user1);

        this.usersDao.save(list);

    }

    /**
     * 根据ID查询单条数据
     */
    @Test
    public void test3(){
        Users users = this.usersDao.findOne(13);
        System.out.println(users);
    }

    /**
     * 查询全部数据
     */
    @Test
    public void test4(){
        List<Users> list = (List<Users>)this.usersDao.findAll();
        for (Users users : list) {
            System.out.println(users);
        }
    }

    /**
     * 删除数据
     */
    @Test
    public void test5(){
        this.usersDao.delete(13);
    }

    /**
     * 更新数据 方式一
     */
    @Test
    public void test6(){
        Users user = this.usersDao.findOne(12);
        user.setUsername("王小红");
        this.usersDao.save(user);
    }

    /**
     * 更新数据 方式二
     */
    @Test
    @Transactional
    @Rollback(false)
    public void test7(){
        Users user = this.usersDao.findOne(12);//持久化状态的
        user.setUsername("王小小");
    }
}

PagingAndSortingRepository接口

分页

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * PagingAndSortingRepository接口讲解
 * @author Administrator
 *
 */
public interface UsersDao extends PagingAndSortingRepository<Users, Integer>{

}

编写测试代码

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * PagingAndSortingRepository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 分页
     */
    @Test
    public void test1(){
        int page = 2; //page:当前页的索引。注意索引都是从0开始的。
        int size = 3;// size:每页显示3条数据
        Pageable pageable= new PageRequest(page, size);
        Page<Users> p = this.usersDao.findAll(pageable);
        System.out.println("数据的总条数:"+p.getTotalElements());
        System.out.println("总页数:"+p.getTotalPages());
        List<Users> list = p.getContent();
        for (Users users : list) {
            System.out.println(users);
        }
    }
}

排序

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * PagingAndSortingRepository接口讲解
 * @author Administrator
 *
 */
public interface UsersDao extends PagingAndSortingRepository<Users, Integer>{

}

编写测试代码

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * PagingAndSortingRepository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 对单列做排序处理
     */
    @Test
    public void test2(){
        //Sort:该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
        //direction:排序规则
        //properties:指定做排序的属性
        Sort sort = new Sort(Direction.DESC,"userid");
        List<Users> list = (List<Users>)this.usersDao.findAll(sort);
        for (Users users : list) {
            System.out.println(users);
        }
    }

    /**
     * 多列的排序处理
     */
    @Test
    public void test3(){
        //Sort:该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
        //direction:排序规则
        //properties:指定做排序的属性
        Order order1 = new Order(Direction.DESC,"userage");
        Order order2 = new Order(Direction.ASC,"username");
        Sort sort = new Sort(order1,order2);
        List<Users> list = (List<Users>)this.usersDao.findAll(sort);
        for (Users users : list) {
            System.out.println(users);
        }
    }
}

JpaRepository接口

JpaRepository接口是我们开发时使用的最多的接口。其特点是可以帮助我们将其他接口
的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法。

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * JpaRepository接口讲解
 * @author Administrator
 *
 */
public interface UsersDao extends JpaRepository<Users, Integer>{

}

编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaRepository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 查询全部数据
     */
    @Test
    public void test1(){
        List<Users> list  = this.usersDao.findAll();
        for (Users users : list) {
            System.out.println(users);
        }
    }
}

JpaSpecificationExecutor接口

完成多条件查询,并且支持分页与排序

单条件查询

编写接口

  • JpaSpecificationExecutor<Users>:不能单独使用,需要配合着jpa中的其他接口一起使用

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口讲解
 * @author Administrator
 *注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着jpa中的其他接口一起使用
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>{

}

编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 需求:根据用户姓名查询数据
     */
    @Test
    public void test1(){
        Specification<Users> spec = new Specification<Users>() {

            /**
             * @return Predicate:定义了查询条件
             * @param Root<Users> root:根对象。封装了查询条件的对象
             * @param CriteriaQuery<?> query:定义了一个基本的查询。一般不使用
             * @param CriteriaBuilder cb:创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate pre = cb.equal(root.get("username"), "王五");
                return pre;
            }
        };
        List<Users> list = this.usersDao.findAll(spec);
        for (Users users : list) {
            System.out.println(users);
        }
    }
}

多条件查询

方式一

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口讲解
 * @author Administrator
 *注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着jpa中的其他接口一起使用
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>{

}
编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 多条件查询 方式一
     * 需求:使用用户姓名以及年龄查询数据
     */
    @Test
    public void test2(){
        Specification<Users> spec = new Specification<Users>() {

            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                list.add(cb.equal(root.get("username"),"王五"));
                list.add(cb.equal(root.get("userage"),24));
                //此时条件之间是没有任何关系的。
                Predicate[] arr = new Predicate[list.size()];
                return cb.and(list.toArray(arr));
            }

        };
        List<Users> list = this.usersDao.findAll(spec);
        for (Users users : list) {
            System.out.println(users);
        }
    }

}

方式二

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口讲解
 * @author Administrator
 *注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着jpa中的其他接口一起使用
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>{

}
编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 多条件查询 方式二
     * 需求:使用用户姓名或者年龄查询数据
     */
    @Test
    public void test3(){
        Specification<Users> spec = new Specification<Users>() {

            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.or(cb.equal(root.get("username"),"王五"),cb.equal(root.get("userage"), 25));
            }

        };
        List<Users> list = this.usersDao.findAll(spec);
        for (Users users : list) {
            System.out.println(users);
        }
    }

}

分页

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口讲解
 * @author Administrator
 *注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着jpa中的其他接口一起使用
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>{

}

编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 需求:查询王姓用户,并且做分页处理
     */
    @Test
    public void test4(){
        //条件
        Specification<Users> spec = new Specification<Users>() {

            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.like(root.get("username").as(String.class), "王%");
            }

        };

        //分页
        Pageable pageable = new PageRequest(2, 2);
        Page<Users> page = this.usersDao.findAll(spec, pageable);
        System.out.println("总条数:"+page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        List<Users> list = page.getContent();
        for (Users users : list) {
            System.out.println(users);
        }
    }

}

排序

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口讲解
 * @author Administrator
 *注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着jpa中的其他接口一起使用
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>{

}

编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 需求:查询数据库中王姓的用户,并且根据用户id做倒序排序
     */
    @Test
    public void test5(){
        //条件
        Specification<Users> spec = new Specification<Users>() {

            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.like(root.get("username").as(String.class), "王%");
            }

        };
        //排序
        Sort sort = new Sort(Direction.DESC,"userid");
        List<Users> list = this.usersDao.findAll(spec, sort);
        for (Users users : list) {
            System.out.println(users);
        }
    }

}

分页与排序

编写接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口讲解
 * @author Administrator
 *注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着jpa中的其他接口一起使用
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>{

}

编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaSpecificationExecutor接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;


    /**
     * 需求:查询数据库中王姓的用户,做分页处理,并且根据用户id做倒序排序
     */
    @Test
    public void test6(){
        //排序等定义
        Sort sort = new Sort(Direction.DESC,"userid");
        //分页的定义
        Pageable pageable = new PageRequest(2,2, sort);

        //查询条件
        Specification<Users> spec = new Specification<Users>() {

            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                return cb.like(root.get("username").as(String.class), "王%");
            }

        };
        Page<Users> page = this.usersDao.findAll(spec, pageable);
        System.out.println("总条数:"+page.getTotalElements());
        System.out.println("总页数:"+page.getTotalPages());
        List<Users> list = page.getContent();
        for (Users users : list) {
            System.out.println(users);
        }
    }

}

自定义 Repository 接口

编写接口

UsersRepository.java

package com.bjsxt.dao;

import com.bjsxt.pojo.Users;

public interface UsersRepository {

    public Users findUserById(Integer userid);
}

使用接口

UsersDao.java

package com.bjsxt.dao;



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.bjsxt.pojo.Users;

/**
 * 用户自定义Repository接口讲解
 * @author Administrator
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>,UsersRepository{

}

编写接口实现类

UsersDaoImpl.java

package com.bjsxt.dao;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.bjsxt.pojo.Users;

public class UsersDaoImpl implements UsersRepository {

    @PersistenceContext(name="entityManagerFactory")
    private EntityManager em;

    @Override
    public Users findUserById(Integer userid) {
        System.out.println("MyRepository......");
        return this.em.find(Users.class, userid);
    }

}

编写测试类

RepositoryTest.java

package com.bjsxt.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;

/**
 * JpaRepository接口测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 需求:根据用户ID查询数据
     */
    @Test
    public void test1(){
        Users users = this.usersDao.findUserById(5);
        System.out.println(users);
    }
}

多表操作

一对一

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

编写Users实体

Users.java

package com.bjsxt.pojo;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="t_users")
public class Users implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)//strategy=GenerationType.IDENTITY 自增长
    @Column(name="userid")
    private Integer userid;

    @Column(name="username")
    private String username;

    @Column(name="userage")
    private Integer userage;

    public Roles getRoles() {
        return roles;
    }

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

    @OneToOne(cascade=CascadeType.PERSIST)
    //@JoinColumn:就是维护一个外键
    @JoinColumn(name="roles_id")
    private Roles roles;

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getUserage() {
        return userage;
    }

    public void setUserage(Integer userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "Users [userid=" + userid + ", username=" + username + ", userage=" + userage + "]";
    }

}

编写Roles实体

package com.bjsxt.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@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;

    @OneToOne(mappedBy="roles")
    private Users users;

    public Users getUsers() {
        return users;
    }

    public void setUsers(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 + "]";
    }



}

编写测试类

OneToOneTest.java

package com.bjsxt.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Roles;
import com.bjsxt.pojo.Users;

/**
 * 一对一关联关系测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class OneToOneTest {

    @Autowired
    private UsersDao usersDao;

    /**
     * 添加用户同时添加角色
     */
    @Test
    public void test1(){
        //创建角色
        Roles roles = new Roles();
        roles.setRolename("管理员");

        //创建用户
        Users users = new Users();
        users.setUserage(30);
        users.setUsername("赵小刚");

        //建立关系
        users.setRoles(roles);
        roles.setUsers(users);

        //保存数据
        this.usersDao.save(users);
    }

    /**
     * 根据用户ID查询用户,同时查询用户角色
     */
    @Test
    public void test2(){
        Users users = this.usersDao.findOne(13);
        System.out.println("用户信息:"+users);
        Roles roles = users.getRoles();
        System.out.println(roles);
    }
}

一对多

需求:从角色到用户的一对多的关联关系
角色:一方
用户:多方

编写Users实体

Users.java

package com.bjsxt.pojo;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="t_users")
public class Users implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)//strategy=GenerationType.IDENTITY 自增长
    @Column(name="userid")
    private Integer userid;

    @Column(name="username")
    private String username;

    @Column(name="userage")
    private Integer userage;

    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="roles_id")
    private Roles roles;


    public Roles getRoles() {
        return roles;
    }

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

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getUserage() {
        return userage;
    }

    public void setUserage(Integer userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "Users [userid=" + userid + ", username=" + username + ", userage=" + userage + "]";
    }

}

编写Roles实体

Roles.java

package com.bjsxt.pojo;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@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<>();

    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 + "]";
    }



}

编写测试类

OneToManyTest.java

package com.bjsxt.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Roles;
import com.bjsxt.pojo.Users;

/**
 * 一对多的关联关系测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class OneToManyTest {

    @Autowired
    private UsersDao usersDao;


    /**
     * 添加用户同时添加角色
     */
    @Test
    public void test1(){
        //创建角色
        Roles roles = new Roles();
        roles.setRolename("管理员");
        //创建用户
        Users users =new Users();
        users.setUserage(30);
        users.setUsername("小王");
        //建立关系
        roles.getUsers().add(users);
        users.setRoles(roles);
        //保存数据
        this.usersDao.save(users);
    }

    /**
     * 根据用户ID查询用户信息,同时查询角色
     */
    @Test
    public void test2(){
        Users users = this.usersDao.findOne(14);
        System.out.println("用户姓名:"+users.getUsername());
        Roles roles = users.getRoles();
        System.out.println(roles);
    }
}

多对多

双向的一对多

需求:一个角色可以拥有多个菜单,一个菜单可以分配多个角色。多对多的关联关系
角色:多方
菜单:多方

编写Roles实体

Roles.java

package com.bjsxt.pojo;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@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;

    @ManyToMany
    //@JoinTable:配置中间表信息
    //joinColumns:建立当前表在中间表中的外键字段
    @JoinTable(name="t_roles_menus",joinColumns=@JoinColumn(name="role_id"),inverseJoinColumns=@JoinColumn(name="menu_id"))
    private Set<Menus> menus = new HashSet<>();


    public Set<Menus> getMenus() {
        return menus;
    }

    public void setMenus(Set<Menus> menus) {
        this.menus = menus;
    }

    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 + "]";
    }



}

编写Menus实体

Menus.java

package com.bjsxt.pojo;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="t_menus")
public class Menus {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="menusid")
    private Integer menusid;

    @Column(name="menusname")
    private String menusname;

    @Column(name="menusurl")
    private String menusurl;

    @Column(name="fatherid")
    private Integer fatherid;

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

    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;
    }

    @Override
    public String toString() {
        return "Menus [menusid=" + menusid + ", menusname=" + menusname + ", menusurl=" + menusurl + ", fatherid="
                + fatherid + "]";
    }
}

编写测试类

ManyToManyTest.java

package com.bjsxt.test;

import java.util.Set;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.bjsxt.dao.RolesDao;
import com.bjsxt.pojo.Menus;
import com.bjsxt.pojo.Roles;

/**
 * 多对多关联关系测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ManyToManyTest {


    @Autowired
    private RolesDao rolesDao;

    /**
     * 添加角色同时添加菜单
     */
    @Test
    public void test1(){
        //创建角色对象
        Roles roles = new Roles();
        roles.setRolename("超级管理员");

        //创建菜单对象    XXX管理平台 --->用户管理
        Menus menus = new Menus();
        menus.setMenusname("XXX管理平台");
        menus.setFatherid(-1);
        menus.setMenusurl(null);

        //用户管理菜单
        Menus menus1 = new Menus();
        menus1.setMenusname("用户管理");
        menus1.setFatherid(1);
        menus1.setMenusurl(null);


        //建立关系
        roles.getMenus().add(menus);
        roles.getMenus().add(menus1);

        menus.getRoles().add(roles);
        menus1.getRoles().add(roles);


        //保存数据
        this.rolesDao.save(roles);
    }

    /**
     * 查询Roles
     */
    @Test
    public void test2(){
        Roles roles = this.rolesDao.findOne(3);
        System.out.println("角色信息:"+roles);
        Set<Menus> menus = roles.getMenus();
        for (Menus menus2 : menus) {
            System.out.println("菜单信息:"+menus2);
        }
    }

}

Spring Data Redis

Spring Data Redis

Spring Data Redis, part of the larger Spring Data family, provides easy configuration and access to Redis from Spring applications. It offers both low-level and high-level abstractions for interacting with the store, freeing the user from infrastructural concerns.

安装

环境

Redis 版本:3.0.0
环境:Linux

步骤

安装 gcc 编译器

yum install gcc-c++

解压安装包

tar -zxf redis-3.0.0.tar.gz

进入解压目录进行编译

cd redis-3.0.0
make

将 Redis 安装到指定目录

make PREFIX=/usr/local/redis install

启动 Redis

  • 前置启动

    默认的是前置启动:./redis-server
  • 后置启动

    • 先将 redis.conf 文件拷贝到 redis 的安装目录cp redis.conf /usr/local/redis/bin
    • 编辑 redis.conf 文件修改:daemonize yes
    • 启动:./redis-server redis.conf
    • 查看 redis 进程:ps aux|grep redis
    • 关闭后置启动的 Redis:./redis-cli shutdown

搭建整合环境

创建项目

导入jar包

spring-ioc

spring-beans-4.2.0.RELEASE.jar

spring-context-4.2.0.RELEASE.jar

spring-core-4.2.0.RELEASE.jar

spring-expression-4.2.0.RELEASE.jar

spring-aop

aopalliance.jar

aspectjrt.jar

aspectjweaver.jar

spring-aop-4.2.0.RELEASE.jar

spring-aspects-4.2.0.RELEASE.jar

spring-jdbc

spring-jdbc-4.2.0.RELEASE.jar(这里没有用到)

spring-tx-4.2.0.RELEASE.jar

spring-orm

这里不需要用到

spring test

spring-tx-4.2.0.RELEASE.jar

apache-logging

commons-logging-1.1.1.jar

spring-data-redis

commons-pool2-2.3.jar

jedis-2.7.2.jar

spring-data-redis-1.6.0.RELEASE.jar

1561200447067

编写配置文件

  • 配置读取properties文件的工具类
  • Jedis连接池
  • Jedis连接工厂:创建Jedis对象的工厂
  • Redis模板对象:是SpringDataRedis提供的用户操作Redis的对象

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    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">
    <!-- 配置读取properties文件的工具类 -->
    <context:property-placeholder location="classpath:redis.properties"/>

    <!-- Jedis连接池 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.pool.maxtTotal}"/>
        <property name="maxIdle" value="${redis.pool.maxtIdle}"/>
        <property name="minIdle" value="${redis.pool.minIdle}"/>
    </bean>

    <!-- Jedis连接工厂:创建Jedis对象的工厂 -->
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <!-- IP地址 -->
        <property name="hostName" value="${redis.hostname}"/>
        <!-- 端口 -->
        <property name="port" value="${redis.port}"/>
        <!-- 连接池 -->
        <property name="poolConfig" ref="poolConfig"/>
    </bean>

    <!-- Redis模板对象:是SpringDataRedis提供的用户操作Redis的对象 -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    <!-- 默认的序列化器:序列化器就是根据规则将存储的数据中的key与value做字符串的序列化处理 -->
    <!-- keySerializer、valueSerializer:对应的是Redis中的String类型 -->
    <!-- hashKeySerializer、hashValueSerializer:对应的是Redis中的Hash类型 -->
    <property name="keySerializer">
        <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
    </property>
    <property name="valueSerializer">
        <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
    </property>
    </bean>
</beans>

redis.properties

redis.pool.maxtTotal=20
redis.pool.maxIdle=10
redis.pool.minIdle=5

redis.hostname=192.168.70.129
redis.port=6379

编写测试类

RedisTest.java

package com.bjsxt.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Redis测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RedisTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 添加键值对
     */
    @Test
    public void test1(){
        this.redisTemplate.opsForValue().set("key", "test");
    }

    /**
     * 获取redis中的数据
     */
    @Test
    public void test2(){
        String str = (String)this.redisTemplate.opsForValue().get("key");
        System.out.println(str);
    }

}

存储实体对象

编写实体类

要实现序列化接口Serializable

Users.java

package com.bjsxt.pojo;

import java.io.Serializable;

public class Users implements Serializable{

    private Integer id;
    private String name;
    private Integer age;
    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;
    }
    @Override
    public String toString() {
        return "Users [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

}

编写测试类

默认序列化StringRedisSerializer在配置文件applicationContext.xml中指定,测试的时候可以更换序列化器

RedisTest.java

package com.bjsxt.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.bjsxt.pojo.Users;

/**
 * Redis测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RedisTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 添加Users
     */
    @Test
    public void test3(){
        Users users = new Users();
        users.setAge(30);
        users.setId(1);
        users.setName("张三");
        //更换序列化器
        this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        this.redisTemplate.opsForValue().set("users", users);
    }

    /**
     * 获取Users
     * 
     */
    @Test
    public void test4(){
        //更换序列化器
        this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        Users users = (Users)this.redisTemplate.opsForValue().get("users");
        System.out.println(users);
    }

}

以 JSON格式存储对象

导入jar包

jackson-annotations-2.8.0.jar

jackson-core-2.8.10.jar

jackson-databind-2.8.10.jar

编写实体类

实现序列化接口

Users.java

package com.bjsxt.pojo;

import java.io.Serializable;

public class Users implements Serializable{

    private Integer id;
    private String name;
    private Integer age;
    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;
    }
    @Override
    public String toString() {
        return "Users [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

}

编写测试类

设置json序列化器this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));

RedisTest.java

package com.bjsxt.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.bjsxt.pojo.Users;

/**
 * Redis测试
 * @author Administrator
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RedisTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 添加Users JSON格式
     */
    @Test
    public void test5(){
        Users users = new Users();
        users.setAge(23);
        users.setId(2);
        users.setName("李四");

        this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
        this.redisTemplate.opsForValue().set("usersjson", users);
    }

    /**
     * 获取Uesrs JSON格式
     */
    @Test
    public void test6(){
        this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
        Users users = (Users)this.redisTemplate.opsForValue().get("usersjson");
        System.out.println(users);
    }
}

  目录