环境说明,使用Jdk1.8版本,spring4.2.0.RELEASE版本、hibernate5.0.7.Final版本,spring-data-jpa-1.9.0.RELEASE版本、spring-data-redis-1.6.0.RELEASE版本。

1、Spring整合Hibernate的依赖jar包配置,修改pom.xml配置如下所示:

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0"
  3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5          http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6     <modelVersion>4.0.0</modelVersion>
  7 
  8     <groupId>com.bie</groupId>
  9     <artifactId>spring-hibernate</artifactId>
 10     <version>1.0-SNAPSHOT</version>
 11 
 12     <dependencies>
 13         <!-- Spring IOC容器依赖的jar包 -->
 14         <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
 15         <dependency>
 16             <groupId>org.springframework</groupId>
 17             <artifactId>spring-context</artifactId>
 18             <version>4.2.0.RELEASE</version>
 19         </dependency>
 20         <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
 21         <dependency>
 22             <groupId>org.springframework</groupId>
 23             <artifactId>spring-core</artifactId>
 24             <version>4.2.0.RELEASE</version>
 25         </dependency>
 26         <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
 27         <dependency>
 28             <groupId>org.springframework</groupId>
 29             <artifactId>spring-beans</artifactId>
 30             <version>4.2.0.RELEASE</version>
 31         </dependency>
 32 
 33         <!-- Spring AOP容器依赖的jar包 -->
 34         <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
 35         <dependency>
 36             <groupId>org.springframework</groupId>
 37             <artifactId>spring-aop</artifactId>
 38             <version>4.2.0.RELEASE</version>
 39         </dependency>
 40         <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
 41         <dependency>
 42             <groupId>org.springframework</groupId>
 43             <artifactId>spring-aspects</artifactId>
 44             <version>4.2.0.RELEASE</version>
 45         </dependency>
 46         <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
 47         <dependency>
 48             <groupId>org.aspectj</groupId>
 49             <artifactId>aspectjrt</artifactId>
 50             <version>1.9.2</version>
 51         </dependency>
 52 
 53         <!-- Spring JDBC依赖的jar包 -->
 54         <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
 55         <dependency>
 56             <groupId>org.springframework</groupId>
 57             <artifactId>spring-jdbc</artifactId>
 58             <version>4.2.0.RELEASE</version>
 59         </dependency>
 60         <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
 61         <dependency>
 62             <groupId>org.springframework</groupId>
 63             <artifactId>spring-tx</artifactId>
 64             <version>4.2.0.RELEASE</version>
 65         </dependency>
 66 
 67         <!-- Spring ORM依赖的jar包 -->
 68         <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
 69         <dependency>
 70             <groupId>org.springframework</groupId>
 71             <artifactId>spring-orm</artifactId>
 72             <version>4.2.0.RELEASE</version>
 73         </dependency>
 74         <!-- Spring 测试依赖的jar包 -->
 75         <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
 76         <dependency>
 77             <groupId>org.springframework</groupId>
 78             <artifactId>spring-test</artifactId>
 79             <version>4.2.0.RELEASE</version>
 80             <scope>test</scope>
 81         </dependency>
 82 
 83         <!-- apache-logging依赖的jar包 -->
 84         <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
 85         <dependency>
 86             <groupId>commons-logging</groupId>
 87             <artifactId>commons-logging</artifactId>
 88             <version>1.1.1</version>
 89         </dependency>
 90 
 91         <!-- hibernate核心依赖jar包,此依赖下面包含8个依赖,共9个依赖包 -->
 92         <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
 93         <dependency>
 94             <groupId>org.hibernate</groupId>
 95             <artifactId>hibernate-core</artifactId>
 96             <version>5.0.7.Final</version>
 97         </dependency>
 98 
 99         <!-- mysql的依赖jar包 -->
100         <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
101         <dependency>
102             <groupId>mysql</groupId>
103             <artifactId>mysql-connector-java</artifactId>
104             <version>5.1.6</version>
105         </dependency>
106 
107         <!-- c3p0的依赖jar包 -->
108         <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
109         <dependency>
110             <groupId>com.mchange</groupId>
111             <artifactId>c3p0</artifactId>
112             <version>0.9.5.2</version>
113         </dependency>
114         <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
115         <dependency>
116             <groupId>org.hibernate</groupId>
117             <artifactId>hibernate-c3p0</artifactId>
118             <version>5.0.7.Final</version>
119         </dependency>
120 
121         <!-- hibernate-jpa的依赖jar包 -->
122         <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
123         <dependency>
124             <groupId>org.hibernate</groupId>
125             <artifactId>hibernate-entitymanager</artifactId>
126             <version>5.0.7.Final</version>
127         </dependency>
128 
129         <!-- junit的依赖jar包 -->
130         <!-- https://mvnrepository.com/artifact/junit/junit -->
131         <dependency>
132             <groupId>junit</groupId>
133             <artifactId>junit</artifactId>
134             <version>4.12</version>
135             <scope>test</scope>
136         </dependency>
137 
138 
139     </dependencies>
140 
141 </project>

在配置文件applicationContext.xml中定义框架整合,将hibernate的配置整合到spring的applicationContext.xml的配置文件中。

1 jdbc.url=jdbc:mysql://localhost:3306/biehl?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
2 jdbc.driver.class=com.mysql.jdbc.Driver
3 jdbc.username=root
4 jdbc.password=123456 
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xmlns:tx="http://www.springframework.org/schema/tx"
 6        xsi:schemaLocation="http://www.springframework.org/schema/beans
 7     http://www.springframework.org/schema/beans/spring-beans.xsd
 8     http://www.springframework.org/schema/context
 9     http://www.springframework.org/schema/context/spring-context.xsd
10     http://www.springframework.org/schema/tx
11     http://www.springframework.org/schema/tx/spring-tx.xsd">
12 
13     <!-- 1、配置读取properties文件的工具类 -->
14     <context:property-placeholder location="classpath:jdbc.properties"/>
15 
16     <!-- 2、配置c3p0数据库连接池,ComboPooledDataSource创建数据库链接池,实例化该类。 -->
17     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
18         <property name="jdbcUrl" value="${jdbc.url}"/>
19         <property name="driverClass" value="${jdbc.driver.class}"/>
20         <property name="user" value="${jdbc.username}"/>
21         <property name="password" value="${jdbc.password}"/>
22     </bean>
23 
24     <!-- 3、配置Hibernate的SeesionFactory,LocalSessionFactoryBean有3.x、4.x、5.x版本,根据自己的hibernate进行选择 -->
25     <!-- LocalSessionFactoryBean在spring启动的时候帮助我们初始化hibernate的sessionFactory对象。 -->
26     <!-- 注意:hibernate的上下文对象交由spring来进行管理,不再需要我们手动进行创建了的。 -->
27     <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
28         <!-- 将c3p0的数据库链接池注入到sessionFactory对象实例中。 -->
29         <property name="dataSource" ref="dataSource"/>
30         <!-- hibernateProperties属性:配置与hibernate相关的内容,如显示sql语句,开启正向工程 -->
31         <property name="hibernateProperties">
32             <props>
33                 <!-- 显示当前执行的sql语句,后台打印执行的sql语句。 -->
34                 <prop key="hibernate.show_sql">true</prop>
35                 <!-- 开启正向工程,可以帮助生成数据表。 -->
36                 <prop key="hibernate.hbm2ddl.auto">update</prop>
37             </props>
38         </property>
39         <!-- 扫描实体所在的包 -->
40         <property name="packagesToScan">
41             <list>
42                 <!-- 实体类所在的包。 -->
43                 <value>com.bie.po</value>
44             </list>
45         </property>
46     </bean>
47 
48     <!-- 4、配置Hibernate的事务管理器 -->
49     <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
50         <!-- 将spring创建的sessionFactory注入到事务管理器中 -->
51         <property name="sessionFactory" ref="sessionFactory"/>
52     </bean>
53 
54     <!-- 5、配置开启注解事务处理,如果需要通过注解开启事务的话。开启注解就可以完成使用注解管理事务。 -->
55     <tx:annotation-driven transaction-manager="transactionManager"/>
56 
57     <!-- 6、配置spring IOC的注解扫描 -->
58     <context:component-scan base-package="com.bie"/>
59 
60     <!-- 7、配置HiberanteTemplate对象 -->
61     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
62         <!-- 将spring创建的sessionFactory注入HiberanteTemplate中 -->
63         <property name="sessionFactory" ref="sessionFactory"/>
64     </bean>
65 
66 </beans>

创建实体类,如下所示:

 1 package com.bie.po;
 2 
 3 import javax.persistence.*;
 4 
 5 @Entity // 表示当前类是实体类
 6 @Table(name = "tb_users") // 告诉hibernate该实体类和数据表进行映射,如果开启了正向工程管理,name则是数据表的名称了。
 7 public class Users {
 8 
 9     @Id // 表示主键
10     @GeneratedValue(strategy = GenerationType.IDENTITY) // GenerationType.IDENTITY表示自增长的策略
11     @Column(name = "userId") // 告诉hibernate当前对象的属性和这个表里面的字段是对应的,需要做他俩的映射处理
12     // 同时,如果是正向工程,创建一个数据表的时候,这个数据表的一个字段的名称就是userId
13     private Integer id;
14 
15     @Column(name = "userName")
16     private String name;
17 
18     @Column(name = "userAge")
19     private Integer age;
20 
21     public Integer getId() {
22         return id;
23     }
24 
25     public void setId(Integer id) {
26         this.id = id;
27     }
28 
29     public String getName() {
30         return name;
31     }
32 
33     public void setName(String name) {
34         this.name = name;
35     }
36 
37     public Integer getAge() {
38         return age;
39     }
40 
41     public void setAge(Integer age) {
42         this.age = age;
43     }
44 
45     @Override
46     public String toString() {
47         return "Users{" +
48                 "id=" + id +
49                 ", name='" + name + '\'' +
50                 ", age=" + age +
51                 '}';
52     }
53 
54     public Users(String name) {
55         this.name = name;
56     }
57 
58     public Users(String name, Integer age) {
59         this.name = name;
60         this.age = age;
61     }
62 
63     public Users() {
64     }
65 }

