springdata笔记

时间:2023-06-27 15:51:37

SpringData整合hibernate

CRUD操作:

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.fly.pojo</value>

</list>

</property>

</bean>

<!-- 配置HibernateTemplate对象 -->

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">

<property name="sessionFactory" ref="sessionFactory"></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.fly" />

</beans>

jdbc.properties:

jdbc.url=jdbc:mysql://localhost:3306/test

jdbc.driver.class=com.mysql.jdbc.Driver

jdbc.username=root

jdbc.password=root

实体类:

package com.fly.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) //自增长

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

}

}

UsersDaoImpl:

package com.fly.dao.impl;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.orm.hibernate5.HibernateTemplate;

import org.springframework.stereotype.Repository;

import com.fly.dao.UsersDao;

import com.fly.pojo.Users;

@Repository

public class UsersDaoImpl implements UsersDao{

@Autowired

private HibernateTemplate hibernateTemplate;

@Override

public void insertUsers(Users user) {

this.hibernateTemplate.save(user);

}

@Override

public void updateUsers(Users user) {

this.hibernateTemplate.update(user);

}

@Override

public void deleteUsers(Users user) {

this.hibernateTemplate.delete(user);

}

@Override

public Users selectUsersById(Integer userid) {

Users users = this.hibernateTemplate.get(Users.class, userid);

return users;

}

}

测试类:

package com.fly.test;

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.fly.dao.UsersDao;

import com.fly.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class UserTest {

@Autowired

private UsersDao usersDao;

@Test

@Transactional  //测试类中事务默认提交方式是回滚

@Rollback(false) //取消自动回滚

public void testInsertUser() {

Users user = new Users();

user.setUserage(20);

user.setUsername("张三");

this.usersDao.insertUsers(user );

}

@Test

@Transactional  //测试类中事务默认提交方式是回滚

@Rollback(false) //取消自动回滚

public void testUpdateUser() {

Users user = new Users();

user.setUserid(1);

user.setUserage(21);

user.setUsername("李四");

this.usersDao.updateUsers(user);

}

@Test

public void testSeleteUser() {

Users users = this.usersDao.selectUsersById(1);

System.out.println(users);

}

@Test

@Transactional  //测试类中事务默认提交方式是回滚

@Rollback(false) //取消自动回滚

public void testdeleteUser() {

Users user = new Users();

user.setUserid(1);

this.usersDao.deleteUsers(user);

}

}

HQL查询:

SQL查询:

QBC查询:

/**

* HQL

* 将原来的sql语句中的表与字段名换成对象与属性的名称

*/

@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 = :name").setString("name", username);

return query.list();

}

/**

* SQL

*/

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

}

/**

* QBC

*/

@Override

public List<Users> selectUserByNameUseCriteria(String username) {

Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();

//sql:select * from t_users where username =

Criteria criteria = session.createCriteria(Users.class);

criteria.add(Restrictions.eq("username", username));

return criteria.list();

}

测试:

/**

* HQL

*/

@Test

@Transactional

public void testselectUserByName() {

List<Users> list = this.usersDao.selectUserByName("张三");

for (Users users : list) {

System.out.println(users);

}

}

/**

* SQL

*/

@Test

@Transactional

public void testselectUserByNameUseSQL() {

List<Users> list = this.usersDao.selectUserByNameUseSQL("张三");

for (Users users : list) {

System.out.println(users);

}

}

/**

* QBC

*/

@Test

@Transactional

public void testselectUserByNameUseCriteria() {

List<Users> list = this.usersDao.selectUserByNameUseCriteria("张三");

for (Users users : list) {

System.out.println(users);

}

}

SpringData整合hibernate基于JPA规范:

多一个jar hibernate-entitymanager-5.0.7.Final.jar

CRUD操作:

<?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="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.fly.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.fly" />

</beans>

UsersDaoImpl:

package com.fly.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;

