前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring整合Hibernate、Hibernate JPA、Spring Data JPA、Spring Data Redis

Spring整合Hibernate、Hibernate JPA、Spring Data JPA、Spring Data Redis

作者头像
别先生
发布2020-05-27 10:46:03
5.1K0
发布2020-05-27 10:46:03
举报
文章被收录于专栏:别先生别先生

环境说明,使用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配置如下所示:

代码语言:javascript
复制
  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的配置文件中。

代码语言:javascript
复制
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 
代码语言:javascript
复制
 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>

创建实体类,如下所示:

代码语言:javascript
复制
 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层,数据交互层的接口和实现类。

代码语言:javascript
复制
 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 语句中的表与字段名称换成对象与属性的名称就可以了。

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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来进行数据的查询。

代码语言:javascript
复制
 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 }
代码语言:javascript
复制
 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 }

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

代码语言:javascript
复制
  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。

代码语言:javascript
复制
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。

代码语言:javascript
复制
 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层接口的实现类。

代码语言:javascript
复制
 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的。

代码语言:javascript
复制
 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。

代码语言:javascript
复制
 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>泛型参数一是实体类的名称,参数二是实体类的主键类型。

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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(?)

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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 语法及其相似。测试代码,使用上面的测试代码即可。

代码语言:javascript
复制
 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就需要进行转义的。

代码语言:javascript
复制
 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 当前语句是一个更新语句。

代码语言:javascript
复制
 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 接口。该接口里面实现方法就自带事务了,不需要自己配置事务了。

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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 接口,完成分页处理和排序处理,注意这里面的分页是查询全部的数据进行分页处理,是不带查询条件进行查询的。

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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接口是我们开发时使用的最多的接口,其特点是可以帮助我们将其他接口的方法的返回值做适配处理,可以使得我们在开发时更方便的使用这些方法。

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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中的其他接口配合使用的,因为该接口没有继承于其他接口。

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
  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 接口。

代码语言:javascript
复制
 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接口。

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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关联映射操作。

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

代码语言:javascript
复制
 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 }

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

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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 }

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

代码语言:javascript
复制
 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 }

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

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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中,什么时候要用,就什么时候取(再次访问数据库)。

代码语言:javascript
复制
 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

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

代码语言:javascript
复制
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 }

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

代码语言:javascript
复制
 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 }

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

代码语言:javascript
复制
 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 }

测试代码,如下所示:

代码语言:javascript
复制
 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。

代码语言:javascript
复制
  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。

代码语言:javascript
复制
 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
代码语言:javascript
复制
 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 端口。

代码语言:javascript
复制
 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 存储实体对象。

代码语言:javascript
复制
 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 的格式存储实体对象。

代码语言:javascript
复制
 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>

测试代码,如所示:

代码语言:javascript
复制
 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 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档