创建dao层,数据交互层的接口和实现类。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  *
 9  */
10 public interface UserDao {
11 
12     /**
13      * 插入操作
14      *
15      * @param users
16      */
17     public void insertUsers(Users users);
18 
19     /**
20      * 修改操作
21      *
22      * @param users
23      */
24     public void updateUsers(Users users);
25 
26     /**
27      * 删除操作
28      *
29      * @param users
30      */
31     public void deleteUsers(Users users);
32 
33     /**
34      * 根据主键查询操作
35      *
36      * @param userid
37      * @return
38      */
39     public Users selectUsersById(Integer userid);
40 
41     /**
42      * 根据名称查询操作
43      *
44      * @param username
45      * @return
46      */
47     public List<Users> selectUserByName(String username);
48 
49 }

首先使用HQL来进行查询数据,如下所示:

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

 1 package com.bie.dao.impl;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.hibernate.Query;
 6 import org.hibernate.Session;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.orm.hibernate5.HibernateTemplate;
 9 import org.springframework.stereotype.Repository;
10 
11 import java.util.List;
12 
13 @Repository // 注入到IOC容器中
14 public class UserDaoImpl implements UserDao {
15 
16     // Spring提供的操作hibernate的对象HibernateTemplate
17     // 这个HibernateTemplate里面封装了一些对hibernate的方法模板。
18     @Autowired
19     // 第一种实现是继承HibernateDaoSupport,如果使用继承方式的话,需要将sessionFactory注入到HibernateDaoSupport的sessionFactory属性。
20     // 第二种是在配置文件中进行配置,建议此种做法。
21     private HibernateTemplate hibernateTemplate;
22 
23 
24     @Override
25     public void insertUsers(Users users) {
26         this.hibernateTemplate.save(users);
27     }
28 
29     @Override
30     public void updateUsers(Users users) {
31         this.hibernateTemplate.update(users);
32     }
33 
34     @Override
35     public void deleteUsers(Users users) {
36         this.hibernateTemplate.delete(users);
37     }
38 
39     @Override
40     public Users selectUsersById(Integer userid) {
41         return this.hibernateTemplate.get(Users.class, userid);
42     }
43 
44     @Override
45     // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
46     public List<Users> selectUserByName(String username) {
47         // 获取session的两种方法。
48         // 方法一、getCurrentSession:当前session必须要有事务边界,且只能处理唯一的一个事务。
49         // 当事务提交或者回滚后session自动失效。
50 
51         // 方法二、openSession:每次都会打开一个新的session.加入每次使用多次。则获得的是不同session对象。
52         // 使用完毕后我们需要手动的调用colse方法关闭session。
53         Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
54         //sql:select * from t_users where username ='';
55         Query query = session.createQuery("from Users where name = :abc");
56         Query queryTemp = query.setString("abc", username);
57         return queryTemp.list();
58     }
59 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.test.annotation.Rollback;
 9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 import org.springframework.transaction.annotation.Transactional;
12 
13 import java.util.List;
14 
15 /**
16  *
17  */
18 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
19 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
20 public class UsersDaoImplTest {
21 
22     @Autowired
23     private UserDao userDao;
24 
25     /**
26      * 添加用户信息
27      */
28     @Test
29     @Transactional // 在测试类对于事务提交方式默认的是回滚。
30     @Rollback(value = false) // 取消自动回滚
31     public void testInsertUsers() {
32         Users users = new Users("张飒飒", 25);
33         this.userDao.insertUsers(users);
34     }
35 
36     /**
37      * 更新用户信息
38      */
39     @Test
40     @Transactional
41     @Rollback(false)
42     public void testUpdateUsers() {
43         Users users = new Users("张飒飒", 22);
44         users.setId(1);
45         this.userDao.updateUsers(users);
46     }
47 
48     /**
49      * 根据编号查询用户信息
50      */
51     @Test
52     public void testSelectUsersById() {
53         Users users = this.userDao.selectUsersById(1);
54         System.out.println(users);
55     }
56 
57     /**
58      * 删除用户信息
59      */
60     @Test
61     @Transactional
62     @Rollback(false)
63     public void testDeleteUsers() {
64         Users users = new Users();
65         users.setId(1);
66         this.userDao.deleteUsers(users);
67     }
68 
69     @Test
70     @Transactional
71     public void testSelectUserByName() {
72         List<Users> usersList = this.userDao.selectUserByName("张飒飒");
73         for (Users users : usersList) {
74             System.out.println(users.toString());
75         }
76     }
77 }

使用SQL、QBC来进行数据的查询。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  *
 9  */
10 public interface UserDao {
11 
12     /**
13      * 插入操作
14      *
15      * @param users
16      */
17     public void insertUsers(Users users);
18 
19     /**
20      * 修改操作
21      *
22      * @param users
23      */
24     public void updateUsers(Users users);
25 
26     /**
27      * 删除操作
28      *
29      * @param users
30      */
31     public void deleteUsers(Users users);
32 
33     /**
34      * 根据主键查询操作
35      *
36      * @param userid
37      * @return
38      */
39     public Users selectUsersById(Integer userid);
40 
41     /**
42      * 根据名称查询操作
43      *
44      * @param username
45      * @return
46      */
47     public List<Users> selectUserByName(String username);
48 
49     /**
50      * 根据sql语句进行名称的查询。
51      *
52      * @param username
53      * @return
54      */
55     List<Users> selectUserByNameUseSQL(String username);
56 
57     /**
58      * QBC:Query By Criteria
59      * hibernate可以根据QBC放弃掉sql语句、hql的写法。
60      * 所有对数据库的操作都换成了对对象和方法的操作了。
61      *
62      * @param username
63      * @return
64      */
65     List<Users> selectUserByNameUseCriteria(String username);
66 }
 1 package com.bie.dao.impl;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.hibernate.Criteria;
 6 import org.hibernate.Query;
 7 import org.hibernate.Session;
 8 import org.hibernate.criterion.Restrictions;
 9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.orm.hibernate5.HibernateTemplate;
11 import org.springframework.stereotype.Repository;
12 
13 import java.util.List;
14 
15 @Repository // 注入到IOC容器中
16 public class UserDaoImpl implements UserDao {
17 
18     // Spring提供的操作hibernate的对象HibernateTemplate
19     // 这个HibernateTemplate里面封装了一些对hibernate的方法模板。
20     @Autowired
21     // 第一种实现是继承HibernateDaoSupport,如果使用继承方式的话,需要将sessionFactory注入到HibernateDaoSupport的sessionFactory属性。
22     // 第二种是在配置文件中进行配置,建议此种做法。
23     private HibernateTemplate hibernateTemplate;
24 
25 
26     @Override
27     public void insertUsers(Users users) {
28         this.hibernateTemplate.save(users);
29     }
30 
31     @Override
32     public void updateUsers(Users users) {
33         this.hibernateTemplate.update(users);
34     }
35 
36     @Override
37     public void deleteUsers(Users users) {
38         this.hibernateTemplate.delete(users);
39     }
40 
41     @Override
42     public Users selectUsersById(Integer userid) {
43         return this.hibernateTemplate.get(Users.class, userid);
44     }
45 
46     @Override
47     // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
48     public List<Users> selectUserByName(String username) {
49         // 获取session的两种方法。
50         // 方法一、getCurrentSession:当前session必须要有事务边界,且只能处理唯一的一个事务。
51         // 当事务提交或者回滚后session自动失效。
52 
53         // 方法二、openSession:每次都会打开一个新的session.加入每次使用多次。则获得的是不同session对象。
54         // 使用完毕后我们需要手动的调用colse方法关闭session。
55         Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
56         //sql:select * from t_users where username ='';
57         Query query = session.createQuery("from Users where name = :abc");
58         Query queryTemp = query.setString("abc", username);
59         return queryTemp.list();
60     }
61 
62     @Override
63     // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
64     public List<Users> selectUserByNameUseSQL(String username) {
65         Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
66         // 使用原生的sql语句来进行查询操作。
67         Query query = session.createSQLQuery("select * from tb_users where userName = ?")
68                 // sql执行的返回结果和那个实体类对象进行映射。
69                 // HQL已经将数据表名称换成了实体类的名称。
70                 .addEntity(Users.class)
71                 .setString(0, username);
72         return query.list();
73     }
74 
75     @Override
76     // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
77     public List<Users> selectUserByNameUseCriteria(String username) {
78         Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
79         //sql:select * from t_users where username = '张三';
80         // 创建一个QBC:Query By Criteria
81         Criteria c = session.createCriteria(Users.class);
82         // 根据实体类的name字段属性进行查询。将需要查询的内容传递到参数二的位置上。
83         c.add(Restrictions.eq("name", username));
84         return c.list();
85     }
86 
87 }

使用测试类进行测试,如下所示:

  1 package com.bie.test;
  2 
  3 import com.bie.dao.UserDao;
  4 import com.bie.po.Users;
  5 import org.junit.Test;
  6 import org.junit.runner.RunWith;
  7 import org.springframework.beans.factory.annotation.Autowired;
  8 import org.springframework.test.annotation.Rollback;
  9 import org.springframework.test.context.ContextConfiguration;
 10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 11 import org.springframework.transaction.annotation.Transactional;
 12 
 13 import java.util.List;
 14 
 15 /**
 16  *
 17  */
 18 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
 19 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
 20 public class UsersDaoImplTest {
 21 
 22     @Autowired
 23     private UserDao userDao;
 24 
 25     /**
 26      * 添加用户信息
 27      */
 28     @Test
 29     @Transactional // 在测试类对于事务提交方式默认的是回滚。
 30     @Rollback(value = false) // 取消自动回滚
 31     public void testInsertUsers() {
 32         Users users = new Users("张飒飒", 25);
 33         this.userDao.insertUsers(users);
 34     }
 35 
 36     /**
 37      * 更新用户信息
 38      */
 39     @Test
 40     @Transactional
 41     @Rollback(false)
 42     public void testUpdateUsers() {
 43         Users users = new Users("张飒飒", 22);
 44         users.setId(1);
 45         this.userDao.updateUsers(users);
 46     }
 47 
 48     /**
 49      * 根据编号查询用户信息
 50      */
 51     @Test
 52     public void testSelectUsersById() {
 53         Users users = this.userDao.selectUsersById(1);
 54         System.out.println(users);
 55     }
 56 
 57     /**
 58      * 删除用户信息
 59      */
 60     @Test
 61     @Transactional
 62     @Rollback(false)
 63     public void testDeleteUsers() {
 64         Users users = new Users();
 65         users.setId(1);
 66         this.userDao.deleteUsers(users);
 67     }
 68 
 69     @Test
 70     @Transactional
 71     public void testSelectUserByName() {
 72         List<Users> usersList = this.userDao.selectUserByName("张飒飒");
 73         for (Users users : usersList) {
 74             System.out.println(users.toString());
 75         }
 76     }
 77 
 78     /**
 79      * sql语句的查询测试。
 80      */
 81     @Test
 82     @Transactional
 83     public void testSelectUserByNameUseSQL() {
 84         List<Users> list = this.userDao.selectUserByNameUseSQL("张飒飒");
 85         for (Users users : list) {
 86             System.out.println(users);
 87         }
 88     }
 89 
 90     /**
 91      * Criteria 测试
 92      */
 93     @Test
 94     @Transactional
 95     public void testSelectUserByNameUseCriteria() {
 96         List<Users> list = this.userDao.selectUserByNameUseCriteria("张飒飒");
 97         for (Users users : list) {
 98             System.out.println(users);
 99         }
100     }
101 
102 }

 

2、JPA、Hibernate、Hibernate JPA的概念理解:

1)、JPA:由 Sun 公司提供了一个对于持久层操作的标准(该标准包含接口+文档,没有具体的实现) 。
2)、Hibernate:是 Gavin King 此人开发的一套对于持久层操作的自动的 ORM 框架。
3)、Hibernate JPA:是在 Hibernate3.2 版本中提供了对于 JPA 的标准的实现。提供了一套按照 JPA 标准来实现持久层开发的API。