import com.fly.dao.UsersDao;

import com.fly.pojo.Users;

@Repository

public class UsersDaoImpl implements UsersDao{

@PersistenceContext(name="entityManagerFactory")

private EntityManager entityManager;

@Override

public void insertUsers(Users user) {

this.entityManager.persist(user);

}

@Override

public void updateUsers(Users user) {

this.entityManager.merge(user);

}

@Override

public void deleteUsers(Users user) {

Users users = this.selectUsersById(user.getUserid());

this.entityManager.remove(users);

}

@Override

public Users selectUsersById(Integer userid) {

Users users = this.entityManager.find(Users.class, userid);

return users;

}

}

HQL

SQL

QBC

/**

* HQL

* 将原来的sql语句中的表与字段名换成对象与属性的名称

*/

@Override

public List<Users> selectUserByName(String username) {

return this.entityManager.createQuery("from Users where username=:name").setParameter("name", username).getResultList();

}

/**

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

}

/**

* QBC

*/

@Override

public List<Users> selectUserByNameUseCriteria(String username) {

//CriteriaBuilder 对象:创建一个 CriteriaQuery,创建查询条件。

CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();

//CriteriaQuery 对象:执行查询的 Criteria 对象

//select * from t_users

CriteriaQuery<Users> query = builder.createQuery(Users.class);

//获取要查询的实体类的对象

Root<Users> root = query.from(Users.class);

//封装查询条件

Predicate predicate = builder.equal(root.get("username"), username);

//select * from t_users where username =

query.where(predicate);

//执行

TypedQuery<Users> typedQuery = this.entityManager.createQuery(query);

return typedQuery.getResultList();

}

Spring Data JPA:

Spring Data JPA:Spring Data JPA 是 spring data 项目下的一个模块。提供了一套基于 JPA标准操作数据库的简化方案。底层默认的是依赖 Hibernate JPA 来实现的。

Spring Data JPA 的技术特点:我们只需要定义接口并集成 Spring Data JPA 中所提供的接口就可以了。不需要编写接口实现类

在hibernate jpa的基础上:

<?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.fly.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.fly" />

<!-- Spring Data JPA 的配置 -->

<!-- base-package:扫描 dao 接口所在的包 -->

<jpa:repositories base-package="com.fly.dao"/>

</beans>

Dao:

public interface UsersDao extends JpaRepository<Users, Integer> {

}

Repository 接口

Repository 接口是 Spring Data JPA 中为我我们提供的所有接口中的顶层接口

Repository 提供了两种查询方式的支持

1)基于方法名称命名规则查询

2)基于@Query 注解查询

方法名称命名规则查询:

规则:findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)

关键字

方法命名

sql where 字句

And

findByNameAndPwd

where name= ? andpwd =?

Or

findByNameOrSex

where name= ? orsex=?

Is,Equal,都不写

findById,findByIdEqual

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

where name like ?

NotLike

findByNameNotLike