1 <!-- hibernate-jpa的依赖jar包 -->
2 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
3 <dependency>
4     <groupId>org.hibernate</groupId>
5     <artifactId>hibernate-entitymanager</artifactId>
6     <version>5.0.7.Final</version>
7 </dependency>

修改spring的配置文件applicationContext.xml。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xmlns:tx="http://www.springframework.org/schema/tx"
 6        xsi:schemaLocation="http://www.springframework.org/schema/beans
 7     http://www.springframework.org/schema/beans/spring-beans.xsd
 8     http://www.springframework.org/schema/context
 9     http://www.springframework.org/schema/context/spring-context.xsd
10     http://www.springframework.org/schema/tx
11     http://www.springframework.org/schema/tx/spring-tx.xsd">
12 
13     <!-- 1、配置读取properties文件的工具类 -->
14     <context:property-placeholder location="classpath:jdbc.properties"/>
15 
16     <!-- 2、配置c3p0数据库连接池,ComboPooledDataSource创建数据库链接池,实例化该类。 -->
17     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
18         <property name="jdbcUrl" value="${jdbc.url}"/>
19         <property name="driverClass" value="${jdbc.driver.class}"/>
20         <property name="user" value="${jdbc.username}"/>
21         <property name="password" value="${jdbc.password}"/>
22     </bean>
23 
24     <!-- 3、Spring 整合Hibernate JPA配置,EntityManagerFactory对象就是hibernate JPA帮助我们创建Hibernate JPA上下文的工厂 -->
25     <!-- LocalContainerEntityManagerFactoryBean帮助我们创建Hibernate JPA上下文的对象EntityManagerFactory -->
26     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
27         <!-- 将c3p0的数据库链接池注入到sessionFactory对象实例中。 -->
28         <property name="dataSource" ref="dataSource"/>
29         <!-- jpaVendorAdapter是一个接口,HibernateJpaVendorAdapter是实现类。 -->
30         <property name="jpaVendorAdapter">
31             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
32                 <!-- hibernate 相关的属性的注入 --> <!-- 配置数据库类型 -->
33                 <property name="database" value="MYSQL"/>
34                 <!-- 正向工程 自动创建表 -->
35                 <property name="generateDdl" value="true"/>
36                 <!-- 显示执行的 SQL -->
37                 <property name="showSql" value="true"/>
38             </bean>
39         </property> <!-- 扫描实体的包 -->
40         <property name="packagesToScan">
41             <list>
42                 <value>com.bie.po</value>
43             </list>
44         </property>
45     </bean>
46 
47     <!-- 4、配置 Hibernate 的事务管理器 -->
48     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
49         <property name="entityManagerFactory" ref="entityManagerFactory"/>
50     </bean>
51 
52 
53 
54     <!-- 5、配置开启注解事务处理,如果需要通过注解开启事务的话。开启注解就可以完成使用注解管理事务。 -->
55     <tx:annotation-driven transaction-manager="transactionManager"/>
56 
57     <!-- 6、配置spring IOC的注解扫描 -->
58     <context:component-scan base-package="com.bie"/>
59 
60 
61 </beans>

创建dao层,数据交互层的接口和实现类。这里直接使用上面的实体类和dao层的接口,只是重新了dao层接口的实现类。

 1 package com.bie.dao.impl;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.springframework.stereotype.Repository;
 6 
 7 import javax.persistence.EntityManager;
 8 import javax.persistence.PersistenceContext;
 9 import javax.persistence.TypedQuery;
10 import javax.persistence.criteria.CriteriaBuilder;
11 import javax.persistence.criteria.CriteriaQuery;
12 import javax.persistence.criteria.Predicate;
13 import javax.persistence.criteria.Root;
14 import java.util.List;
15 
16 @Repository // 注入到IOC容器中
17 public class UserDaoImpl implements UserDao {
18 
19     // 使用hibernate JPA的对象进行方法的调用
20     @PersistenceContext(name = "entityManagerFactory")
21     private EntityManager entityManager;
22 
23 
24     @Override
25     public void insertUsers(Users users) {
26         this.entityManager.persist(users);
27     }
28 
29     @Override
30     public void updateUsers(Users users) {
31         this.entityManager.merge(users);
32     }
33 
34     @Override
35     public void deleteUsers(Users users) {
36         Users u = this.selectUsersById(users.getId());
37         this.entityManager.remove(u);
38     }
39 
40     @Override
41     public Users selectUsersById(Integer userid) {
42         return this.entityManager.find(Users.class, userid);
43     }
44 
45     /**
46      * Hibernate JPA中的 HQL 语句
47      *
48      * @param username
49      * @return
50      */
51     @Override
52     public List<Users> selectUserByName(String username) {
53         return this.entityManager.createQuery("from Users where name = :abc")
54                 .setParameter("abc", username)
55                 .getResultList();
56     }
57 
58     /**
59      * HibernateJPA 中的 SQL 语句
60      *
61      * @param username
62      * @return
63      */
64     @Override
65     public List<Users> selectUserByNameUseSQL(String username) {
66         //在 Hibernate JPA 中 如果通过?方式来帮顶参数,那么他的查数是从 1 开始的。而 hibernate 中是从 0 开始的。
67         return this.entityManager
68                 .createNativeQuery("select * from tb_users where userName = ?", Users.class)
69                 .setParameter(1, username)
70                 .getResultList();
71     }
72 
73     /**
74      * HibernateJPA 中 QBC 查询
75      *
76      * @param username
77      * @return
78      */
79     @Override
80     public List<Users> selectUserByNameUseCriteria(String username) {
81         // CriteriaBuilder 对象:创建一个 CriteriaQuery,创建查询条件。
82         CriteriaBuilder builber = this.entityManager.getCriteriaBuilder();
83         // CriteriaQuery 对象:执行查询的 Criteria 对象
84         // select * from tb_users
85         CriteriaQuery<Users> query = builber.createQuery(Users.class);
86         // 获取要查询的实体类的对象
87         Root<Users> root = query.from(Users.class);
88         // 封装查询条件
89         Predicate cate = builber.equal(root.get("name"), username);
90         // select * from t_users where username = '张三';
91         query.where(cate);
92         // 执行查询
93         TypedQuery<Users> typeQuery = this.entityManager.createQuery(query);
94         return typeQuery.getResultList();
95     }
96 
97 }

测试代码,可以直接使用上面的测试代码即可。

 

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

3.1)、Spring Data JPA 的技术特点:我们只需要定义接口并集成 Spring Data JPA 中所提供的接 口就可以了,不需要编写接口实现类。Spring Data JPA是基于Hibernate JPA的,Hibernate JPA是依赖于Hibernate的。

 1 <!-- spring-data-jpa的依赖jar包 -->
 2 <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
 3 <dependency>
 4     <groupId>org.springframework.data</groupId>
 5     <artifactId>spring-data-jpa</artifactId>
 6     <version>1.9.0.RELEASE</version>
 7 </dependency>
 8 <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
 9 <dependency>
10     <groupId>org.slf4j</groupId>
11     <artifactId>slf4j-log4j12</artifactId>
12     <version>1.7.2</version>
13     <scope>test</scope>
14 </dependency>

修改spring的配置文件applicationContext.xml。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xmlns:tx="http://www.springframework.org/schema/tx"
 6        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
 7        xsi:schemaLocation="http://www.springframework.org/schema/beans
 8     http://www.springframework.org/schema/beans/spring-beans.xsd
 9     http://www.springframework.org/schema/context
10     http://www.springframework.org/schema/context/spring-context.xsd
11     http://www.springframework.org/schema/data/jpa
12     http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
13     http://www.springframework.org/schema/tx
14     http://www.springframework.org/schema/tx/spring-tx.xsd">
15 
16     <!-- 1、配置读取properties文件的工具类 -->
17     <context:property-placeholder location="classpath:jdbc.properties"/>
18 
19     <!-- 2、配置c3p0数据库连接池,ComboPooledDataSource创建数据库链接池,实例化该类。 -->
20     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
21         <property name="jdbcUrl" value="${jdbc.url}"/>
22         <property name="driverClass" value="${jdbc.driver.class}"/>
23         <property name="user" value="${jdbc.username}"/>
24         <property name="password" value="${jdbc.password}"/>
25     </bean>
26 
27     <!-- 3、Spring 整合Hibernate JPA配置,EntityManagerFactory对象就是hibernate JPA帮助我们创建Hibernate JPA上下文的工厂 -->
28     <!-- LocalContainerEntityManagerFactoryBean帮助我们创建Hibernate JPA上下文的对象EntityManagerFactory -->
29     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
30         <!-- 将c3p0的数据库链接池注入到sessionFactory对象实例中。 -->
31         <property name="dataSource" ref="dataSource"/>
32         <!-- jpaVendorAdapter是一个接口,HibernateJpaVendorAdapter是实现类。 -->
33         <property name="jpaVendorAdapter">
34             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
35                 <!-- hibernate 相关的属性的注入 --> <!-- 配置数据库类型 -->
36                 <property name="database" value="MYSQL"/>
37                 <!-- 正向工程 自动创建表 -->
38                 <property name="generateDdl" value="true"/>
39                 <!-- 显示执行的 SQL -->
40                 <property name="showSql" value="true"/>
41             </bean>
42         </property>
43         <!-- 扫描实体的包 -->
44         <property name="packagesToScan">
45             <list>
46                 <value>com.bie.po</value>
47             </list>
48         </property>
49     </bean>
50 
51     <!-- 4、配置 Hibernate 的事务管理器 -->
52     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
53         <property name="entityManagerFactory" ref="entityManagerFactory"/>
54     </bean>
55 
56     <!-- 5、配置开启注解事务处理,如果需要通过注解开启事务的话。开启注解就可以完成使用注解管理事务。 -->
57     <tx:annotation-driven transaction-manager="transactionManager"/>
58 
59     <!-- 6、配置spring IOC的注解扫描 -->
60     <context:component-scan base-package="com.bie"/>
61 
62 
63     <!-- Spring Data JPA 的配置 -->
64     <!-- base-package:扫描 dao 接口所在的包 -->
65     <jpa:repositories base-package="com.bie.dao"/>
66 
67 </beans>

创建dao层的接口,继承JpaRepository<Users, Integer>,JpaRepository<Users, Integer>泛型参数一是实体类的名称,参数二是实体类的主键类型。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.jpa.repository.JpaRepository;
 5 
 6 /**
 7  * 使用Spring Data JPA
 8  * <p>
 9  * JpaRepository<Users, Integer>泛型参数一是实体类的名称,参数二是实体类的主键类型。
10  */
11 public interface UserDao extends JpaRepository<Users, Integer> {
12 
13 
14 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.test.annotation.Rollback;
 9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 import org.springframework.transaction.annotation.Transactional;
12 
13 /**
14  *
15  */
16 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
17 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
18 public class UsersDaoImplTest {
19 
20     @Autowired
21     private UserDao userDao;
22 
23     /**
24      * 添加用户信息
25      */
26     @Test
27     @Transactional // 在测试类对于事务提交方式默认的是回滚。
28     @Rollback(value = false) // 取消自动回滚
29     public void testInsertUsers() {
30         Users users = new Users("张飒飒", 25);
31         this.userDao.save(users);
32     }
33 
34 
35 }

 

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

1)、第一种,基于方法名称命名规则查询。方法命名规则: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 findByIdLessThanEqual 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,Not Null findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)   
NotIn findByIdNotIn(Collection<?> c) where id not in (?)
True、False findByAaaTue、findByAaaFalse where aaa = true、where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)

 

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.repository.Repository;
 5 
 6 import java.util.List;
 7 
 8 public interface UserDao extends Repository<Users, Integer> {
 9 
10     /**
11      * @param string
12      * @return
13      */
14     List<Users> findByNameIs(String string);
15 
16     /**
17      * @param string
18      * @return
19      */
20     List<Users> findByNameLike(String string);
21 
22     /**
23      * @param name
24      * @param age
25      * @return
26      */
27     List<Users> findByNameAndAgeGreaterThanEqual(String name, Integer age);
28 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.test.context.ContextConfiguration;
 9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10 
11 import java.util.List;
12 
13 /**
14  *
15  */
16 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
17 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
18 public class UsersDaoImplTest {
19 
20     @Autowired
21     private UserDao userDao;
22 
23     /**
24      * 需求:使用用户名作为查询条件
25      */
26     @Test
27     public void test1() {
28         // 判断相等的条件,有三种表示方式。
29         // 第一种什么都不写,默认的就是做相等判断。第二种是IS。第三种是Equal。
30         List<Users> list = this.userDao.findByNameIs("张飒飒");
31         for (Users users : list) {
32             System.out.println(users);
33         }
34     }
35 
36     /**
37      * 需求:根据用户姓名做 Like 处理
38      * <p>
39      * Like:条件关键字
40      */
41     @Test
42     public void test2() {
43         List<Users> list = this.userDao.findByNameLike("张%");
44         for (Users users : list) {
45             System.out.println(users);
46         }
47     }
48 
49     /**
50      * 需求:查询名称为王五,并且他的年龄大于等于 22 岁
51      */
52     @Test
53     public void test3() {
54         List<Users> list = this.userDao.findByNameAndAgeGreaterThanEqual("张飒飒", 22);
55         for (Users users : list) {
56             System.out.println(users);
57         }
58     }
59 
60 
61 }

2)、第二种,基于@Query 注解查询。

通过 JPQL 语句查询,JPQL是通过 Hibernate 的 HQL 演变过来的,它和 HQL 语法及其相似。测试代码,使用上面的测试代码即可。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.jpa.repository.Query;
 5 import org.springframework.data.repository.Repository;
 6 
 7 import java.util.List;
 8 
 9 public interface UserDao extends Repository<Users, Integer> {
10 
11     //使用@Query 注解查询
12     @Query(value = "from Users where name = ?")
13     List<Users> queryUserByNameUseJPQL(String name);
14 
15     @Query("from Users where name like ?")
16     List<Users> queryUserByLikeNameUseJPQL(String name);
17 
18     @Query("from Users where name = ? and age >= ?")
19     List<Users> queryUserByNameAndAge(String name, Integer age);
20 
21 
22 }

通过 SQL 语句查询。nativeQuery属性,默认的是false,表示不开启sql查询,是否对value中的语句做转义。如果是hql就不需要进行转义,如果是sql就需要进行转义的。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.jpa.repository.Query;
 5 import org.springframework.data.repository.Repository;
 6 
 7 import java.util.List;
 8 
 9 public interface UserDao extends Repository<Users, Integer> {
10 
11     // 使用@Query注解查询SQL
12     // nativeQuery:默认的是false,表示不开启sql查询,是否对value中的语句做转义。
13     @Query(value = "select * from tb_users where userName = ?", nativeQuery = true)
14     List<Users> queryUserByNameUseSQL(String name);
15 
16     @Query(value = "select * from tb_users where userName like ?", nativeQuery = true)
17     List<Users> queryUserByLikeNameUseSQL(String name);
18 
19     @Query(value = "select * from tb_users where userName = ? and userAge >= ?", nativeQuery = true)
20     List<Users> queryUserByNameAndAgeUseSQL(String name, Integer age);
21 }

通过@Query 注解完成数据更新,@Modifying 当前语句是一个更新语句。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.jpa.repository.Modifying;
 5 import org.springframework.data.jpa.repository.Query;
 6 import org.springframework.data.repository.Repository;
 7 
 8 import java.util.List;
 9 
10 public interface UserDao extends Repository<Users, Integer> {
11 
12     // 通过@Query注解完成数据更新
13     @Query("update Users set userAge = ? where userId = ?")
14     @Modifying //@Modifying 当前语句是一个更新语句
15     void updateUserAgeById(Integer age, Integer id);
16 }

 