where name notlike ?

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(

Dao:

package com.fly.dao;

import java.util.List;

import org.springframework.data.repository.Repository;

import com.fly.pojo.Users;

/**

* * Repository 接口测试

*/

public interface UsersDao extends Repository<Users, Integer> {

List<Users> findByUsernameIs(String string);

List<Users> findByUsernameLike(String string);

//查询名称为 ,并且他的年龄大于等于

List<Users> findByUsernameAndUserageGreaterThanEqual(String name,Integer age);

}

测试:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class RepositoryTest {

@Autowired

private UsersDao usersDao;

@Test

public void test1() {

List<Users> list = this.usersDao.findByUsernameIs("李四");

for (Users users : list) {

System.out.println(users);

}

}

@Test

public void test2() {

List<Users> list = this.usersDao.findByUsernameLike("李%");

for (Users users : list) {

System.out.println(users);

}

}

@Test

public void test3() {

List<Users> list = this.usersDao.findByUsernameAndUserageGreaterThanEqual("李四",18);

for (Users users : list) {

System.out.println(users);

}

}

}

基于@Query 注解的查询:

  1. 通过 JPQL 语句查询

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

//使用@Query 注解查询

//通过 JPQL 语句查询

@Query(value="from Users where username=?")

List<Users> quertUserByNameUseJPQL(String name);

@Query(value="from Users where username like ?")

List<Users> quertUserByLikeNameUseJPQL(String name);

@Query(value="from Users where username=? and userage >= ?")

List<Users> quertUserByNameAndAgeUseJPQL(String name,Integer age);

测试:

//使用@Query 注解查询

//通过 JPQL 语句查询

@Test

public void test4() {

List<Users> list = this.usersDao.quertUserByNameUseJPQL("李四");

for (Users users : list) {

System.out.println(users);

}

}

@Test

public void test5() {

List<Users> list = this.usersDao.quertUserByLikeNameUseJPQL("李%");

for (Users users : list) {

System.out.println(users);

}

}

@Test

public void test6() {

List<Users> list = this.usersDao.quertUserByNameAndAgeUseJPQL("李四",18);

for (Users users : list) {

System.out.println(users);

}

}

  1. 通过 SQL 语句查询:

//通过 SQL 语句查询

//nativeQuery:默认的是 false.表示不开启 sql 查询。

@Query(value="select * from t_users where username=?",nativeQuery=true)

List<Users> quertUserByNameUseSQL(String name);

@Query(value="select * from t_users where username like ?",nativeQuery=true)

List<Users> quertUserByLikeNameUseSQL(String name);

@Query(value="select * from t_users where username=? and userage >= ?",nativeQuery=true)

List<Users> quertUserByNameAndAgeUseSQL(String name,Integer age);

通过@Query 注解完成数据更新:

//通过@Query 注解完成数据更新

@Query("update Users set username = ? where userid = ?")

@Modifying //当前语句是一个更新语句

void updateUserNameById(String name,Integer id);

测试:

//通过@Query 注解完成数据更新

@Test

@Transactional

@Rollback(false)

public void test10() {

this.usersDao.updateUserNameById("赵六", 4);

}

CrudRepository接口:

接口:

public interface UsersDao extends CrudRepository<Users, Integer> {

}

测试:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class CrudRepositoryTest {

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

user.setUsername("王五22");

Users user1 = new Users();

user1.setUserage(22);

user1.setUsername("王五33");

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

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() {

Users users = this.usersDao.findOne(4);

users.setUsername("王六");

this.usersDao.save(users);

}

/**

* 更新方式二

*/

@Test

@Transactional

@Rollback(false)

public void test6() {

Users users = this.usersDao.findOne(4);

users.setUsername("王七");

}

/**

* 删除

*/

/**

* 更新方式一

*/

@Test

public void test7() {

this.usersDao.delete(4);

}

}

PagingAndSortingRepository 接口:

分页,排序:

接口:

public interface UsersDao2 extends PagingAndSortingRepository<Users, Integer> {

}

测试:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class PagingAndSortingRepositoryTest {

@Autowired

private UsersDao2 usersDao;

/**

* 分页处理

*/

@Test

public void test1() {

int page = 0;//page:当前页的索引。注意索引都是从 0 开始的。

int size = 3;// size:每页显示 3 条数据

Pageable pageable = new PageRequest(page, size);

Page<Users> findAll = this.usersDao.findAll(pageable);

System.out.println("数据的总条数:"+findAll.getTotalElements());

System.out.println("总页数:"+findAll.getTotalPages());

List<Users> list = findAll.getContent();

for (Users users : list) {

System.out.println(users);

}

}

/**

* 对单列做排序处理

*/

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

//import org.springframework.data.domain.Sort.Order;

//Sort:该对象封装了排序规则以及指

//direction:排序规则

//properties:指定做排序的

Order order1 = new Order(Direction.DESC,"userage");

Order order2 = new Order(Direction.ASC,"userid");

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 接口其特点是将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法

接口类:

public interface UsersDao3 extends JpaRepository<Users, Integer> {

}

测试:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class JpaRepositoryTest {

@Autowired

private UsersDao3 usersDao;

/**

* 查询所有数据

*/

@Test

public void test1() {

List<Users> list = this.usersDao.findAll();

for (Users users : list) {

System.out.println(users);

}

}

}

JpaSpecificationExecutor 接口:

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

  1. 单条件查询:

接口:

/**

*  JpaSpecificationExecutor 接口讲解

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

*/

public interface UsersDao4 extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users> {

}

测试:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class JpaSpecificationExecutorTest {

@Autowired

private UsersDao4 usersDao;

/**

* 需求:根据用户姓名查询数据

*/

@Test

public void test1() {

List<Users> list = this.usersDao.findAll(new Specification<Users>() {

/**

* Predicate:定义了查询条件

* Root<Users> root:根对象。封装了查询条件的对象

* CriteriaQuery<?> query:定义了一个基本的查询.一般不使用

* CriteriaBuilder cb:创建一个查询条件

*/

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

Predicate predicate = builder.like(root.get("username"), "王%");

return predicate;

}

});

for (Users users : list) {

System.out.println(users);

}

}

}

  1. 多条件查询:

/**

* 多条件查询 方式一 数组

* 需求:使用用户姓名以及年龄查询数据

*/

@Test

public void test2() {

List<Users> list = this.usersDao.findAll(new Specification<Users>() {

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

List<Predicate> list = new ArrayList<>();

list.add(builder.equal(root.get("username"), "张三"));

list.add(builder.equal(root.get("userage"), 20));

Predicate[] arr = new Predicate[list.size()];

return builder.and(list.toArray(arr));

}

});

for (Users users : list) {

System.out.println(users);

}

}