3.3、CrudRepository 接口。该接口里面实现方法就自带事务了,不需要自己配置事务了。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.repository.CrudRepository;
 5 
 6 /**
 7  * CrudRepository接口
 8  */
 9 public interface UserDao extends CrudRepository<Users, Integer> {
10 
11 
12 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.test.annotation.Rollback;
 9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 import org.springframework.transaction.annotation.Transactional;
12 
13 import java.util.ArrayList;
14 import java.util.List;
15 
16 /**
17  *
18  */
19 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
20 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
21 public class UsersDaoImplTest {
22 
23     @Autowired
24     private UserDao userDao;
25 
26     /**
27      * 添加单条数据
28      */
29     @Test
30     public void test1() {
31         Users user = new Users("李四四", 21);
32         this.userDao.save(user);
33     }
34 
35     /**
36      * 批量添加数据
37      */
38     @Test
39     public void test2() {
40         Users user1 = new Users("李四四", 21);
41         Users user2 = new Users("王五五", 22);
42         List<Users> list = new ArrayList<>();
43         list.add(user1);
44         list.add(user2);
45         this.userDao.save(list);
46 
47     }
48 
49     /**
50      * 根据 ID 查询单条数据
51      */
52     @Test
53     public void test3() {
54         Users users = this.userDao.findOne(6);
55         System.out.println(users);
56     }
57 
58     /**
59      * 查询全部数据
60      */
61     @Test
62     public void test4() {
63         List<Users> list = (List<Users>) this.userDao.findAll();
64         for (Users users : list) {
65             System.out.println(users);
66         }
67     }
68 
69     /**
70      * 删除数据
71      */
72     @Test
73     public void test5() {
74         this.userDao.delete(5);
75     }
76 
77     /**
78      * 更新数据 方式一
79      */
80     @Test
81     public void test6() {
82         Users user = this.userDao.findOne(6);
83         user.setName("亚瑟瑟");
84         this.userDao.save(user);
85     }
86 
87     /**
88      * 更新数据 方式二
89      */
90     @Test
91     @Transactional
92     @Rollback(false)
93     public void test7() {
94         // 对象没有关闭,持久化状态的,对对象进行修改都是可以更新到数据库的。
95         Users user = this.userDao.findOne(6);
96         user.setName("王小小");
97     }
98 
99 }

 

3.4、PagingAndSortingRepository 接口,完成分页处理和排序处理,注意这里面的分页是查询全部的数据进行分页处理,是不带查询条件进行查询的。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.repository.PagingAndSortingRepository;
 5 
 6 /**
 7  * PagingAndSortingRepository 接口
 8  */
 9 public interface UserDao extends PagingAndSortingRepository<Users, Integer> {
10 
11 
12 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.data.domain.Page;
 9 import org.springframework.data.domain.PageRequest;
10 import org.springframework.data.domain.Pageable;
11 import org.springframework.data.domain.Sort;
12 import org.springframework.test.context.ContextConfiguration;
13 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
14 
15 import java.util.List;
16 
17 /**
18  *
19  */
20 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
21 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
22 public class UsersDaoImplTest {
23 
24     @Autowired
25     private UserDao userDao;
26 
27     /**
28      * 分页,对数据表所有数据进行查询进行分页,是不带条件的分页查询。
29      */
30     @Test
31     public void test1() {
32         // page,当前页的索引。注意索引都是从0开始的。
33         int page = 0;
34         // size,每页显示3条数据。
35         int size = 3;
36         Pageable pageable = new PageRequest(page, size);
37         Page<Users> p = this.userDao.findAll(pageable);
38         System.out.println("数据的总条数:" + p.getTotalElements());
39         System.out.println("总页数:" + p.getTotalPages());
40         List<Users> list = p.getContent();
41         for (Users users : list) {
42             System.out.println(users);
43         }
44     }
45 
46 
47     /**
48      * 对单列做排序处理
49      */
50     @Test
51     public void test2() {
52         // Sort代表了该对象封装了排序规则以及指定的排序字段(对象的属性来表示)。
53         // direction代表了排序规则。
54         // properties代表了指定做排序的实体类属性。
55         Sort sort = new Sort(Sort.Direction.DESC, "id");
56         List<Users> list = (List<Users>) this.userDao.findAll(sort);
57         for (Users users : list) {
58             System.out.println(users);
59         }
60     }
61 
62     /**
63      * 多列的排序处理
64      */
65     @Test
66     public void test3() {
67         // Sort代表了该对象封装了排序规则以及指定的排序字段(对象的属性来表示)。
68         // direction代表了排序规则。
69         // properties代表了指定做排序的实体类属性。
70         Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "age");
71         Sort.Order order2 = new Sort.Order(Sort.Direction.ASC, "name");
72         Sort sort = new Sort(order1, order2);
73         List<Users> list = (List<Users>) this.userDao.findAll(sort);
74         for (Users users : list) {
75             System.out.println(users);
76         }
77     }
78 
79 }

 

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

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.jpa.repository.JpaRepository;
 5 
 6 /**
 7  * JpaRepository 接口
 8  */
 9 public interface UserDao extends JpaRepository<Users, Integer> {
10 
11 
12 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.test.context.ContextConfiguration;
 9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10 
11 import java.util.List;
12 
13 /**
14  *
15  */
16 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
17 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
18 public class UsersDaoImplTest {
19 
20     @Autowired
21     private UserDao userDao;
22 
23     /**
24      * 查询全部数据
25      */
26     @Test
27     public void test1() {
28         List<Users> list = this.userDao.findAll();
29         for (Users users : list) {
30             System.out.println(users);
31         }
32     }
33 
34 }

 

3.6、JpaSpecificationExecutor 接口,完成多条件查询,并且支持分页与排序。此接口不可以单独使用,需要配合着Jpa中的其他接口配合使用的,因为该接口没有继承于其他接口。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.jpa.repository.JpaRepository;
 5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 6 
 7 /**
 8  * JpaSpecificationExecutor 接口
 9  * 注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着 jpa 中的其他接口一起使用
10  */
11 public interface UserDao extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
12 
13 
14 }

测试代码,如下所示:

  1 package com.bie.test;
  2 
  3 import com.bie.dao.UserDao;
  4 import com.bie.po.Users;
  5 import org.junit.Test;
  6 import org.junit.runner.RunWith;
  7 import org.springframework.beans.factory.annotation.Autowired;
  8 import org.springframework.data.domain.Page;
  9 import org.springframework.data.domain.PageRequest;
 10 import org.springframework.data.domain.Pageable;
 11 import org.springframework.data.domain.Sort;
 12 import org.springframework.data.jpa.domain.Specification;
 13 import org.springframework.test.context.ContextConfiguration;
 14 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 15 
 16 import javax.persistence.criteria.CriteriaBuilder;
 17 import javax.persistence.criteria.CriteriaQuery;
 18 import javax.persistence.criteria.Predicate;
 19 import javax.persistence.criteria.Root;
 20 import java.util.ArrayList;
 21 import java.util.List;
 22 
 23 /**
 24  *
 25  */
 26 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
 27 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
 28 public class UsersDaoImplTest {
 29 
 30     @Autowired
 31     private UserDao userDao;
 32 
 33     /**
 34      * 需求:根据用户姓名查询数据
 35      */
 36     @Test
 37     public void test1() {
 38 
 39         Specification<Users> specification = new Specification<Users>() {
 40             /**
 41              *
 42              * @param root 根对象。封装了查询条件的对象
 43              * @param query 定义了一个基本的查询.一般不使用
 44              * @param cb 创建一个查询条件
 45              * @return Predicate:定义了查询条件
 46              */
 47             @Override
 48             public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
 49                 Predicate pre = cb.equal(root.get("name"), "王五五");
 50                 return pre;
 51             }
 52 
 53         };
 54         List<Users> list = this.userDao.findAll(specification);
 55         for (Users users : list) {
 56             System.out.println(users);
 57         }
 58     }
 59 
 60     /**
 61      * 多条件查询 方式一
 62      * 需求:使用用户姓名以及年龄查询数据
 63      */
 64     @Test
 65     public void test2() {
 66         Specification<Users> specification = new Specification<Users>() {
 67 
 68             @Override
 69             public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
 70                 List<Predicate> list = new ArrayList<>();
 71                 list.add(cb.equal(root.get("name"), "王五五"));
 72                 list.add(cb.equal(root.get("age"), 22));
 73                 //此时条件之间是没有任何关系的。
 74                 Predicate[] arr = new Predicate[list.size()];
 75                 return cb.and(list.toArray(arr));
 76             }
 77 
 78         };
 79         List<Users> list = this.userDao.findAll(specification);
 80         for (Users users : list) {
 81             System.out.println(users);
 82         }
 83     }
 84 
 85     /**
 86      * 多条件查询 方式二
 87      * 需求:使用用户姓名或者年龄查询数据
 88      */
 89     @Test
 90     public void test3() {
 91         Specification<Users> specification = new Specification<Users>() {
 92 
 93             @Override
 94             public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
 95                 return cb.or(cb.equal(root.get("name"), "王五五"), cb.equal(root.get("age"), 22));
 96             }
 97 
 98         };
 99         List<Users> list = this.userDao.findAll(specification);
100         for (Users users : list) {
101             System.out.println(users);
102         }
103     }
104 
105     /**
106      * 需求:查询王姓用户,并且做分页处理
107      */
108     @Test
109     public void test4() {
110         // 条件
111         Specification<Users> specification = new Specification<Users>() {
112 
113             @Override
114             public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
115                 return cb.like(root.get("name").as(String.class), "王%");
116             }
117 
118         };
119 
120         // 分页
121         Pageable pageable = new PageRequest(0, 2);
122         Page<Users> page = this.userDao.findAll(specification, pageable);
123         System.out.println("总条数:" + page.getTotalElements());
124         System.out.println("总页数:" + page.getTotalPages());
125         List<Users> list = page.getContent();
126         for (Users users : list) {
127             System.out.println(users);
128         }
129     }
130 
131     /**
132      * 需求:查询数据库中王姓的用户,并且根据用户id做倒序排序
133      */
134     @Test
135     public void test5() {
136         //条件
137         Specification<Users> specification = new Specification<Users>() {
138 
139             @Override
140             public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
141                 return cb.like(root.get("name").as(String.class), "王%");
142             }
143 
144         };
145         // 排序
146         Sort sort = new Sort(Sort.Direction.DESC, "id");
147         List<Users> list = this.userDao.findAll(specification, sort);
148         for (Users users : list) {
149             System.out.println(users);
150         }
151     }
152 
153     /**
154      * 需求:查询数据库中王姓的用户,做分页处理,并且根据用户id做倒序排序
155      */
156     @Test
157     public void test6() {
158         // 排序等定义
159         Sort sort = new Sort(Sort.Direction.DESC, "id");
160         // 分页的定义
161         Pageable pageable = new PageRequest(0, 2, sort);
162 
163         // 查询条件
164         Specification<Users> specification = new Specification<Users>() {
165 
166             @Override
167             public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
168                 return cb.like(root.get("name").as(String.class), "王%");
169             }
170 
171         };
172         Page<Users> page = this.userDao.findAll(specification, pageable);
173         System.out.println("总条数:" + page.getTotalElements());
174         System.out.println("总页数:" + page.getTotalPages());
175         List<Users> list = page.getContent();
176         for (Users users : list) {
177             System.out.println(users);
178         }
179     }
180 
181 
182 }

 