/**

* 多条件查询 方式二  多参数

* 需求:使用用户姓名或者年龄查询数据

*/

@Test

public void test3() {

List<Users> list = this.usersDao.findAll(new Specification<Users>() {

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

return builder.or(builder.equal(root.get("username"), "张三"),builder.equal(root.get("userage"), 20));

}

});

for (Users users : list) {

System.out.println(users);

}

}

分页排序:

/**

* 分页

* 需求:查询王姓用户,并且做分页处理

*/

@Test

public void test4() {

Specification<Users> specification = new Specification<Users>() {

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

return builder.like(root.get("username").as(String.class), "王%");

}

};

Pageable pageable = new PageRequest(0, 3);

Page<Users> findAll = this.usersDao.findAll(specification, pageable);

System.out.println("总条数"+findAll.getTotalElements());

System.out.println("总页数"+findAll.getTotalPages());

for (Users users : findAll) {

System.out.println(users);

}

}

/**

* 排序

* 需求:查询数据库中王姓的用户,并且根据用户 id 做倒序排序

*/

@Test

public void test5() {

Specification<Users> specification = new Specification<Users>() {

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

return builder.like(root.get("username").as(String.class), "王%");

}

};

Sort sort = new Sort(Direction.DESC,"userid");

List<Users> findAll = this.usersDao.findAll(specification, sort);

for (Users users : findAll) {

System.out.println(users);

}

}

/**

* 分页+排序

*  需求:查询数据库中王姓的用户,做分页处理,并且根据用户 id 做倒序排序

*/

@Test

public void test6() {

Specification<Users> specification = new Specification<Users>() {

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

return builder.like(root.get("username").as(String.class), "王%");

}

};

Sort sort = new Sort(Direction.DESC,"userid");

Pageable pageable = new PageRequest(0, 2, sort);

Page<Users> findAll = this.usersDao.findAll(specification, pageable);

for (Users users : findAll) {

System.out.println(users);

}

}

用户自定义 Repository 接口:

/**

* 自定义 Repository 接口讲

* @author Administrator

*

*/

public interface UsersRepository {

public Users findUserById(Integer userid);

}

//注意UsersDao5Impl ,UsersDao5

public class UsersDao5Impl implements UsersRepository{

@PersistenceContext(name="entityManagerFactory")

private EntityManager entityManager;

@Override

public Users findUserById(Integer userid) {

return this.entityManager.find(Users.class, userid);

}

}

public interface UsersDao5 extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>,UsersRepository{

}

测试:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class UsersRepositoryTest {

@Autowired

private UsersDao5 usersDao;

//需求:根据用户 ID 查询数据

@Test

public void test1() {

Users users = this.usersDao.findUserById(5);

System.out.println(users);

}

}

关联映射操作:

一对一的关联关系

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

用户:一方

角色:一方

public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users> {

}

/**

* Users实体类

* @author Administrator

*

*/

@Entity

@Table(name="t_users")

public class Users implements Serializable{

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY) //自增长

@Column(name="userid")

private Integer userid;

@Column(name="username")

private String username;

@Column(name="userage")

private Integer userage;

@OneToOne(cascade=CascadeType.PERSIST)

@JoinColumn(name="roles_id") //维护的外键

private Roles roles;

/**

* 角色实体类

* @author Administrator

*

*/

@Entity

@Table(name="t_roles")

public class Roles {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

@Column(name="roleid")

private Integer rodeid;

@Column(name="rolename")

private String rolename;

@OneToOne(mappedBy="roles")

private Users users;

测试:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

public class CrudRepositoryTest {

@Autowired

private UsersDao usersDao;

/**

* 一对一关联关系测试

* * 添加用户同时添加角色

*/

@Test

public void test1() {

Roles roles = new Roles();

roles.setRolename("员工1");

Users user = new Users();

user.setUserage(21);

user.setUsername("黄三1");

user.setRoles(roles);

roles.setUsers(user);

this.usersDao.save(user);

}

/**

* 根据用户 ID 查询用户,同时查询用户角色

*/

@Test

public void test2() {

Users users = this.usersDao.findOne(5);

System.out.println("用户信息"+users);

Roles roles = users.getRoles();

System.out.println(roles);

}

}

一对多的关联关系

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

角色:一方

用户:多方

Users.java:

@ManyToOne(cascade=CascadeType.PERSIST)

@JoinColumn(name="roles_id")

private Roles roles;

Roles.java:

@OneToMany(mappedBy="roles")

private Set<Users> users = new HashSet<>();

测试:

/**

*添加用户同时添加角色

*/

@Test

public void test3() {

Roles roles = new Roles();

roles.setRolename("员工2");

Users user = new Users();

user.setUserage(21);

user.setUsername("黄三2");

user.setRoles(roles);

roles.getUsers().add(user);

this.usersDao.save(user);

}

/**

* 根据用户 ID 查询用户信息,同时查询角色

*/

@Test

public void test4() {

Users users = this.usersDao.findOne(17);

System.out.println("用户姓名:"+users.getUsername());

Roles roles = users.getRoles();

System.out.println(roles);

}

多对多的关联关系

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

角色:多方

菜单:多方

public interface RolesDao extends JpaRepository<Roles, Integer>,JpaSpecificationExecutor<Roles> {

}

/**

* 菜单实体类

* @author Administrator

*

*/

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

Roles.java:

@ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)//EAGER 立即加载

//@JoinTable:配置中间表信息//joinColumns:建立当前表在中间表中的外键字段

@JoinTable(name="t_roles_menus",joinColumns=@JoinColumn(name="role_id"),inverseJoinColumns=@JoinColumn(name="menu_id"))

private Set<Menus> menus = new HashSet<>();

测试:

@Autowired

private RolesDao rolesDao;

/**

*  添加角色同时添加菜单

*/

@Test