3.7、用户自定义 Repository 接口,如果上面Jpa接口满足不了需求,可以进行自定义 Repository 接口

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 
 5 /**
 6  * 用户自定义接口
 7  */
 8 public interface UsersRepository {
 9 
10     /**
11      * 根据用户主键信息查询用户信息
12      *
13      * @param userid
14      * @return
15      */
16     public Users findUserById(Integer userid);
17 
18 }

 定义自己的业务接口,然后继承自己的自定义Jpa接口。

 1 package com.bie.dao;
 2 
 3 import com.bie.po.Users;
 4 import org.springframework.data.jpa.repository.JpaRepository;
 5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 6 
 7 /**
 8  * 用户自定义接口
 9  */
10 public interface UserDao extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users>, UsersRepository {
11 
12 
13 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Users;
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.test.context.ContextConfiguration;
 9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10 
11 /**
12  *
13  */
14 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
15 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
16 public class UsersDaoImplTest {
17 
18     @Autowired
19     private UserDao userDao;
20 
21 
22     @Test
23     public void test7() {
24         Users users = this.userDao.findUserById(6);
25         System.out.println(users);
26     }
27 
28 }

 

3.7、Spring data Jpa关联映射操作。

需求:是用户与角色的一对一的关联关系,一个用户只能有一个角色,一个角色只能分配给一个用户

 1 package com.bie.po;
 2 
 3 import javax.persistence.*;
 4 
 5 @Entity // 表示当前类是实体类
 6 @Table(name = "tb_users") // 告诉hibernate该实体类和数据表进行映射,如果开启了正向工程管理,name则是数据表的名称了。
 7 public class Users {
 8 
 9     @Id // 表示主键
10     @GeneratedValue(strategy = GenerationType.IDENTITY) // GenerationType.IDENTITY表示自增长的策略
11     @Column(name = "userId") // 告诉hibernate当前对象的属性和这个表里面的字段是对应的,需要做他俩的映射处理
12     // 同时,如果是正向工程,创建一个数据表的时候,这个数据表的一个字段的名称就是userId
13     private Integer id;
14 
15     @Column(name = "userName")
16     private String name;
17 
18     @Column(name = "userAge")
19     private Integer age;
20 
21     @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
22     // @JoinColumn:就是维护一个外键,该外键就是用户和角色关联的一个键
23     @JoinColumn(name = "roles_id")
24     private Roles roles;// 该roles对象就表示当前对象所对应的角色。
25 
26     public Integer getId() {
27         return id;
28     }
29 
30     public void setId(Integer id) {
31         this.id = id;
32     }
33 
34     public String getName() {
35         return name;
36     }
37 
38     public void setName(String name) {
39         this.name = name;
40     }
41 
42     public Integer getAge() {
43         return age;
44     }
45 
46     public void setAge(Integer age) {
47         this.age = age;
48     }
49 
50     @Override
51     public String toString() {
52         return "Users{" +
53                 "id=" + id +
54                 ", name='" + name + '\'' +
55                 ", age=" + age +
56                 '}';
57     }
58 
59     public Users(String name) {
60         this.name = name;
61     }
62 
63     public Users(String name, Integer age) {
64         this.name = name;
65         this.age = age;
66     }
67 
68     public Users() {
69     }
70 
71     public Roles getRoles() {
72         return roles;
73     }
74 
75     public void setRoles(Roles roles) {
76         this.roles = roles;
77     }
78 }

角色的实体类,如下所示:

 1 package com.bie.po;
 2 
 3 import javax.persistence.*;
 4 
 5 @Entity
 6 @Table(name = "tb_roles")
 7 public class Roles {
 8 
 9 
10     @Id
11     @GeneratedValue(strategy = GenerationType.IDENTITY)
12     @Column(name = "roleId")
13     private Integer roleId;// 角色编号
14 
15     @Column(name = "roleName")
16     private String roleName;// 角色名称
17 
18     // 注意,这里面的mappedBy的值就是用户实体类里面的角色的对象实例名称
19     // 将那个对象关联进行,去关联跟这个用户里面相同的角色对应的用户。
20     @OneToOne(mappedBy = "roles")
21     private Users users;// 表示当前角色对应的用户
22 
23     public Integer getRoleId() {
24         return roleId;
25     }
26 
27     public void setRoleId(Integer roleId) {
28         this.roleId = roleId;
29     }
30 
31     public String getRoleName() {
32         return roleName;
33     }
34 
35     public void setRoleName(String roleName) {
36         this.roleName = roleName;
37     }
38 
39     public Roles(String roleName) {
40         this.roleName = roleName;
41     }
42 
43     @Override
44     public String toString() {
45         return "Roles{" +
46                 "roleId=" + roleId +
47                 ", roleName='" + roleName + '\'' +
48                 '}';
49     }
50 
51     public Roles() {
52     }
53 
54     public Users getUsers() {
55         return users;
56     }
57 
58     public void setUsers(Users users) {
59         this.users = users;
60     }
61 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Roles;
 5 import com.bie.po.Users;
 6 import org.junit.Test;
 7 import org.junit.runner.RunWith;
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 
12 /**
13  *
14  */
15 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
16 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
17 public class UsersDaoImplTest {
18 
19     @Autowired
20     private UserDao userDao;
21 
22     // 添加用户的同时,添加角色
23 
24     /**
25      * 一对一关联关系的添加
26      */
27     @Test
28     public void testSave() {
29         // 创建一个用户
30         Users users = new Users("admin", 22);
31 
32         // 创建一个角色
33         Roles roles = new Roles("管理员");
34 
35         // 关联,建立双向关系
36         users.setRoles(roles);
37         roles.setUsers(users);
38 
39 
40         // 新增,插入用户的时候进行级联操作。
41         this.userDao.save(users);
42     }
43 
44     /**
45      * 一对一关联关系的查询
46      */
47     @Test
48     public void testSelect() {
49         Users users = this.userDao.findOne(1);
50         System.out.println(users.toString());
51         System.out.println(users.getRoles().toString());
52     }
53 }

 

需求:一对多的关联关系,需求是用户与角色的一对多的关联关系,一个用户只能有一个角色,一个角色只能分配给多个用户,用户对用户是一对多的关联关系。

 1 package com.bie.po;
 2 
 3 import javax.persistence.*;
 4 
 5 @Entity // 表示该类是实体类
 6 @Table(name = "tb_users") // 表示该实体类和数据表进行映射,name表示实体类和数据表进行映射
 7 // 如果使用的是正向工程的话,name属性的值表示的是数据表的表名称。
 8 public class Users {
 9 
10     @Id // 表示该字段是主键
11     @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键的生成策略
12     @Column(name = "id") // 表示实体类的字段和数据表的字段进行映射的关系,如果是正向工程的话,name的值就是数据表的字段名称
13     private Integer id;// 用户编号
14 
15     @Column(name = "name")
16     private String name;// 用户姓名
17 
18     @Column(name = "age")
19     private Integer age;// 用户年龄
20 
21     @Column(name = "address")
22     private String address;// 用户地址
23 
24     // 用户是多方,角色是一方,所以一个用户只能分配一个角色
25     @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) // 用户对角色,多对一关系
26     @JoinColumn(name = "roles_id") // 该注解的作用就是为了维护一个外键,外键在Users这一侧
27     // 可以通过正向工程在数据表新增一个字段。
28     private Roles roles;
29 
30 
31     // alt + insert来生成构造器、setter\getter等等方法
32     public Integer getId() {
33         return id;
34     }
35 
36     public void setId(Integer id) {
37         this.id = id;
38     }
39 
40     public String getName() {
41         return name;
42     }
43 
44     public void setName(String name) {
45         this.name = name;
46     }
47 
48     public Integer getAge() {
49         return age;
50     }
51 
52     public void setAge(Integer age) {
53         this.age = age;
54     }
55 
56     public String getAddress() {
57         return address;
58     }
59 
60     public void setAddress(String address) {
61         this.address = address;
62     }
63 
64     @Override
65     public String toString() {
66         return "Users{" +
67                 "id=" + id +
68                 ", name='" + name + '\'' +
69                 ", age=" + age +
70                 ", address='" + address + '\'' +
71                 '}';
72     }
73 
74     public Users(String name, Integer age, String address) {
75         this.name = name;
76         this.age = age;
77         this.address = address;
78     }
79 
80 
81     public Users() {
82     }
83 
84     public Roles getRoles() {
85         return roles;
86     }
87 
88     public void setRoles(Roles roles) {
89         this.roles = roles;
90     }
91 
92 }

角色的实体类,如下所示:

 1 package com.bie.po;
 2 
 3 import javax.persistence.*;
 4 import java.util.HashSet;
 5 import java.util.Set;
 6 
 7 @Entity
 8 @Table(name = "tb_roles")
 9 public class Roles {
10 
11     @Id
12     @GeneratedValue(strategy = GenerationType.IDENTITY)
13     @Column(name = "roleId")
14     private Integer roleId;// 角色编号
15 
16     @Column(name = "roleName")
17     private String roleName;// 角色名称
18 
19     // 角色是多的方式,一个角色可以分配给多个用户
20     @OneToMany(mappedBy = "roles")
21     //表示一对多的关系,mappedBy表示向Set集合放Users,放的是当前roles相同的,外键和主键相同的
22     // 表示外键和主键相同的,做在角色表里面角色和那个用户之间的描述。
23     private Set<Users> usersSet = new HashSet<Users>();
24 
25     public Integer getRoleId() {
26         return roleId;
27     }
28 
29     public void setRoleId(Integer roleId) {
30         this.roleId = roleId;
31     }
32 
33     public String getRoleName() {
34         return roleName;
35     }
36 
37     public void setRoleName(String roleName) {
38         this.roleName = roleName;
39     }
40 
41     @Override
42     public String toString() {
43         return "Roles{" +
44                 "roleId=" + roleId +
45                 ", roleName='" + roleName + '\'' +
46                 '}';
47     }
48 
49     public Roles(String roleName) {
50         this.roleName = roleName;
51     }
52 
53     public Roles() {
54     }
55 
56     public Set<Users> getUsersSet() {
57         return usersSet;
58     }
59 
60     public void setUsersSet(Set<Users> usersSet) {
61         this.usersSet = usersSet;
62     }
63 
64 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.UserDao;
 4 import com.bie.po.Roles;
 5 import com.bie.po.Users;
 6 import org.junit.Test;
 7 import org.junit.runner.RunWith;
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 
12 /**
13  *
14  */
15 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
16 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
17 public class UsersDaoImplTest {
18 
19     @Autowired
20     private UserDao userDao;
21 
22     // 添加用户的同时,添加角色
23 
24     /**
25      * 一对多关联关系的添加
26      */
27     @Test
28     public void testSave() {
29         // 创建一个用户
30         Users users = new Users("admin", 22, "北京市西城区");
31 
32         // 创建一个角色
33         Roles roles = new Roles("管理员");
34 
35         // 关联,建立双向关系
36         users.setRoles(roles);
37         roles.getUsersSet().add(users);
38 
39 
40         // 新增,插入用户的时候进行级联操作。
41         this.userDao.save(users);
42     }
43 
44     /**
45      * 一对多关联关系的查询
46      */
47     @Test
48     public void testSelect() {
49         Users users = this.userDao.findOne(5);
50         System.out.println(users.toString());
51         System.out.println(users.getRoles().toString());
52     }
53 }

如果出现下面的错误:

可以使用@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)。

Spring Data JPA中有四种Cascade 类型:

1)、PERSIST:持久保存拥有的实体,也会持久保存该实体的属于相关数据。