public void test5() {

Roles roles = new Roles();

roles.setRolename("前台");

Menus menus = new Menus();

menus.setMenusname("xx平台");

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 test6() {

Roles roles = this.rolesDao.findOne(4);

System.out.println("角色信息"+roles);

Set<Menus>menus = roles.getMenus();

for (Menus menus2 : menus) {

System.out.println("菜单信息:"+menus2);

}

}

Spring Data 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"

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:redis.properties"/>

<!-- Jedis连接池 -->

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">

<property name="maxTotal" value="${redis.pool.maxTotal}"/>

<property name="maxIdle" value="${redis.pool.maxIdle}"/>

<property name="minIdle" value="${redis.pool.minIdle}"/>

</bean>

<!-- Jedis的连接工厂 -->

<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

<property name="hostName" value="${redis.conn.hostName}"/>

<property name="port" value="${redis.conn.port}"/>

<property name="poolConfig" ref="poolConfig"/>

</bean>

<!-- Redis模板对象 -->

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

<property name="connectionFactory" ref="jedisConnectionFactory"/>

<!-- 序列化器:能够把我们储存的key与value做序列化处理的对象 -->

<!-- 配置默认的序列化器 -->

<!-- keySerializer、valueSerializer 配置Redis中的String类型key与value的序列化器 -->

<!-- HashKeySerializer、HashValueSerializer 配置Redis中的Hash类型key与value的序列化器 -->

<property name="keySerializer">

<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

</property>

<property name="valueSerializer">

<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

</property>

</bean>

</beans>

redis.properties:

redis.pool.maxTotal=20

redis.pool.maxIdle=10

redis.pool.minIdle=5

redis.conn.hostName=127.0.0.1

redis.conn.port=6379

Users.java:

public class Users implements Serializable{

private Integer id;

private String name;

private Integer age;

测试:

@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 string = (String) this.redisTemplate.opsForValue().get("key");

System.out.println(string);

}

/**

* 添加 Users

*/

@Test

public void test3() {

Users users = new Users();

users.setAge(20);

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

}

/**

* 添加 Users JSON 格式

*/

@Test

public void test5() {

Users users = new Users();

users.setAge(21);

users.setId(2);

users.setName("李四");

this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));

this.redisTemplate.opsForValue().set("userjson", users);

}

/**

* 获取 Uesrs JSON 格式

*/

@Test

public void test6() {

this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));

Users users = (Users) this.redisTemplate.opsForValue().get("userjson");

System.out.println(users);

}

}

构建Maven工程 Spring Data Redis

Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis,  JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。

spring-data-redis针对jedis提供了如下功能:
1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作

<!-- 集中定义依赖版本号 -->

<properties>

<spring.version>4.2.4.RELEASE</spring.version>

</properties>

<dependencies>

<!-- Spring -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aspects</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jms</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-test</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.9</version>

</dependency>

<!-- 缓存 -->

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.8.1</version>

</dependency>

<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-redis</artifactId>

<version>1.7.2.RELEASE</version>

</dependency>

</dependencies>

redis-config.properties:

# Redis settings

# server IP

redis.host=127.0.0.1

# server port

redis.port=6379

# server pass

redis.pass=

# use dbIndex

redis.database=0

redis.maxIdle=300

redis.maxWait=3000

redis.testOnBorrow=true

applicationContext-redis.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:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:cache="http://www.springframework.org/schema/cache"

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/mvc   

            http://www.springframework.org/schema/mvc/spring-mvc.xsd

            http://www.springframework.org/schema/cache  

            http://www.springframework.org/schema/cache/spring-cache.xsd">

<context:property-placeholder

location="classpath*:properties/*.properties" />

<!-- redis 相关配置 -->

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">

<!-- 最大空闲数 -->

<property name="maxIdle" value="${redis.maxIdle}" />

<!-- 连接时的最大等待毫秒数 -->