2)、MERGE:将分离的实体重新合并到活动的持久性上下文时,也会合并该实体的所有数据。

3)、REMOVE:删除一个实体时候,也删除该实体的所有数据。

4)、ALL:以上都适用。

Spring Data JPA中有两种fetch 类型:

1)、FetchType.EAGE:如果是EAGER,那么表示取出这条数据时,它关联的数据也同时取出放入内存中。

2)、FetchType.LAZY:如果是LAZY,那么取出这条数据时,它关联的数据并不取出来,在同一个session中,什么时候要用,就什么时候取(再次访问数据库)。

 1 org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles
 2 
 3     at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
 4     at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223)
 5     at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
 6     at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
 7     at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
 8     at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
 9     at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
10     at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
11     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
12     at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
13     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
14     at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:119)
15     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
16     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
17     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
18     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
19     at com.sun.proxy.$Proxy33.save(Unknown Source)
20     at com.bie.test.UsersDaoImplTest.testSave(UsersDaoImplTest.java:40)
21     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
22     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
23     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
24     at java.lang.reflect.Method.invoke(Method.java:498)
25     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
26     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
27     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
28     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
29     at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
30     at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:85)
31     at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:86)
32     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
33     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:241)
34     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
35     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
36     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
37     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
38     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
39     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
40     at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
41     at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
42     at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
43     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
44     at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
45     at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
46     at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
47     at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
48     at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
49 Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles
50     at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1689)
51     at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
52     at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
53     at org.hibernate.jpa.internal.EntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(EntityManagerImpl.java:235)
54     at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2967)
55     at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
56     at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
57     at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
58     at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
59     at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
60     at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
61     at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
62     at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
63     ... 43 more
64 Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles
65     at org.hibernate.engine.spi.CascadingActions$8.noCascade(CascadingActions.java:379)
66     at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:126)
67     at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:150)
68     at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:141)
69     at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:74)
70     at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
71     at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
72     at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
73     at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
74     ... 51 more
75 
76 
77 Process finished with exit code -1

 

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

1 package com.bie.dao;
2 
3 import com.bie.po.Roles;
4 import org.springframework.data.jpa.repository.JpaRepository;
5 
6 public interface RoleDao extends JpaRepository<Roles, Integer> {
7 
8 
9 }

角色信息的实体类,代码如下所示。

 1 package com.bie.po;
 2 
 3 import javax.persistence.*;
 4 import java.util.HashSet;
 5 import java.util.Set;
 6 
 7 @Entity
 8 @Table(name = "tb_roles")
 9 public class Roles {
10 
11 
12     @Id
13     @GeneratedValue(strategy = GenerationType.IDENTITY)
14     @Column(name = "roleId")
15     private Integer roleId;// 角色编号
16 
17     @Column(name = "roleName")
18     private String roleName;// 角色名称
19 
20     @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) // 放弃延迟加载,改为立即加载。
21     // @JoinTable:配置中间表信息
22     // joinColumns:建立当前表在中间表中的外键字段
23     @JoinTable(name = "t_roles_menus", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "menu_id"))
24     private Set<Menus> menus = new HashSet<>();
25 
26     public Integer getRoleId() {
27         return roleId;
28     }
29 
30     public void setRoleId(Integer roleId) {
31         this.roleId = roleId;
32     }
33 
34     public String getRoleName() {
35         return roleName;
36     }
37 
38     public void setRoleName(String roleName) {
39         this.roleName = roleName;
40     }
41 
42     public Roles(String roleName) {
43         this.roleName = roleName;
44     }
45 
46     @Override
47     public String toString() {
48         return "Roles{" +
49                 "roleId=" + roleId +
50                 ", roleName='" + roleName + '\'' +
51                 '}';
52     }
53 
54     public Roles() {
55     }
56 
57     public Set<Menus> getMenus() {
58         return menus;
59     }
60 
61     public void setMenus(Set<Menus> menus) {
62         this.menus = menus;
63     }
64 }

菜单信息的实体类,如下所示:

 1 package com.bie.po;
 2 
 3 import javax.persistence.*;
 4 import java.util.HashSet;
 5 import java.util.Set;
 6 
 7 @Entity
 8 @Table(name = "tb_menus")
 9 public class Menus {
10 
11     @Id
12     @GeneratedValue(strategy = GenerationType.IDENTITY)
13     @Column(name = "menusid")
14     private Integer menusId;// 菜单编号
15 
16     @Column(name = "menusname")
17     private String menusName;// 菜单名称
18 
19     @Column(name = "menusUrl")
20     private String menusurl;// 菜单路径
21 
22     @Column(name = "fatherid")
23     private Integer fatherId;// 父菜单
24 
25     // 一个菜单可以对应多个角色,一个角色可以对应多个菜单。
26     @ManyToMany(mappedBy = "menus")
27     private Set<Roles> roles = new HashSet<>();
28 
29     public Menus() {
30     }
31 
32     public Menus(String menusName, Integer fatherId, String menusurl) {
33         this.menusName = menusName;
34         this.menusurl = menusurl;
35         this.fatherId = fatherId;
36     }
37 
38     @Override
39     public String toString() {
40         return "Menus{" +
41                 "menusId=" + menusId +
42                 ", menusName='" + menusName + '\'' +
43                 ", menusurl='" + menusurl + '\'' +
44                 ", fatherId=" + fatherId +
45                 ", roles=" + roles +
46                 '}';
47     }
48 
49     public Integer getMenusId() {
50         return menusId;
51     }
52 
53     public void setMenusId(Integer menusId) {
54         this.menusId = menusId;
55     }
56 
57     public String getMenusName() {
58         return menusName;
59     }
60 
61     public void setMenusName(String menusName) {
62         this.menusName = menusName;
63     }
64 
65     public String getMenusurl() {
66         return menusurl;
67     }
68 
69     public void setMenusurl(String menusurl) {
70         this.menusurl = menusurl;
71     }
72 
73     public Integer getFatherId() {
74         return fatherId;
75     }
76 
77     public void setFatherId(Integer fatherId) {
78         this.fatherId = fatherId;
79     }
80 
81     public Set<Roles> getRoles() {
82         return roles;
83     }
84 
85     public void setRoles(Set<Roles> roles) {
86         this.roles = roles;
87     }
88 }

测试代码,如下所示:

 1 package com.bie.test;
 2 
 3 import com.bie.dao.RoleDao;
 4 import com.bie.po.Menus;
 5 import com.bie.po.Roles;
 6 import org.junit.Test;
 7 import org.junit.runner.RunWith;
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 
12 import java.util.Set;
13 
14 /**
15  *
16  */
17 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
18 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
19 public class UsersDaoImplTest {
20 
21     @Autowired
22     private RoleDao roleDao;
23 
24 
25     /**
26      * 添加角色同时添加菜单
27      */
28     @Test
29     public void test1() {
30         // 创建角色对象
31         Roles roles = new Roles("超级管理员");
32         // 创建菜单对象    XXX 管理平台 --->用户管理
33         Menus menus = new Menus("哈哈哈管理平台", -1, "null");
34 
35         // 用户管理菜单
36         Menus menus1 = new Menus("用户管理平台", -1, "null");
37 
38         // 建立关系
39         roles.getMenus().add(menus);
40         roles.getMenus().add(menus1);
41         menus.getRoles().add(roles);
42         menus1.getRoles().add(roles);
43 
44         // 保存数据
45         this.roleDao.save(roles);
46     }
47 
48     /**
49      * 查询 Roles
50      */
51     @Test
52     public void test2() {
53         Roles roles = this.roleDao.findOne(1);
54         System.out.println("角色信息:" + roles);
55         Set<Menus> menus = roles.getMenus();
56         for (Menus menus2 : menus) {
57             System.out.println("菜单信息:" + menus2);
58         }
59     }
60 
61 }

 