<property name="maxWaitMillis" value="${redis.maxWait}" />

<!-- 在提取一个jedis实例时,是否提前进行验证操作;如果为true,则得到的jedis实例均是可用的; -->

<property name="testOnBorrow" value="${redis.testOnBorrow}" />

</bean>

<bean id="JedisConnectionFactory"

class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"

p:host-name="${redis.host}" p:port="${redis.port}"

p:password="${redis.pass}" p:pool-config-ref="poolConfig" />

<bean id="redisTemplate"

class="org.springframework.data.redis.core.RedisTemplate">

<property name="connectionFactory"

ref="JedisConnectionFactory" />

</bean>

</beans>

测试:  

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations="classpath:spring/applicationContext-redis.xml")

public class TestRedis {

@Autowired

private RedisTemplate redisTemplate;

/**

* 值类型操作

*/

@Test

public void setValue() {

redisTemplate.boundValueOps("name").set("test");

}

@Test

public void getValue() {

String string = (String) redisTemplate.boundValueOps("name").get();

System.out.println(string);

}

@Test

public void deleteValue() {

redisTemplate.delete("name");

}

/**

* Set类型操作

* set是无序的

*/

@Test

public void setSetValue() {

redisTemplate.boundSetOps("nameset").add("曹操");

redisTemplate.boundSetOps("nameset").add("曹植");

redisTemplate.boundSetOps("nameset").add("曹呸");

}

@Test

public void getSetValue() {

Set set = redisTemplate.boundSetOps("nameset").members();

System.out.println(set);

}

@Test

public void deleteSetValue() {

redisTemplate.boundSetOps("nameset").remove("曹操");

}

@Test

public void deleteAllSetValue() {

redisTemplate.delete("nameset");

}

/**

*  List类型操作

*/

@Test

public void setListValue() {

redisTemplate.boundListOps("namelist1").rightPush("刘备");

redisTemplate.boundListOps("namelist1").rightPush("关羽");

redisTemplate.boundListOps("namelist1").rightPush("张飞");

}

@Test

public void setListValue2() {

redisTemplate.boundListOps("namelist2").leftPush("刘备2");

redisTemplate.boundListOps("namelist2").leftPush("关羽2");

redisTemplate.boundListOps("namelist2").leftPush("张飞2");

}

@Test

public void getListValue() {

List list =  redisTemplate.boundListOps("namelist1").range(0, 10);

System.out.println(list);

}

@Test

public void getListValue2() {

List list =  redisTemplate.boundListOps("namelist2").range(0, 10);

System.out.println(list);

}

//根据索引查询元素

@Test

public void SearchList(){

String string = (String) redisTemplate.boundListOps("namelist1").index(1);

System.out.println(string);

}

// 移除集合某个元素

@Test

public void removeList(){

redisTemplate.boundListOps("namelist1").remove(1, "刘备");//移除一个

}

@Test

public void removeAllList(){

redisTemplate.delete("namelist1");

}

/**

*  Hash类型操作

*/

@Test

public void setHashValue() {

redisTemplate.boundHashOps("namehash").put("a", "唐僧");

redisTemplate.boundHashOps("namehash").put("b", "唐僧1");

redisTemplate.boundHashOps("namehash").put("c", "唐僧2");

redisTemplate.boundHashOps("namehash").put("d", "唐僧3");

}

@Test

public void getHashKeyValue() {

Set set = redisTemplate.boundHashOps("namehash").keys();

System.out.println(set);

}

@Test

public void getHashValValue() {

List list = redisTemplate.boundHashOps("namehash").values();

System.out.println(list);

}

//根据KEY提取值

@Test

public void testGetValueByKey(){

Object object = redisTemplate.boundHashOps("namehash").get("b");

System.out.println(object);

}

//根据KEY移除值

@Test

public void testRemoveValueByKey(){

redisTemplate.boundHashOps("namehash").delete("c");

}

}