4、Spring Data Redis帮助我们更方便,更容易操作Redis。

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0"
  3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5          http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6     <modelVersion>4.0.0</modelVersion>
  7 
  8     <groupId>com.bie</groupId>
  9     <artifactId>spring-redis</artifactId>
 10     <version>1.0-SNAPSHOT</version>
 11 
 12     <dependencies>
 13         <!-- Spring IOC容器依赖的jar包 -->
 14         <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
 15         <dependency>
 16             <groupId>org.springframework</groupId>
 17             <artifactId>spring-context</artifactId>
 18             <version>4.2.0.RELEASE</version>
 19         </dependency>
 20         <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
 21         <dependency>
 22             <groupId>org.springframework</groupId>
 23             <artifactId>spring-core</artifactId>
 24             <version>4.2.0.RELEASE</version>
 25         </dependency>
 26         <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
 27         <dependency>
 28             <groupId>org.springframework</groupId>
 29             <artifactId>spring-beans</artifactId>
 30             <version>4.2.0.RELEASE</version>
 31         </dependency>
 32 
 33         <!-- Spring AOP容器依赖的jar包 -->
 34         <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
 35         <dependency>
 36             <groupId>org.springframework</groupId>
 37             <artifactId>spring-aop</artifactId>
 38             <version>4.2.0.RELEASE</version>
 39         </dependency>
 40         <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
 41         <dependency>
 42             <groupId>org.springframework</groupId>
 43             <artifactId>spring-aspects</artifactId>
 44             <version>4.2.0.RELEASE</version>
 45         </dependency>
 46         <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
 47         <dependency>
 48             <groupId>org.aspectj</groupId>
 49             <artifactId>aspectjrt</artifactId>
 50             <version>1.9.2</version>
 51         </dependency>
 52 
 53         <!-- Spring JDBC依赖的jar包 -->
 54         <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
 55         <dependency>
 56             <groupId>org.springframework</groupId>
 57             <artifactId>spring-jdbc</artifactId>
 58             <version>4.2.0.RELEASE</version>
 59         </dependency>
 60         <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
 61         <dependency>
 62             <groupId>org.springframework</groupId>
 63             <artifactId>spring-tx</artifactId>
 64             <version>4.2.0.RELEASE</version>
 65         </dependency>
 66 
 67         <!-- apache-logging依赖的jar包 -->
 68         <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
 69         <dependency>
 70             <groupId>commons-logging</groupId>
 71             <artifactId>commons-logging</artifactId>
 72             <version>1.1.1</version>
 73         </dependency>
 74 
 75         <!-- Spring 测试依赖的jar包 -->
 76         <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
 77         <dependency>
 78             <groupId>org.springframework</groupId>
 79             <artifactId>spring-test</artifactId>
 80             <version>4.2.0.RELEASE</version>
 81             <scope>test</scope>
 82         </dependency>
 83 
 84         <!-- junit的依赖jar包 -->
 85         <!-- https://mvnrepository.com/artifact/junit/junit -->
 86         <dependency>
 87             <groupId>junit</groupId>
 88             <artifactId>junit</artifactId>
 89             <version>4.12</version>
 90             <scope>test</scope>
 91         </dependency>
 92 
 93         <!-- redis的依赖包、Spring Data JPA的依赖包。 -->
 94         <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
 95         <dependency>
 96             <groupId>org.springframework.data</groupId>
 97             <artifactId>spring-data-redis</artifactId>
 98             <version>1.6.0.RELEASE</version>
 99         </dependency>
100         <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
101         <dependency>
102             <groupId>redis.clients</groupId>
103             <artifactId>jedis</artifactId>
104             <version>2.7.2</version>
105         </dependency>
106 
107 
108     </dependencies>
109 
110 </project>

Spring整合SpringDataRedis整合配置文件application.xml,配置redis连接信息的redis.properties。

 1 # 最大连接数
 2 redis.pool.maxtTotal=20
 3 # 最大空闲数
 4 redis.pool.maxIdle=10
 5 # 最小空闲数
 6 redis.pool.minIdle=5
 7 
 8 # redis的ip地址
 9 redis.hostname=192.168.110.140
10 # redis的端口号
11 redis.port=6379
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans.xsd
 7     http://www.springframework.org/schema/context
 8     http://www.springframework.org/schema/context/spring-context.xsd">
 9 
10     <!-- 配置读取properties文件的工具类 -->
11     <context:property-placeholder location="classpath:redis.properties"/>
12 
13     <!-- Jedis连接池 -->
14     <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
15         <property name="maxTotal" value="${redis.pool.maxtTotal}"/>
16         <property name="maxIdle" value="${redis.pool.maxIdle}"/>
17         <property name="minIdle" value="${redis.pool.minIdle}"/>
18     </bean>
19 
20     <!-- Jedis连接工厂:创建Jedis对象的工厂 -->
21     <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
22         <!-- IP地址 -->
23         <property name="hostName" value="${redis.hostname}"/>
24         <!-- 端口 -->
25         <property name="port" value="${redis.port}"/>
26         <!-- 连接池 -->
27         <property name="poolConfig" ref="poolConfig"/>
28     </bean>
29 
30     <!-- Redis模板对象:是SpringDataRedis提供的用户操作Redis的对象 -->
31     <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
32         <!-- 模板对象注入Jedisd的连接工厂,连接工厂注入redis的ip地址信息,端口号 -->
33         <property name="connectionFactory" ref="jedisConnectionFactory"/>
34         <!-- 默认的序列化器:序列化器就是根据规则将存储的数据中的key与value做字符串的序列化处理 -->
35         <!-- keySerializer、valueSerializer:对应的是Redis中的String类型 -->
36         <!-- hashKeySerializer、hashValueSerializer:对应的是Redis中的Hash类型 -->
37         <property name="keySerializer">
38             <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
39         </property>
40         <property name="valueSerializer">
41             <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
42         </property>
43     </bean>
44 
45 </beans>

测试代码,如下所示:

关闭 linux 防火墙,或者在防火墙中开启 6379 端口。

 1 import org.junit.Test;
 2 import org.junit.runner.RunWith;
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.data.redis.core.RedisTemplate;
 5 import org.springframework.test.context.ContextConfiguration;
 6 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 7 
 8 /**
 9  * @ProjectName: springredis
10  * @Package: PACKAGE_NAME
11  * @ClassName: RedisTest
12  * @Author: biehl
13  * @Description: ${description}
14  * @Date: 2020/5/24 10:16
15  * @Version: 1.0
16  */
17 @RunWith(SpringJUnit4ClassRunner.class)
18 @ContextConfiguration("classpath:applicationContext.xml")
19 public class RedisTest {
20 
21     @Autowired
22     private RedisTemplate<String, Object> redisTemplate;
23 
24     /**
25      * 添加键值对
26      */
27     @Test
28     public void test1() {
29         this.redisTemplate.opsForValue().set("key", "哈哈哈,学好数理化,走遍天下都不怕");
30     }
31 
32     /**
33      * 获取redis中的数据
34      */
35     @Test
36     public void test2() {
37         String str = (String) this.redisTemplate.opsForValue().get("key");
38         System.out.println(str);
39     }
40 
41 
42 }

Spring Data Redisd 存储实体对象。

 1 import com.bie.po.Users;
 2 import org.junit.Test;
 3 import org.junit.runner.RunWith;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.data.redis.core.RedisTemplate;
 6 import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
 7 import org.springframework.test.context.ContextConfiguration;
 8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 9 
10 /**
11  * @ProjectName: springredis
12  * @Package: PACKAGE_NAME
13  * @ClassName: RedisTest
14  * @Author: biehl
15  * @Description: ${description}
16  * @Date: 2020/5/24 10:16
17  * @Version: 1.0
18  */
19 @RunWith(SpringJUnit4ClassRunner.class)
20 @ContextConfiguration("classpath:applicationContext.xml")
21 public class RedisTest {
22 
23     @Autowired
24     private RedisTemplate<String, Object> redisTemplate;
25 
26     /**
27      * 添加Users
28      */
29     @Test
30     public void test3() {
31         // 注意:实体类要实现序列化处理的,不然报异常。
32         Users users = new Users(1, "张三三", 25);
33         //更换序列化器
34         this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
35         this.redisTemplate.opsForValue().set("users", users);
36     }
37 
38     /**
39      * 获取Users
40      */
41     @Test
42     public void test4() {
43         //更换序列化器
44         this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
45         Users users = (Users) this.redisTemplate.opsForValue().get("users");
46         System.out.println(users);
47     }
48 
49 }

Spring Data Redis 以 JSON 的格式存储实体对象。

 1 <!-- jackson的依赖包 -->
 2 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
 3 <dependency>
 4     <groupId>com.fasterxml.jackson.core</groupId>
 5     <artifactId>jackson-databind</artifactId>
 6     <version>2.8.10</version>
 7 </dependency>
 8 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
 9 <dependency>
10     <groupId>com.fasterxml.jackson.core</groupId>
11     <artifactId>jackson-core</artifactId>
12     <version>2.8.10</version>
13 </dependency>
14 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
15 <dependency>
16     <groupId>com.fasterxml.jackson.core</groupId>
17     <artifactId>jackson-annotations</artifactId>
18     <version>2.8.10</version>
19 </dependency>

测试代码,如所示:

 1 import com.bie.po.Users;
 2 import org.junit.Test;
 3 import org.junit.runner.RunWith;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.data.redis.core.RedisTemplate;
 6 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
 7 import org.springframework.test.context.ContextConfiguration;
 8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 9 
10 /**
11  * @ProjectName: springredis
12  * @Package: PACKAGE_NAME
13  * @ClassName: RedisTest
14  * @Author: biehl
15  * @Description: ${description}
16  * @Date: 2020/5/24 10:16
17  * @Version: 1.0
18  */
19 @RunWith(SpringJUnit4ClassRunner.class)
20 @ContextConfiguration("classpath:applicationContext.xml")
21 public class RedisTest {
22 
23     @Autowired
24     private RedisTemplate<String, Object> redisTemplate;
25 
26     /**
27      * 添加Users JSON格式
28      */
29     @Test
30     public void test5() {
31         Users users = new Users(1,"李四四",25);
32 
33         this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
34         this.redisTemplate.opsForValue().set("usersjson", users);
35     }
36 
37     /**
38      * 获取Uesrs JSON格式
39      */
40     @Test
41     public void test6() {
42         this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
43         Users users = (Users) this.redisTemplate.opsForValue().get("usersjson");
44         System.out.println(users);
45     }
46 
47 }