环境说明,使用Jdk1.8版本,spring4.2.0.RELEASE版本、hibernate5.0.7.Final版本,spring-data-jpa-1.9.0.RELEASE版本、spring-data-redis-1.6.0.RELEASE版本。
1、Spring整合Hibernate的依赖jar包配置,修改pom.xml配置如下所示:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6 <modelVersion>4.0.0</modelVersion>
7
8 <groupId>com.bie</groupId>
9 <artifactId>spring-hibernate</artifactId>
10 <version>1.0-SNAPSHOT</version>
11
12 <dependencies>
13 <!-- Spring IOC容器依赖的jar包 -->
14 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
15 <dependency>
16 <groupId>org.springframework</groupId>
17 <artifactId>spring-context</artifactId>
18 <version>4.2.0.RELEASE</version>
19 </dependency>
20 <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
21 <dependency>
22 <groupId>org.springframework</groupId>
23 <artifactId>spring-core</artifactId>
24 <version>4.2.0.RELEASE</version>
25 </dependency>
26 <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
27 <dependency>
28 <groupId>org.springframework</groupId>
29 <artifactId>spring-beans</artifactId>
30 <version>4.2.0.RELEASE</version>
31 </dependency>
32
33 <!-- Spring AOP容器依赖的jar包 -->
34 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
35 <dependency>
36 <groupId>org.springframework</groupId>
37 <artifactId>spring-aop</artifactId>
38 <version>4.2.0.RELEASE</version>
39 </dependency>
40 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
41 <dependency>
42 <groupId>org.springframework</groupId>
43 <artifactId>spring-aspects</artifactId>
44 <version>4.2.0.RELEASE</version>
45 </dependency>
46 <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
47 <dependency>
48 <groupId>org.aspectj</groupId>
49 <artifactId>aspectjrt</artifactId>
50 <version>1.9.2</version>
51 </dependency>
52
53 <!-- Spring JDBC依赖的jar包 -->
54 <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
55 <dependency>
56 <groupId>org.springframework</groupId>
57 <artifactId>spring-jdbc</artifactId>
58 <version>4.2.0.RELEASE</version>
59 </dependency>
60 <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
61 <dependency>
62 <groupId>org.springframework</groupId>
63 <artifactId>spring-tx</artifactId>
64 <version>4.2.0.RELEASE</version>
65 </dependency>
66
67 <!-- Spring ORM依赖的jar包 -->
68 <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
69 <dependency>
70 <groupId>org.springframework</groupId>
71 <artifactId>spring-orm</artifactId>
72 <version>4.2.0.RELEASE</version>
73 </dependency>
74 <!-- Spring 测试依赖的jar包 -->
75 <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
76 <dependency>
77 <groupId>org.springframework</groupId>
78 <artifactId>spring-test</artifactId>
79 <version>4.2.0.RELEASE</version>
80 <scope>test</scope>
81 </dependency>
82
83 <!-- apache-logging依赖的jar包 -->
84 <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
85 <dependency>
86 <groupId>commons-logging</groupId>
87 <artifactId>commons-logging</artifactId>
88 <version>1.1.1</version>
89 </dependency>
90
91 <!-- hibernate核心依赖jar包,此依赖下面包含8个依赖,共9个依赖包 -->
92 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
93 <dependency>
94 <groupId>org.hibernate</groupId>
95 <artifactId>hibernate-core</artifactId>
96 <version>5.0.7.Final</version>
97 </dependency>
98
99 <!-- mysql的依赖jar包 -->
100 <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
101 <dependency>
102 <groupId>mysql</groupId>
103 <artifactId>mysql-connector-java</artifactId>
104 <version>5.1.6</version>
105 </dependency>
106
107 <!-- c3p0的依赖jar包 -->
108 <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
109 <dependency>
110 <groupId>com.mchange</groupId>
111 <artifactId>c3p0</artifactId>
112 <version>0.9.5.2</version>
113 </dependency>
114 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
115 <dependency>
116 <groupId>org.hibernate</groupId>
117 <artifactId>hibernate-c3p0</artifactId>
118 <version>5.0.7.Final</version>
119 </dependency>
120
121 <!-- hibernate-jpa的依赖jar包 -->
122 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
123 <dependency>
124 <groupId>org.hibernate</groupId>
125 <artifactId>hibernate-entitymanager</artifactId>
126 <version>5.0.7.Final</version>
127 </dependency>
128
129 <!-- junit的依赖jar包 -->
130 <!-- https://mvnrepository.com/artifact/junit/junit -->
131 <dependency>
132 <groupId>junit</groupId>
133 <artifactId>junit</artifactId>
134 <version>4.12</version>
135 <scope>test</scope>
136 </dependency>
137
138
139 </dependencies>
140
141 </project>
在配置文件applicationContext.xml中定义框架整合,将hibernate的配置整合到spring的applicationContext.xml的配置文件中。
1 jdbc.url=jdbc:mysql://localhost:3306/biehl?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
2 jdbc.driver.class=com.mysql.jdbc.Driver
3 jdbc.username=root
4 jdbc.password=123456
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xmlns:tx="http://www.springframework.org/schema/tx"
6 xsi:schemaLocation="http://www.springframework.org/schema/beans
7 http://www.springframework.org/schema/beans/spring-beans.xsd
8 http://www.springframework.org/schema/context
9 http://www.springframework.org/schema/context/spring-context.xsd
10 http://www.springframework.org/schema/tx
11 http://www.springframework.org/schema/tx/spring-tx.xsd">
12
13 <!-- 1、配置读取properties文件的工具类 -->
14 <context:property-placeholder location="classpath:jdbc.properties"/>
15
16 <!-- 2、配置c3p0数据库连接池,ComboPooledDataSource创建数据库链接池,实例化该类。 -->
17 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
18 <property name="jdbcUrl" value="${jdbc.url}"/>
19 <property name="driverClass" value="${jdbc.driver.class}"/>
20 <property name="user" value="${jdbc.username}"/>
21 <property name="password" value="${jdbc.password}"/>
22 </bean>
23
24 <!-- 3、配置Hibernate的SeesionFactory,LocalSessionFactoryBean有3.x、4.x、5.x版本,根据自己的hibernate进行选择 -->
25 <!-- LocalSessionFactoryBean在spring启动的时候帮助我们初始化hibernate的sessionFactory对象。 -->
26 <!-- 注意:hibernate的上下文对象交由spring来进行管理,不再需要我们手动进行创建了的。 -->
27 <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
28 <!-- 将c3p0的数据库链接池注入到sessionFactory对象实例中。 -->
29 <property name="dataSource" ref="dataSource"/>
30 <!-- hibernateProperties属性:配置与hibernate相关的内容,如显示sql语句,开启正向工程 -->
31 <property name="hibernateProperties">
32 <props>
33 <!-- 显示当前执行的sql语句,后台打印执行的sql语句。 -->
34 <prop key="hibernate.show_sql">true</prop>
35 <!-- 开启正向工程,可以帮助生成数据表。 -->
36 <prop key="hibernate.hbm2ddl.auto">update</prop>
37 </props>
38 </property>
39 <!-- 扫描实体所在的包 -->
40 <property name="packagesToScan">
41 <list>
42 <!-- 实体类所在的包。 -->
43 <value>com.bie.po</value>
44 </list>
45 </property>
46 </bean>
47
48 <!-- 4、配置Hibernate的事务管理器 -->
49 <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
50 <!-- 将spring创建的sessionFactory注入到事务管理器中 -->
51 <property name="sessionFactory" ref="sessionFactory"/>
52 </bean>
53
54 <!-- 5、配置开启注解事务处理,如果需要通过注解开启事务的话。开启注解就可以完成使用注解管理事务。 -->
55 <tx:annotation-driven transaction-manager="transactionManager"/>
56
57 <!-- 6、配置spring IOC的注解扫描 -->
58 <context:component-scan base-package="com.bie"/>
59
60 <!-- 7、配置HiberanteTemplate对象 -->
61 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
62 <!-- 将spring创建的sessionFactory注入HiberanteTemplate中 -->
63 <property name="sessionFactory" ref="sessionFactory"/>
64 </bean>
65
66 </beans>
创建实体类,如下所示:
1 package com.bie.po;
2
3 import javax.persistence.*;
4
5 @Entity // 表示当前类是实体类
6 @Table(name = "tb_users") // 告诉hibernate该实体类和数据表进行映射,如果开启了正向工程管理,name则是数据表的名称了。
7 public class Users {
8
9 @Id // 表示主键
10 @GeneratedValue(strategy = GenerationType.IDENTITY) // GenerationType.IDENTITY表示自增长的策略
11 @Column(name = "userId") // 告诉hibernate当前对象的属性和这个表里面的字段是对应的,需要做他俩的映射处理
12 // 同时,如果是正向工程,创建一个数据表的时候,这个数据表的一个字段的名称就是userId
13 private Integer id;
14
15 @Column(name = "userName")
16 private String name;
17
18 @Column(name = "userAge")
19 private Integer age;
20
21 public Integer getId() {
22 return id;
23 }
24
25 public void setId(Integer id) {
26 this.id = id;
27 }
28
29 public String getName() {
30 return name;
31 }
32
33 public void setName(String name) {
34 this.name = name;
35 }
36
37 public Integer getAge() {
38 return age;
39 }
40
41 public void setAge(Integer age) {
42 this.age = age;
43 }
44
45 @Override
46 public String toString() {
47 return "Users{" +
48 "id=" + id +
49 ", name='" + name + '\'' +
50 ", age=" + age +
51 '}';
52 }
53
54 public Users(String name) {
55 this.name = name;
56 }
57
58 public Users(String name, Integer age) {
59 this.name = name;
60 this.age = age;
61 }
62
63 public Users() {
64 }
65 }
创建dao层,数据交互层的接口和实现类。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4
5 import java.util.List;
6
7 /**
8 *
9 */
10 public interface UserDao {
11
12 /**
13 * 插入操作
14 *
15 * @param users
16 */
17 public void insertUsers(Users users);
18
19 /**
20 * 修改操作
21 *
22 * @param users
23 */
24 public void updateUsers(Users users);
25
26 /**
27 * 删除操作
28 *
29 * @param users
30 */
31 public void deleteUsers(Users users);
32
33 /**
34 * 根据主键查询操作
35 *
36 * @param userid
37 * @return
38 */
39 public Users selectUsersById(Integer userid);
40
41 /**
42 * 根据名称查询操作
43 *
44 * @param username
45 * @return
46 */
47 public List<Users> selectUserByName(String username);
48
49 }
首先使用HQL来进行查询数据,如下所示:
HQL是Hibernate Query Language的缩写,HQL的语法,就是将原来的 sql 语句中的表与字段名称换成对象与属性的名称就可以了。
1 package com.bie.dao.impl;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.hibernate.Query;
6 import org.hibernate.Session;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.orm.hibernate5.HibernateTemplate;
9 import org.springframework.stereotype.Repository;
10
11 import java.util.List;
12
13 @Repository // 注入到IOC容器中
14 public class UserDaoImpl implements UserDao {
15
16 // Spring提供的操作hibernate的对象HibernateTemplate
17 // 这个HibernateTemplate里面封装了一些对hibernate的方法模板。
18 @Autowired
19 // 第一种实现是继承HibernateDaoSupport,如果使用继承方式的话,需要将sessionFactory注入到HibernateDaoSupport的sessionFactory属性。
20 // 第二种是在配置文件中进行配置,建议此种做法。
21 private HibernateTemplate hibernateTemplate;
22
23
24 @Override
25 public void insertUsers(Users users) {
26 this.hibernateTemplate.save(users);
27 }
28
29 @Override
30 public void updateUsers(Users users) {
31 this.hibernateTemplate.update(users);
32 }
33
34 @Override
35 public void deleteUsers(Users users) {
36 this.hibernateTemplate.delete(users);
37 }
38
39 @Override
40 public Users selectUsersById(Integer userid) {
41 return this.hibernateTemplate.get(Users.class, userid);
42 }
43
44 @Override
45 // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
46 public List<Users> selectUserByName(String username) {
47 // 获取session的两种方法。
48 // 方法一、getCurrentSession:当前session必须要有事务边界,且只能处理唯一的一个事务。
49 // 当事务提交或者回滚后session自动失效。
50
51 // 方法二、openSession:每次都会打开一个新的session.加入每次使用多次。则获得的是不同session对象。
52 // 使用完毕后我们需要手动的调用colse方法关闭session。
53 Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
54 //sql:select * from t_users where username ='';
55 Query query = session.createQuery("from Users where name = :abc");
56 Query queryTemp = query.setString("abc", username);
57 return queryTemp.list();
58 }
59 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.test.annotation.Rollback;
9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 import org.springframework.transaction.annotation.Transactional;
12
13 import java.util.List;
14
15 /**
16 *
17 */
18 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
19 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
20 public class UsersDaoImplTest {
21
22 @Autowired
23 private UserDao userDao;
24
25 /**
26 * 添加用户信息
27 */
28 @Test
29 @Transactional // 在测试类对于事务提交方式默认的是回滚。
30 @Rollback(value = false) // 取消自动回滚
31 public void testInsertUsers() {
32 Users users = new Users("张飒飒", 25);
33 this.userDao.insertUsers(users);
34 }
35
36 /**
37 * 更新用户信息
38 */
39 @Test
40 @Transactional
41 @Rollback(false)
42 public void testUpdateUsers() {
43 Users users = new Users("张飒飒", 22);
44 users.setId(1);
45 this.userDao.updateUsers(users);
46 }
47
48 /**
49 * 根据编号查询用户信息
50 */
51 @Test
52 public void testSelectUsersById() {
53 Users users = this.userDao.selectUsersById(1);
54 System.out.println(users);
55 }
56
57 /**
58 * 删除用户信息
59 */
60 @Test
61 @Transactional
62 @Rollback(false)
63 public void testDeleteUsers() {
64 Users users = new Users();
65 users.setId(1);
66 this.userDao.deleteUsers(users);
67 }
68
69 @Test
70 @Transactional
71 public void testSelectUserByName() {
72 List<Users> usersList = this.userDao.selectUserByName("张飒飒");
73 for (Users users : usersList) {
74 System.out.println(users.toString());
75 }
76 }
77 }
使用SQL、QBC来进行数据的查询。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4
5 import java.util.List;
6
7 /**
8 *
9 */
10 public interface UserDao {
11
12 /**
13 * 插入操作
14 *
15 * @param users
16 */
17 public void insertUsers(Users users);
18
19 /**
20 * 修改操作
21 *
22 * @param users
23 */
24 public void updateUsers(Users users);
25
26 /**
27 * 删除操作
28 *
29 * @param users
30 */
31 public void deleteUsers(Users users);
32
33 /**
34 * 根据主键查询操作
35 *
36 * @param userid
37 * @return
38 */
39 public Users selectUsersById(Integer userid);
40
41 /**
42 * 根据名称查询操作
43 *
44 * @param username
45 * @return
46 */
47 public List<Users> selectUserByName(String username);
48
49 /**
50 * 根据sql语句进行名称的查询。
51 *
52 * @param username
53 * @return
54 */
55 List<Users> selectUserByNameUseSQL(String username);
56
57 /**
58 * QBC:Query By Criteria
59 * hibernate可以根据QBC放弃掉sql语句、hql的写法。
60 * 所有对数据库的操作都换成了对对象和方法的操作了。
61 *
62 * @param username
63 * @return
64 */
65 List<Users> selectUserByNameUseCriteria(String username);
66 }
1 package com.bie.dao.impl;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.hibernate.Criteria;
6 import org.hibernate.Query;
7 import org.hibernate.Session;
8 import org.hibernate.criterion.Restrictions;
9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.orm.hibernate5.HibernateTemplate;
11 import org.springframework.stereotype.Repository;
12
13 import java.util.List;
14
15 @Repository // 注入到IOC容器中
16 public class UserDaoImpl implements UserDao {
17
18 // Spring提供的操作hibernate的对象HibernateTemplate
19 // 这个HibernateTemplate里面封装了一些对hibernate的方法模板。
20 @Autowired
21 // 第一种实现是继承HibernateDaoSupport,如果使用继承方式的话,需要将sessionFactory注入到HibernateDaoSupport的sessionFactory属性。
22 // 第二种是在配置文件中进行配置,建议此种做法。
23 private HibernateTemplate hibernateTemplate;
24
25
26 @Override
27 public void insertUsers(Users users) {
28 this.hibernateTemplate.save(users);
29 }
30
31 @Override
32 public void updateUsers(Users users) {
33 this.hibernateTemplate.update(users);
34 }
35
36 @Override
37 public void deleteUsers(Users users) {
38 this.hibernateTemplate.delete(users);
39 }
40
41 @Override
42 public Users selectUsersById(Integer userid) {
43 return this.hibernateTemplate.get(Users.class, userid);
44 }
45
46 @Override
47 // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
48 public List<Users> selectUserByName(String username) {
49 // 获取session的两种方法。
50 // 方法一、getCurrentSession:当前session必须要有事务边界,且只能处理唯一的一个事务。
51 // 当事务提交或者回滚后session自动失效。
52
53 // 方法二、openSession:每次都会打开一个新的session.加入每次使用多次。则获得的是不同session对象。
54 // 使用完毕后我们需要手动的调用colse方法关闭session。
55 Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
56 //sql:select * from t_users where username ='';
57 Query query = session.createQuery("from Users where name = :abc");
58 Query queryTemp = query.setString("abc", username);
59 return queryTemp.list();
60 }
61
62 @Override
63 // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
64 public List<Users> selectUserByNameUseSQL(String username) {
65 Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
66 // 使用原生的sql语句来进行查询操作。
67 Query query = session.createSQLQuery("select * from tb_users where userName = ?")
68 // sql执行的返回结果和那个实体类对象进行映射。
69 // HQL已经将数据表名称换成了实体类的名称。
70 .addEntity(Users.class)
71 .setString(0, username);
72 return query.list();
73 }
74
75 @Override
76 // @Transactional(readOnly = true) // getCurrentSession需要运行在一个事务边界中,所以需要开启事务。
77 public List<Users> selectUserByNameUseCriteria(String username) {
78 Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
79 //sql:select * from t_users where username = '张三';
80 // 创建一个QBC:Query By Criteria
81 Criteria c = session.createCriteria(Users.class);
82 // 根据实体类的name字段属性进行查询。将需要查询的内容传递到参数二的位置上。
83 c.add(Restrictions.eq("name", username));
84 return c.list();
85 }
86
87 }
使用测试类进行测试,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.test.annotation.Rollback;
9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 import org.springframework.transaction.annotation.Transactional;
12
13 import java.util.List;
14
15 /**
16 *
17 */
18 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
19 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
20 public class UsersDaoImplTest {
21
22 @Autowired
23 private UserDao userDao;
24
25 /**
26 * 添加用户信息
27 */
28 @Test
29 @Transactional // 在测试类对于事务提交方式默认的是回滚。
30 @Rollback(value = false) // 取消自动回滚
31 public void testInsertUsers() {
32 Users users = new Users("张飒飒", 25);
33 this.userDao.insertUsers(users);
34 }
35
36 /**
37 * 更新用户信息
38 */
39 @Test
40 @Transactional
41 @Rollback(false)
42 public void testUpdateUsers() {
43 Users users = new Users("张飒飒", 22);
44 users.setId(1);
45 this.userDao.updateUsers(users);
46 }
47
48 /**
49 * 根据编号查询用户信息
50 */
51 @Test
52 public void testSelectUsersById() {
53 Users users = this.userDao.selectUsersById(1);
54 System.out.println(users);
55 }
56
57 /**
58 * 删除用户信息
59 */
60 @Test
61 @Transactional
62 @Rollback(false)
63 public void testDeleteUsers() {
64 Users users = new Users();
65 users.setId(1);
66 this.userDao.deleteUsers(users);
67 }
68
69 @Test
70 @Transactional
71 public void testSelectUserByName() {
72 List<Users> usersList = this.userDao.selectUserByName("张飒飒");
73 for (Users users : usersList) {
74 System.out.println(users.toString());
75 }
76 }
77
78 /**
79 * sql语句的查询测试。
80 */
81 @Test
82 @Transactional
83 public void testSelectUserByNameUseSQL() {
84 List<Users> list = this.userDao.selectUserByNameUseSQL("张飒飒");
85 for (Users users : list) {
86 System.out.println(users);
87 }
88 }
89
90 /**
91 * Criteria 测试
92 */
93 @Test
94 @Transactional
95 public void testSelectUserByNameUseCriteria() {
96 List<Users> list = this.userDao.selectUserByNameUseCriteria("张飒飒");
97 for (Users users : list) {
98 System.out.println(users);
99 }
100 }
101
102 }
2、JPA、Hibernate、Hibernate JPA的概念理解:
1)、JPA:由 Sun 公司提供了一个对于持久层操作的标准(该标准包含接口+文档,没有具体的实现) 。 2)、Hibernate:是 Gavin King 此人开发的一套对于持久层操作的自动的 ORM 框架。 3)、Hibernate JPA:是在 Hibernate3.2 版本中提供了对于 JPA 的标准的实现。提供了一套按照 JPA 标准来实现持久层开发的API。
1 <!-- hibernate-jpa的依赖jar包 -->
2 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
3 <dependency>
4 <groupId>org.hibernate</groupId>
5 <artifactId>hibernate-entitymanager</artifactId>
6 <version>5.0.7.Final</version>
7 </dependency>
修改spring的配置文件applicationContext.xml。
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xmlns:tx="http://www.springframework.org/schema/tx"
6 xsi:schemaLocation="http://www.springframework.org/schema/beans
7 http://www.springframework.org/schema/beans/spring-beans.xsd
8 http://www.springframework.org/schema/context
9 http://www.springframework.org/schema/context/spring-context.xsd
10 http://www.springframework.org/schema/tx
11 http://www.springframework.org/schema/tx/spring-tx.xsd">
12
13 <!-- 1、配置读取properties文件的工具类 -->
14 <context:property-placeholder location="classpath:jdbc.properties"/>
15
16 <!-- 2、配置c3p0数据库连接池,ComboPooledDataSource创建数据库链接池,实例化该类。 -->
17 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
18 <property name="jdbcUrl" value="${jdbc.url}"/>
19 <property name="driverClass" value="${jdbc.driver.class}"/>
20 <property name="user" value="${jdbc.username}"/>
21 <property name="password" value="${jdbc.password}"/>
22 </bean>
23
24 <!-- 3、Spring 整合Hibernate JPA配置,EntityManagerFactory对象就是hibernate JPA帮助我们创建Hibernate JPA上下文的工厂 -->
25 <!-- LocalContainerEntityManagerFactoryBean帮助我们创建Hibernate JPA上下文的对象EntityManagerFactory -->
26 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
27 <!-- 将c3p0的数据库链接池注入到sessionFactory对象实例中。 -->
28 <property name="dataSource" ref="dataSource"/>
29 <!-- jpaVendorAdapter是一个接口,HibernateJpaVendorAdapter是实现类。 -->
30 <property name="jpaVendorAdapter">
31 <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
32 <!-- hibernate 相关的属性的注入 --> <!-- 配置数据库类型 -->
33 <property name="database" value="MYSQL"/>
34 <!-- 正向工程 自动创建表 -->
35 <property name="generateDdl" value="true"/>
36 <!-- 显示执行的 SQL -->
37 <property name="showSql" value="true"/>
38 </bean>
39 </property> <!-- 扫描实体的包 -->
40 <property name="packagesToScan">
41 <list>
42 <value>com.bie.po</value>
43 </list>
44 </property>
45 </bean>
46
47 <!-- 4、配置 Hibernate 的事务管理器 -->
48 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
49 <property name="entityManagerFactory" ref="entityManagerFactory"/>
50 </bean>
51
52
53
54 <!-- 5、配置开启注解事务处理,如果需要通过注解开启事务的话。开启注解就可以完成使用注解管理事务。 -->
55 <tx:annotation-driven transaction-manager="transactionManager"/>
56
57 <!-- 6、配置spring IOC的注解扫描 -->
58 <context:component-scan base-package="com.bie"/>
59
60
61 </beans>
创建dao层,数据交互层的接口和实现类。这里直接使用上面的实体类和dao层的接口,只是重新了dao层接口的实现类。
1 package com.bie.dao.impl;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.springframework.stereotype.Repository;
6
7 import javax.persistence.EntityManager;
8 import javax.persistence.PersistenceContext;
9 import javax.persistence.TypedQuery;
10 import javax.persistence.criteria.CriteriaBuilder;
11 import javax.persistence.criteria.CriteriaQuery;
12 import javax.persistence.criteria.Predicate;
13 import javax.persistence.criteria.Root;
14 import java.util.List;
15
16 @Repository // 注入到IOC容器中
17 public class UserDaoImpl implements UserDao {
18
19 // 使用hibernate JPA的对象进行方法的调用
20 @PersistenceContext(name = "entityManagerFactory")
21 private EntityManager entityManager;
22
23
24 @Override
25 public void insertUsers(Users users) {
26 this.entityManager.persist(users);
27 }
28
29 @Override
30 public void updateUsers(Users users) {
31 this.entityManager.merge(users);
32 }
33
34 @Override
35 public void deleteUsers(Users users) {
36 Users u = this.selectUsersById(users.getId());
37 this.entityManager.remove(u);
38 }
39
40 @Override
41 public Users selectUsersById(Integer userid) {
42 return this.entityManager.find(Users.class, userid);
43 }
44
45 /**
46 * Hibernate JPA中的 HQL 语句
47 *
48 * @param username
49 * @return
50 */
51 @Override
52 public List<Users> selectUserByName(String username) {
53 return this.entityManager.createQuery("from Users where name = :abc")
54 .setParameter("abc", username)
55 .getResultList();
56 }
57
58 /**
59 * HibernateJPA 中的 SQL 语句
60 *
61 * @param username
62 * @return
63 */
64 @Override
65 public List<Users> selectUserByNameUseSQL(String username) {
66 //在 Hibernate JPA 中 如果通过?方式来帮顶参数,那么他的查数是从 1 开始的。而 hibernate 中是从 0 开始的。
67 return this.entityManager
68 .createNativeQuery("select * from tb_users where userName = ?", Users.class)
69 .setParameter(1, username)
70 .getResultList();
71 }
72
73 /**
74 * HibernateJPA 中 QBC 查询
75 *
76 * @param username
77 * @return
78 */
79 @Override
80 public List<Users> selectUserByNameUseCriteria(String username) {
81 // CriteriaBuilder 对象:创建一个 CriteriaQuery,创建查询条件。
82 CriteriaBuilder builber = this.entityManager.getCriteriaBuilder();
83 // CriteriaQuery 对象:执行查询的 Criteria 对象
84 // select * from tb_users
85 CriteriaQuery<Users> query = builber.createQuery(Users.class);
86 // 获取要查询的实体类的对象
87 Root<Users> root = query.from(Users.class);
88 // 封装查询条件
89 Predicate cate = builber.equal(root.get("name"), username);
90 // select * from t_users where username = '张三';
91 query.where(cate);
92 // 执行查询
93 TypedQuery<Users> typeQuery = this.entityManager.createQuery(query);
94 return typeQuery.getResultList();
95 }
96
97 }
测试代码,可以直接使用上面的测试代码即可。
3、Spring Data JPA:Spring Data JPA 是 spring data 项目下的一个模块,提供了一套基于 JPA 标准操作数据库的简化方案,底层默认的是依赖 Hibernate JPA 来实现的。
3.1)、Spring Data JPA 的技术特点:我们只需要定义接口并集成 Spring Data JPA 中所提供的接 口就可以了,不需要编写接口实现类。Spring Data JPA是基于Hibernate JPA的,Hibernate JPA是依赖于Hibernate的。
1 <!-- spring-data-jpa的依赖jar包 -->
2 <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
3 <dependency>
4 <groupId>org.springframework.data</groupId>
5 <artifactId>spring-data-jpa</artifactId>
6 <version>1.9.0.RELEASE</version>
7 </dependency>
8 <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
9 <dependency>
10 <groupId>org.slf4j</groupId>
11 <artifactId>slf4j-log4j12</artifactId>
12 <version>1.7.2</version>
13 <scope>test</scope>
14 </dependency>
修改spring的配置文件applicationContext.xml。
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xmlns:tx="http://www.springframework.org/schema/tx"
6 xmlns:jpa="http://www.springframework.org/schema/data/jpa"
7 xsi:schemaLocation="http://www.springframework.org/schema/beans
8 http://www.springframework.org/schema/beans/spring-beans.xsd
9 http://www.springframework.org/schema/context
10 http://www.springframework.org/schema/context/spring-context.xsd
11 http://www.springframework.org/schema/data/jpa
12 http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
13 http://www.springframework.org/schema/tx
14 http://www.springframework.org/schema/tx/spring-tx.xsd">
15
16 <!-- 1、配置读取properties文件的工具类 -->
17 <context:property-placeholder location="classpath:jdbc.properties"/>
18
19 <!-- 2、配置c3p0数据库连接池,ComboPooledDataSource创建数据库链接池,实例化该类。 -->
20 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
21 <property name="jdbcUrl" value="${jdbc.url}"/>
22 <property name="driverClass" value="${jdbc.driver.class}"/>
23 <property name="user" value="${jdbc.username}"/>
24 <property name="password" value="${jdbc.password}"/>
25 </bean>
26
27 <!-- 3、Spring 整合Hibernate JPA配置,EntityManagerFactory对象就是hibernate JPA帮助我们创建Hibernate JPA上下文的工厂 -->
28 <!-- LocalContainerEntityManagerFactoryBean帮助我们创建Hibernate JPA上下文的对象EntityManagerFactory -->
29 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
30 <!-- 将c3p0的数据库链接池注入到sessionFactory对象实例中。 -->
31 <property name="dataSource" ref="dataSource"/>
32 <!-- jpaVendorAdapter是一个接口,HibernateJpaVendorAdapter是实现类。 -->
33 <property name="jpaVendorAdapter">
34 <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
35 <!-- hibernate 相关的属性的注入 --> <!-- 配置数据库类型 -->
36 <property name="database" value="MYSQL"/>
37 <!-- 正向工程 自动创建表 -->
38 <property name="generateDdl" value="true"/>
39 <!-- 显示执行的 SQL -->
40 <property name="showSql" value="true"/>
41 </bean>
42 </property>
43 <!-- 扫描实体的包 -->
44 <property name="packagesToScan">
45 <list>
46 <value>com.bie.po</value>
47 </list>
48 </property>
49 </bean>
50
51 <!-- 4、配置 Hibernate 的事务管理器 -->
52 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
53 <property name="entityManagerFactory" ref="entityManagerFactory"/>
54 </bean>
55
56 <!-- 5、配置开启注解事务处理,如果需要通过注解开启事务的话。开启注解就可以完成使用注解管理事务。 -->
57 <tx:annotation-driven transaction-manager="transactionManager"/>
58
59 <!-- 6、配置spring IOC的注解扫描 -->
60 <context:component-scan base-package="com.bie"/>
61
62
63 <!-- Spring Data JPA 的配置 -->
64 <!-- base-package:扫描 dao 接口所在的包 -->
65 <jpa:repositories base-package="com.bie.dao"/>
66
67 </beans>
创建dao层的接口,继承JpaRepository<Users, Integer>,JpaRepository<Users, Integer>泛型参数一是实体类的名称,参数二是实体类的主键类型。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.jpa.repository.JpaRepository;
5
6 /**
7 * 使用Spring Data JPA
8 * <p>
9 * JpaRepository<Users, Integer>泛型参数一是实体类的名称,参数二是实体类的主键类型。
10 */
11 public interface UserDao extends JpaRepository<Users, Integer> {
12
13
14 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.test.annotation.Rollback;
9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 import org.springframework.transaction.annotation.Transactional;
12
13 /**
14 *
15 */
16 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
17 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
18 public class UsersDaoImplTest {
19
20 @Autowired
21 private UserDao userDao;
22
23 /**
24 * 添加用户信息
25 */
26 @Test
27 @Transactional // 在测试类对于事务提交方式默认的是回滚。
28 @Rollback(value = false) // 取消自动回滚
29 public void testInsertUsers() {
30 Users users = new Users("张飒飒", 25);
31 this.userDao.save(users);
32 }
33
34
35 }
3.2)、Repository 接口是 Spring Data JPA 中为我们提供的所有接口中的顶层接口,Repository 提供了两种查询方式的支持。
1)、第一种,基于方法名称命名规则查询。方法命名规则:findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)。
关键字 | 方法命名 | sql where 子句 |
---|---|---|
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equal | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEqual | findByIdLessThanEqual | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEqual | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,Not Null | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like '?%' |
EndingWith | findByNameEndingWith | where name like '%?' |
Containing | findByNameContaining | where name like '%?%' |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection<?> c) | where id in (?) |
NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
True、False | findByAaaTue、findByAaaFalse | where aaa = true、where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.repository.Repository;
5
6 import java.util.List;
7
8 public interface UserDao extends Repository<Users, Integer> {
9
10 /**
11 * @param string
12 * @return
13 */
14 List<Users> findByNameIs(String string);
15
16 /**
17 * @param string
18 * @return
19 */
20 List<Users> findByNameLike(String string);
21
22 /**
23 * @param name
24 * @param age
25 * @return
26 */
27 List<Users> findByNameAndAgeGreaterThanEqual(String name, Integer age);
28 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.test.context.ContextConfiguration;
9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10
11 import java.util.List;
12
13 /**
14 *
15 */
16 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
17 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
18 public class UsersDaoImplTest {
19
20 @Autowired
21 private UserDao userDao;
22
23 /**
24 * 需求:使用用户名作为查询条件
25 */
26 @Test
27 public void test1() {
28 // 判断相等的条件,有三种表示方式。
29 // 第一种什么都不写,默认的就是做相等判断。第二种是IS。第三种是Equal。
30 List<Users> list = this.userDao.findByNameIs("张飒飒");
31 for (Users users : list) {
32 System.out.println(users);
33 }
34 }
35
36 /**
37 * 需求:根据用户姓名做 Like 处理
38 * <p>
39 * Like:条件关键字
40 */
41 @Test
42 public void test2() {
43 List<Users> list = this.userDao.findByNameLike("张%");
44 for (Users users : list) {
45 System.out.println(users);
46 }
47 }
48
49 /**
50 * 需求:查询名称为王五,并且他的年龄大于等于 22 岁
51 */
52 @Test
53 public void test3() {
54 List<Users> list = this.userDao.findByNameAndAgeGreaterThanEqual("张飒飒", 22);
55 for (Users users : list) {
56 System.out.println(users);
57 }
58 }
59
60
61 }
2)、第二种,基于@Query 注解查询。
通过 JPQL 语句查询,JPQL是通过 Hibernate 的 HQL 演变过来的,它和 HQL 语法及其相似。测试代码,使用上面的测试代码即可。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.jpa.repository.Query;
5 import org.springframework.data.repository.Repository;
6
7 import java.util.List;
8
9 public interface UserDao extends Repository<Users, Integer> {
10
11 //使用@Query 注解查询
12 @Query(value = "from Users where name = ?")
13 List<Users> queryUserByNameUseJPQL(String name);
14
15 @Query("from Users where name like ?")
16 List<Users> queryUserByLikeNameUseJPQL(String name);
17
18 @Query("from Users where name = ? and age >= ?")
19 List<Users> queryUserByNameAndAge(String name, Integer age);
20
21
22 }
通过 SQL 语句查询。nativeQuery属性,默认的是false,表示不开启sql查询,是否对value中的语句做转义。如果是hql就不需要进行转义,如果是sql就需要进行转义的。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.jpa.repository.Query;
5 import org.springframework.data.repository.Repository;
6
7 import java.util.List;
8
9 public interface UserDao extends Repository<Users, Integer> {
10
11 // 使用@Query注解查询SQL
12 // nativeQuery:默认的是false,表示不开启sql查询,是否对value中的语句做转义。
13 @Query(value = "select * from tb_users where userName = ?", nativeQuery = true)
14 List<Users> queryUserByNameUseSQL(String name);
15
16 @Query(value = "select * from tb_users where userName like ?", nativeQuery = true)
17 List<Users> queryUserByLikeNameUseSQL(String name);
18
19 @Query(value = "select * from tb_users where userName = ? and userAge >= ?", nativeQuery = true)
20 List<Users> queryUserByNameAndAgeUseSQL(String name, Integer age);
21 }
通过@Query 注解完成数据更新,@Modifying 当前语句是一个更新语句。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.jpa.repository.Modifying;
5 import org.springframework.data.jpa.repository.Query;
6 import org.springframework.data.repository.Repository;
7
8 import java.util.List;
9
10 public interface UserDao extends Repository<Users, Integer> {
11
12 // 通过@Query注解完成数据更新
13 @Query("update Users set userAge = ? where userId = ?")
14 @Modifying //@Modifying 当前语句是一个更新语句
15 void updateUserAgeById(Integer age, Integer id);
16 }
3.3、CrudRepository 接口。该接口里面实现方法就自带事务了,不需要自己配置事务了。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.repository.CrudRepository;
5
6 /**
7 * CrudRepository接口
8 */
9 public interface UserDao extends CrudRepository<Users, Integer> {
10
11
12 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.test.annotation.Rollback;
9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 import org.springframework.transaction.annotation.Transactional;
12
13 import java.util.ArrayList;
14 import java.util.List;
15
16 /**
17 *
18 */
19 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
20 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
21 public class UsersDaoImplTest {
22
23 @Autowired
24 private UserDao userDao;
25
26 /**
27 * 添加单条数据
28 */
29 @Test
30 public void test1() {
31 Users user = new Users("李四四", 21);
32 this.userDao.save(user);
33 }
34
35 /**
36 * 批量添加数据
37 */
38 @Test
39 public void test2() {
40 Users user1 = new Users("李四四", 21);
41 Users user2 = new Users("王五五", 22);
42 List<Users> list = new ArrayList<>();
43 list.add(user1);
44 list.add(user2);
45 this.userDao.save(list);
46
47 }
48
49 /**
50 * 根据 ID 查询单条数据
51 */
52 @Test
53 public void test3() {
54 Users users = this.userDao.findOne(6);
55 System.out.println(users);
56 }
57
58 /**
59 * 查询全部数据
60 */
61 @Test
62 public void test4() {
63 List<Users> list = (List<Users>) this.userDao.findAll();
64 for (Users users : list) {
65 System.out.println(users);
66 }
67 }
68
69 /**
70 * 删除数据
71 */
72 @Test
73 public void test5() {
74 this.userDao.delete(5);
75 }
76
77 /**
78 * 更新数据 方式一
79 */
80 @Test
81 public void test6() {
82 Users user = this.userDao.findOne(6);
83 user.setName("亚瑟瑟");
84 this.userDao.save(user);
85 }
86
87 /**
88 * 更新数据 方式二
89 */
90 @Test
91 @Transactional
92 @Rollback(false)
93 public void test7() {
94 // 对象没有关闭,持久化状态的,对对象进行修改都是可以更新到数据库的。
95 Users user = this.userDao.findOne(6);
96 user.setName("王小小");
97 }
98
99 }
3.4、PagingAndSortingRepository 接口,完成分页处理和排序处理,注意这里面的分页是查询全部的数据进行分页处理,是不带查询条件进行查询的。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.repository.PagingAndSortingRepository;
5
6 /**
7 * PagingAndSortingRepository 接口
8 */
9 public interface UserDao extends PagingAndSortingRepository<Users, Integer> {
10
11
12 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.data.domain.Page;
9 import org.springframework.data.domain.PageRequest;
10 import org.springframework.data.domain.Pageable;
11 import org.springframework.data.domain.Sort;
12 import org.springframework.test.context.ContextConfiguration;
13 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
14
15 import java.util.List;
16
17 /**
18 *
19 */
20 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
21 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
22 public class UsersDaoImplTest {
23
24 @Autowired
25 private UserDao userDao;
26
27 /**
28 * 分页,对数据表所有数据进行查询进行分页,是不带条件的分页查询。
29 */
30 @Test
31 public void test1() {
32 // page,当前页的索引。注意索引都是从0开始的。
33 int page = 0;
34 // size,每页显示3条数据。
35 int size = 3;
36 Pageable pageable = new PageRequest(page, size);
37 Page<Users> p = this.userDao.findAll(pageable);
38 System.out.println("数据的总条数:" + p.getTotalElements());
39 System.out.println("总页数:" + p.getTotalPages());
40 List<Users> list = p.getContent();
41 for (Users users : list) {
42 System.out.println(users);
43 }
44 }
45
46
47 /**
48 * 对单列做排序处理
49 */
50 @Test
51 public void test2() {
52 // Sort代表了该对象封装了排序规则以及指定的排序字段(对象的属性来表示)。
53 // direction代表了排序规则。
54 // properties代表了指定做排序的实体类属性。
55 Sort sort = new Sort(Sort.Direction.DESC, "id");
56 List<Users> list = (List<Users>) this.userDao.findAll(sort);
57 for (Users users : list) {
58 System.out.println(users);
59 }
60 }
61
62 /**
63 * 多列的排序处理
64 */
65 @Test
66 public void test3() {
67 // Sort代表了该对象封装了排序规则以及指定的排序字段(对象的属性来表示)。
68 // direction代表了排序规则。
69 // properties代表了指定做排序的实体类属性。
70 Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "age");
71 Sort.Order order2 = new Sort.Order(Sort.Direction.ASC, "name");
72 Sort sort = new Sort(order1, order2);
73 List<Users> list = (List<Users>) this.userDao.findAll(sort);
74 for (Users users : list) {
75 System.out.println(users);
76 }
77 }
78
79 }
3.5、JpaRepository接口是我们开发时使用的最多的接口,其特点是可以帮助我们将其他接口的方法的返回值做适配处理,可以使得我们在开发时更方便的使用这些方法。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.jpa.repository.JpaRepository;
5
6 /**
7 * JpaRepository 接口
8 */
9 public interface UserDao extends JpaRepository<Users, Integer> {
10
11
12 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.test.context.ContextConfiguration;
9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10
11 import java.util.List;
12
13 /**
14 *
15 */
16 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
17 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
18 public class UsersDaoImplTest {
19
20 @Autowired
21 private UserDao userDao;
22
23 /**
24 * 查询全部数据
25 */
26 @Test
27 public void test1() {
28 List<Users> list = this.userDao.findAll();
29 for (Users users : list) {
30 System.out.println(users);
31 }
32 }
33
34 }
3.6、JpaSpecificationExecutor 接口,完成多条件查询,并且支持分页与排序。此接口不可以单独使用,需要配合着Jpa中的其他接口配合使用的,因为该接口没有继承于其他接口。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.jpa.repository.JpaRepository;
5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
6
7 /**
8 * JpaSpecificationExecutor 接口
9 * 注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着 jpa 中的其他接口一起使用
10 */
11 public interface UserDao extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
12
13
14 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.data.domain.Page;
9 import org.springframework.data.domain.PageRequest;
10 import org.springframework.data.domain.Pageable;
11 import org.springframework.data.domain.Sort;
12 import org.springframework.data.jpa.domain.Specification;
13 import org.springframework.test.context.ContextConfiguration;
14 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
15
16 import javax.persistence.criteria.CriteriaBuilder;
17 import javax.persistence.criteria.CriteriaQuery;
18 import javax.persistence.criteria.Predicate;
19 import javax.persistence.criteria.Root;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 /**
24 *
25 */
26 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
27 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
28 public class UsersDaoImplTest {
29
30 @Autowired
31 private UserDao userDao;
32
33 /**
34 * 需求:根据用户姓名查询数据
35 */
36 @Test
37 public void test1() {
38
39 Specification<Users> specification = new Specification<Users>() {
40 /**
41 *
42 * @param root 根对象。封装了查询条件的对象
43 * @param query 定义了一个基本的查询.一般不使用
44 * @param cb 创建一个查询条件
45 * @return Predicate:定义了查询条件
46 */
47 @Override
48 public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
49 Predicate pre = cb.equal(root.get("name"), "王五五");
50 return pre;
51 }
52
53 };
54 List<Users> list = this.userDao.findAll(specification);
55 for (Users users : list) {
56 System.out.println(users);
57 }
58 }
59
60 /**
61 * 多条件查询 方式一
62 * 需求:使用用户姓名以及年龄查询数据
63 */
64 @Test
65 public void test2() {
66 Specification<Users> specification = new Specification<Users>() {
67
68 @Override
69 public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
70 List<Predicate> list = new ArrayList<>();
71 list.add(cb.equal(root.get("name"), "王五五"));
72 list.add(cb.equal(root.get("age"), 22));
73 //此时条件之间是没有任何关系的。
74 Predicate[] arr = new Predicate[list.size()];
75 return cb.and(list.toArray(arr));
76 }
77
78 };
79 List<Users> list = this.userDao.findAll(specification);
80 for (Users users : list) {
81 System.out.println(users);
82 }
83 }
84
85 /**
86 * 多条件查询 方式二
87 * 需求:使用用户姓名或者年龄查询数据
88 */
89 @Test
90 public void test3() {
91 Specification<Users> specification = new Specification<Users>() {
92
93 @Override
94 public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
95 return cb.or(cb.equal(root.get("name"), "王五五"), cb.equal(root.get("age"), 22));
96 }
97
98 };
99 List<Users> list = this.userDao.findAll(specification);
100 for (Users users : list) {
101 System.out.println(users);
102 }
103 }
104
105 /**
106 * 需求:查询王姓用户,并且做分页处理
107 */
108 @Test
109 public void test4() {
110 // 条件
111 Specification<Users> specification = new Specification<Users>() {
112
113 @Override
114 public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
115 return cb.like(root.get("name").as(String.class), "王%");
116 }
117
118 };
119
120 // 分页
121 Pageable pageable = new PageRequest(0, 2);
122 Page<Users> page = this.userDao.findAll(specification, pageable);
123 System.out.println("总条数:" + page.getTotalElements());
124 System.out.println("总页数:" + page.getTotalPages());
125 List<Users> list = page.getContent();
126 for (Users users : list) {
127 System.out.println(users);
128 }
129 }
130
131 /**
132 * 需求:查询数据库中王姓的用户,并且根据用户id做倒序排序
133 */
134 @Test
135 public void test5() {
136 //条件
137 Specification<Users> specification = new Specification<Users>() {
138
139 @Override
140 public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
141 return cb.like(root.get("name").as(String.class), "王%");
142 }
143
144 };
145 // 排序
146 Sort sort = new Sort(Sort.Direction.DESC, "id");
147 List<Users> list = this.userDao.findAll(specification, sort);
148 for (Users users : list) {
149 System.out.println(users);
150 }
151 }
152
153 /**
154 * 需求:查询数据库中王姓的用户,做分页处理,并且根据用户id做倒序排序
155 */
156 @Test
157 public void test6() {
158 // 排序等定义
159 Sort sort = new Sort(Sort.Direction.DESC, "id");
160 // 分页的定义
161 Pageable pageable = new PageRequest(0, 2, sort);
162
163 // 查询条件
164 Specification<Users> specification = new Specification<Users>() {
165
166 @Override
167 public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
168 return cb.like(root.get("name").as(String.class), "王%");
169 }
170
171 };
172 Page<Users> page = this.userDao.findAll(specification, pageable);
173 System.out.println("总条数:" + page.getTotalElements());
174 System.out.println("总页数:" + page.getTotalPages());
175 List<Users> list = page.getContent();
176 for (Users users : list) {
177 System.out.println(users);
178 }
179 }
180
181
182 }
3.7、用户自定义 Repository 接口,如果上面Jpa接口满足不了需求,可以进行自定义 Repository 接口。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4
5 /**
6 * 用户自定义接口
7 */
8 public interface UsersRepository {
9
10 /**
11 * 根据用户主键信息查询用户信息
12 *
13 * @param userid
14 * @return
15 */
16 public Users findUserById(Integer userid);
17
18 }
定义自己的业务接口,然后继承自己的自定义Jpa接口。
1 package com.bie.dao;
2
3 import com.bie.po.Users;
4 import org.springframework.data.jpa.repository.JpaRepository;
5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
6
7 /**
8 * 用户自定义接口
9 */
10 public interface UserDao extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users>, UsersRepository {
11
12
13 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Users;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.test.context.ContextConfiguration;
9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10
11 /**
12 *
13 */
14 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
15 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
16 public class UsersDaoImplTest {
17
18 @Autowired
19 private UserDao userDao;
20
21
22 @Test
23 public void test7() {
24 Users users = this.userDao.findUserById(6);
25 System.out.println(users);
26 }
27
28 }
3.7、Spring data Jpa关联映射操作。
需求:是用户与角色的一对一的关联关系,一个用户只能有一个角色,一个角色只能分配给一个用户
1 package com.bie.po;
2
3 import javax.persistence.*;
4
5 @Entity // 表示当前类是实体类
6 @Table(name = "tb_users") // 告诉hibernate该实体类和数据表进行映射,如果开启了正向工程管理,name则是数据表的名称了。
7 public class Users {
8
9 @Id // 表示主键
10 @GeneratedValue(strategy = GenerationType.IDENTITY) // GenerationType.IDENTITY表示自增长的策略
11 @Column(name = "userId") // 告诉hibernate当前对象的属性和这个表里面的字段是对应的,需要做他俩的映射处理
12 // 同时,如果是正向工程,创建一个数据表的时候,这个数据表的一个字段的名称就是userId
13 private Integer id;
14
15 @Column(name = "userName")
16 private String name;
17
18 @Column(name = "userAge")
19 private Integer age;
20
21 @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
22 // @JoinColumn:就是维护一个外键,该外键就是用户和角色关联的一个键
23 @JoinColumn(name = "roles_id")
24 private Roles roles;// 该roles对象就表示当前对象所对应的角色。
25
26 public Integer getId() {
27 return id;
28 }
29
30 public void setId(Integer id) {
31 this.id = id;
32 }
33
34 public String getName() {
35 return name;
36 }
37
38 public void setName(String name) {
39 this.name = name;
40 }
41
42 public Integer getAge() {
43 return age;
44 }
45
46 public void setAge(Integer age) {
47 this.age = age;
48 }
49
50 @Override
51 public String toString() {
52 return "Users{" +
53 "id=" + id +
54 ", name='" + name + '\'' +
55 ", age=" + age +
56 '}';
57 }
58
59 public Users(String name) {
60 this.name = name;
61 }
62
63 public Users(String name, Integer age) {
64 this.name = name;
65 this.age = age;
66 }
67
68 public Users() {
69 }
70
71 public Roles getRoles() {
72 return roles;
73 }
74
75 public void setRoles(Roles roles) {
76 this.roles = roles;
77 }
78 }
角色的实体类,如下所示:
1 package com.bie.po;
2
3 import javax.persistence.*;
4
5 @Entity
6 @Table(name = "tb_roles")
7 public class Roles {
8
9
10 @Id
11 @GeneratedValue(strategy = GenerationType.IDENTITY)
12 @Column(name = "roleId")
13 private Integer roleId;// 角色编号
14
15 @Column(name = "roleName")
16 private String roleName;// 角色名称
17
18 // 注意,这里面的mappedBy的值就是用户实体类里面的角色的对象实例名称
19 // 将那个对象关联进行,去关联跟这个用户里面相同的角色对应的用户。
20 @OneToOne(mappedBy = "roles")
21 private Users users;// 表示当前角色对应的用户
22
23 public Integer getRoleId() {
24 return roleId;
25 }
26
27 public void setRoleId(Integer roleId) {
28 this.roleId = roleId;
29 }
30
31 public String getRoleName() {
32 return roleName;
33 }
34
35 public void setRoleName(String roleName) {
36 this.roleName = roleName;
37 }
38
39 public Roles(String roleName) {
40 this.roleName = roleName;
41 }
42
43 @Override
44 public String toString() {
45 return "Roles{" +
46 "roleId=" + roleId +
47 ", roleName='" + roleName + '\'' +
48 '}';
49 }
50
51 public Roles() {
52 }
53
54 public Users getUsers() {
55 return users;
56 }
57
58 public void setUsers(Users users) {
59 this.users = users;
60 }
61 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Roles;
5 import com.bie.po.Users;
6 import org.junit.Test;
7 import org.junit.runner.RunWith;
8 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11
12 /**
13 *
14 */
15 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
16 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
17 public class UsersDaoImplTest {
18
19 @Autowired
20 private UserDao userDao;
21
22 // 添加用户的同时,添加角色
23
24 /**
25 * 一对一关联关系的添加
26 */
27 @Test
28 public void testSave() {
29 // 创建一个用户
30 Users users = new Users("admin", 22);
31
32 // 创建一个角色
33 Roles roles = new Roles("管理员");
34
35 // 关联,建立双向关系
36 users.setRoles(roles);
37 roles.setUsers(users);
38
39
40 // 新增,插入用户的时候进行级联操作。
41 this.userDao.save(users);
42 }
43
44 /**
45 * 一对一关联关系的查询
46 */
47 @Test
48 public void testSelect() {
49 Users users = this.userDao.findOne(1);
50 System.out.println(users.toString());
51 System.out.println(users.getRoles().toString());
52 }
53 }
需求:一对多的关联关系,需求是用户与角色的一对多的关联关系,一个用户只能有一个角色,一个角色只能分配给多个用户,用户对用户是一对多的关联关系。
1 package com.bie.po;
2
3 import javax.persistence.*;
4
5 @Entity // 表示该类是实体类
6 @Table(name = "tb_users") // 表示该实体类和数据表进行映射,name表示实体类和数据表进行映射
7 // 如果使用的是正向工程的话,name属性的值表示的是数据表的表名称。
8 public class Users {
9
10 @Id // 表示该字段是主键
11 @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键的生成策略
12 @Column(name = "id") // 表示实体类的字段和数据表的字段进行映射的关系,如果是正向工程的话,name的值就是数据表的字段名称
13 private Integer id;// 用户编号
14
15 @Column(name = "name")
16 private String name;// 用户姓名
17
18 @Column(name = "age")
19 private Integer age;// 用户年龄
20
21 @Column(name = "address")
22 private String address;// 用户地址
23
24 // 用户是多方,角色是一方,所以一个用户只能分配一个角色
25 @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) // 用户对角色,多对一关系
26 @JoinColumn(name = "roles_id") // 该注解的作用就是为了维护一个外键,外键在Users这一侧
27 // 可以通过正向工程在数据表新增一个字段。
28 private Roles roles;
29
30
31 // alt + insert来生成构造器、setter\getter等等方法
32 public Integer getId() {
33 return id;
34 }
35
36 public void setId(Integer id) {
37 this.id = id;
38 }
39
40 public String getName() {
41 return name;
42 }
43
44 public void setName(String name) {
45 this.name = name;
46 }
47
48 public Integer getAge() {
49 return age;
50 }
51
52 public void setAge(Integer age) {
53 this.age = age;
54 }
55
56 public String getAddress() {
57 return address;
58 }
59
60 public void setAddress(String address) {
61 this.address = address;
62 }
63
64 @Override
65 public String toString() {
66 return "Users{" +
67 "id=" + id +
68 ", name='" + name + '\'' +
69 ", age=" + age +
70 ", address='" + address + '\'' +
71 '}';
72 }
73
74 public Users(String name, Integer age, String address) {
75 this.name = name;
76 this.age = age;
77 this.address = address;
78 }
79
80
81 public Users() {
82 }
83
84 public Roles getRoles() {
85 return roles;
86 }
87
88 public void setRoles(Roles roles) {
89 this.roles = roles;
90 }
91
92 }
角色的实体类,如下所示:
1 package com.bie.po;
2
3 import javax.persistence.*;
4 import java.util.HashSet;
5 import java.util.Set;
6
7 @Entity
8 @Table(name = "tb_roles")
9 public class Roles {
10
11 @Id
12 @GeneratedValue(strategy = GenerationType.IDENTITY)
13 @Column(name = "roleId")
14 private Integer roleId;// 角色编号
15
16 @Column(name = "roleName")
17 private String roleName;// 角色名称
18
19 // 角色是多的方式,一个角色可以分配给多个用户
20 @OneToMany(mappedBy = "roles")
21 //表示一对多的关系,mappedBy表示向Set集合放Users,放的是当前roles相同的,外键和主键相同的
22 // 表示外键和主键相同的,做在角色表里面角色和那个用户之间的描述。
23 private Set<Users> usersSet = new HashSet<Users>();
24
25 public Integer getRoleId() {
26 return roleId;
27 }
28
29 public void setRoleId(Integer roleId) {
30 this.roleId = roleId;
31 }
32
33 public String getRoleName() {
34 return roleName;
35 }
36
37 public void setRoleName(String roleName) {
38 this.roleName = roleName;
39 }
40
41 @Override
42 public String toString() {
43 return "Roles{" +
44 "roleId=" + roleId +
45 ", roleName='" + roleName + '\'' +
46 '}';
47 }
48
49 public Roles(String roleName) {
50 this.roleName = roleName;
51 }
52
53 public Roles() {
54 }
55
56 public Set<Users> getUsersSet() {
57 return usersSet;
58 }
59
60 public void setUsersSet(Set<Users> usersSet) {
61 this.usersSet = usersSet;
62 }
63
64 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.UserDao;
4 import com.bie.po.Roles;
5 import com.bie.po.Users;
6 import org.junit.Test;
7 import org.junit.runner.RunWith;
8 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11
12 /**
13 *
14 */
15 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
16 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
17 public class UsersDaoImplTest {
18
19 @Autowired
20 private UserDao userDao;
21
22 // 添加用户的同时,添加角色
23
24 /**
25 * 一对多关联关系的添加
26 */
27 @Test
28 public void testSave() {
29 // 创建一个用户
30 Users users = new Users("admin", 22, "北京市西城区");
31
32 // 创建一个角色
33 Roles roles = new Roles("管理员");
34
35 // 关联,建立双向关系
36 users.setRoles(roles);
37 roles.getUsersSet().add(users);
38
39
40 // 新增,插入用户的时候进行级联操作。
41 this.userDao.save(users);
42 }
43
44 /**
45 * 一对多关联关系的查询
46 */
47 @Test
48 public void testSelect() {
49 Users users = this.userDao.findOne(5);
50 System.out.println(users.toString());
51 System.out.println(users.getRoles().toString());
52 }
53 }
如果出现下面的错误:
可以使用@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)。
Spring Data JPA中有四种Cascade 类型:
1)、PERSIST:持久保存拥有的实体,也会持久保存该实体的属于相关数据。
2)、MERGE:将分离的实体重新合并到活动的持久性上下文时,也会合并该实体的所有数据。
3)、REMOVE:删除一个实体时候,也删除该实体的所有数据。
4)、ALL:以上都适用。
Spring Data JPA中有两种fetch 类型:
1)、FetchType.EAGE:如果是EAGER,那么表示取出这条数据时,它关联的数据也同时取出放入内存中。
2)、FetchType.LAZY:如果是LAZY,那么取出这条数据时,它关联的数据并不取出来,在同一个session中,什么时候要用,就什么时候取(再次访问数据库)。
1 org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles
2
3 at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
4 at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223)
5 at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
6 at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
7 at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
8 at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
9 at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
10 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
11 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
12 at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
13 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
14 at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:119)
15 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
16 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
17 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
18 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
19 at com.sun.proxy.$Proxy33.save(Unknown Source)
20 at com.bie.test.UsersDaoImplTest.testSave(UsersDaoImplTest.java:40)
21 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
22 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
23 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
24 at java.lang.reflect.Method.invoke(Method.java:498)
25 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
26 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
27 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
28 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
29 at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
30 at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:85)
31 at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:86)
32 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
33 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:241)
34 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
35 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
36 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
37 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
38 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
39 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
40 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
41 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
42 at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
43 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
44 at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
45 at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
46 at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
47 at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
48 at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
49 Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles
50 at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1689)
51 at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
52 at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
53 at org.hibernate.jpa.internal.EntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(EntityManagerImpl.java:235)
54 at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2967)
55 at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
56 at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
57 at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
58 at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
59 at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
60 at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
61 at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61)
62 at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
63 ... 43 more
64 Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.bie.po.Users.roles -> com.bie.po.Roles
65 at org.hibernate.engine.spi.CascadingActions$8.noCascade(CascadingActions.java:379)
66 at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:126)
67 at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:150)
68 at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:141)
69 at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:74)
70 at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
71 at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
72 at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
73 at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
74 ... 51 more
75
76
77 Process finished with exit code -1
需求:多对多的关联关系,需求是角色与菜单的多对多的关联关系,一个角色可以有多个菜单,一个菜单可以有多个角色。
1 package com.bie.dao;
2
3 import com.bie.po.Roles;
4 import org.springframework.data.jpa.repository.JpaRepository;
5
6 public interface RoleDao extends JpaRepository<Roles, Integer> {
7
8
9 }
角色信息的实体类,代码如下所示。
1 package com.bie.po;
2
3 import javax.persistence.*;
4 import java.util.HashSet;
5 import java.util.Set;
6
7 @Entity
8 @Table(name = "tb_roles")
9 public class Roles {
10
11
12 @Id
13 @GeneratedValue(strategy = GenerationType.IDENTITY)
14 @Column(name = "roleId")
15 private Integer roleId;// 角色编号
16
17 @Column(name = "roleName")
18 private String roleName;// 角色名称
19
20 @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) // 放弃延迟加载,改为立即加载。
21 // @JoinTable:配置中间表信息
22 // joinColumns:建立当前表在中间表中的外键字段
23 @JoinTable(name = "t_roles_menus", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "menu_id"))
24 private Set<Menus> menus = new HashSet<>();
25
26 public Integer getRoleId() {
27 return roleId;
28 }
29
30 public void setRoleId(Integer roleId) {
31 this.roleId = roleId;
32 }
33
34 public String getRoleName() {
35 return roleName;
36 }
37
38 public void setRoleName(String roleName) {
39 this.roleName = roleName;
40 }
41
42 public Roles(String roleName) {
43 this.roleName = roleName;
44 }
45
46 @Override
47 public String toString() {
48 return "Roles{" +
49 "roleId=" + roleId +
50 ", roleName='" + roleName + '\'' +
51 '}';
52 }
53
54 public Roles() {
55 }
56
57 public Set<Menus> getMenus() {
58 return menus;
59 }
60
61 public void setMenus(Set<Menus> menus) {
62 this.menus = menus;
63 }
64 }
菜单信息的实体类,如下所示:
1 package com.bie.po;
2
3 import javax.persistence.*;
4 import java.util.HashSet;
5 import java.util.Set;
6
7 @Entity
8 @Table(name = "tb_menus")
9 public class Menus {
10
11 @Id
12 @GeneratedValue(strategy = GenerationType.IDENTITY)
13 @Column(name = "menusid")
14 private Integer menusId;// 菜单编号
15
16 @Column(name = "menusname")
17 private String menusName;// 菜单名称
18
19 @Column(name = "menusUrl")
20 private String menusurl;// 菜单路径
21
22 @Column(name = "fatherid")
23 private Integer fatherId;// 父菜单
24
25 // 一个菜单可以对应多个角色,一个角色可以对应多个菜单。
26 @ManyToMany(mappedBy = "menus")
27 private Set<Roles> roles = new HashSet<>();
28
29 public Menus() {
30 }
31
32 public Menus(String menusName, Integer fatherId, String menusurl) {
33 this.menusName = menusName;
34 this.menusurl = menusurl;
35 this.fatherId = fatherId;
36 }
37
38 @Override
39 public String toString() {
40 return "Menus{" +
41 "menusId=" + menusId +
42 ", menusName='" + menusName + '\'' +
43 ", menusurl='" + menusurl + '\'' +
44 ", fatherId=" + fatherId +
45 ", roles=" + roles +
46 '}';
47 }
48
49 public Integer getMenusId() {
50 return menusId;
51 }
52
53 public void setMenusId(Integer menusId) {
54 this.menusId = menusId;
55 }
56
57 public String getMenusName() {
58 return menusName;
59 }
60
61 public void setMenusName(String menusName) {
62 this.menusName = menusName;
63 }
64
65 public String getMenusurl() {
66 return menusurl;
67 }
68
69 public void setMenusurl(String menusurl) {
70 this.menusurl = menusurl;
71 }
72
73 public Integer getFatherId() {
74 return fatherId;
75 }
76
77 public void setFatherId(Integer fatherId) {
78 this.fatherId = fatherId;
79 }
80
81 public Set<Roles> getRoles() {
82 return roles;
83 }
84
85 public void setRoles(Set<Roles> roles) {
86 this.roles = roles;
87 }
88 }
测试代码,如下所示:
1 package com.bie.test;
2
3 import com.bie.dao.RoleDao;
4 import com.bie.po.Menus;
5 import com.bie.po.Roles;
6 import org.junit.Test;
7 import org.junit.runner.RunWith;
8 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11
12 import java.util.Set;
13
14 /**
15 *
16 */
17 @RunWith(SpringJUnit4ClassRunner.class) // spring与junit的整合。
18 @ContextConfiguration("classpath:applicationContext.xml") // 加载spring的配置文件applicationContext.xml
19 public class UsersDaoImplTest {
20
21 @Autowired
22 private RoleDao roleDao;
23
24
25 /**
26 * 添加角色同时添加菜单
27 */
28 @Test
29 public void test1() {
30 // 创建角色对象
31 Roles roles = new Roles("超级管理员");
32 // 创建菜单对象 XXX 管理平台 --->用户管理
33 Menus menus = new Menus("哈哈哈管理平台", -1, "null");
34
35 // 用户管理菜单
36 Menus menus1 = new Menus("用户管理平台", -1, "null");
37
38 // 建立关系
39 roles.getMenus().add(menus);
40 roles.getMenus().add(menus1);
41 menus.getRoles().add(roles);
42 menus1.getRoles().add(roles);
43
44 // 保存数据
45 this.roleDao.save(roles);
46 }
47
48 /**
49 * 查询 Roles
50 */
51 @Test
52 public void test2() {
53 Roles roles = this.roleDao.findOne(1);
54 System.out.println("角色信息:" + roles);
55 Set<Menus> menus = roles.getMenus();
56 for (Menus menus2 : menus) {
57 System.out.println("菜单信息:" + menus2);
58 }
59 }
60
61 }
4、Spring Data Redis帮助我们更方便,更容易操作Redis。
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6 <modelVersion>4.0.0</modelVersion>
7
8 <groupId>com.bie</groupId>
9 <artifactId>spring-redis</artifactId>
10 <version>1.0-SNAPSHOT</version>
11
12 <dependencies>
13 <!-- Spring IOC容器依赖的jar包 -->
14 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
15 <dependency>
16 <groupId>org.springframework</groupId>
17 <artifactId>spring-context</artifactId>
18 <version>4.2.0.RELEASE</version>
19 </dependency>
20 <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
21 <dependency>
22 <groupId>org.springframework</groupId>
23 <artifactId>spring-core</artifactId>
24 <version>4.2.0.RELEASE</version>
25 </dependency>
26 <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
27 <dependency>
28 <groupId>org.springframework</groupId>
29 <artifactId>spring-beans</artifactId>
30 <version>4.2.0.RELEASE</version>
31 </dependency>
32
33 <!-- Spring AOP容器依赖的jar包 -->
34 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
35 <dependency>
36 <groupId>org.springframework</groupId>
37 <artifactId>spring-aop</artifactId>
38 <version>4.2.0.RELEASE</version>
39 </dependency>
40 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
41 <dependency>
42 <groupId>org.springframework</groupId>
43 <artifactId>spring-aspects</artifactId>
44 <version>4.2.0.RELEASE</version>
45 </dependency>
46 <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
47 <dependency>
48 <groupId>org.aspectj</groupId>
49 <artifactId>aspectjrt</artifactId>
50 <version>1.9.2</version>
51 </dependency>
52
53 <!-- Spring JDBC依赖的jar包 -->
54 <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
55 <dependency>
56 <groupId>org.springframework</groupId>
57 <artifactId>spring-jdbc</artifactId>
58 <version>4.2.0.RELEASE</version>
59 </dependency>
60 <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
61 <dependency>
62 <groupId>org.springframework</groupId>
63 <artifactId>spring-tx</artifactId>
64 <version>4.2.0.RELEASE</version>
65 </dependency>
66
67 <!-- apache-logging依赖的jar包 -->
68 <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
69 <dependency>
70 <groupId>commons-logging</groupId>
71 <artifactId>commons-logging</artifactId>
72 <version>1.1.1</version>
73 </dependency>
74
75 <!-- Spring 测试依赖的jar包 -->
76 <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
77 <dependency>
78 <groupId>org.springframework</groupId>
79 <artifactId>spring-test</artifactId>
80 <version>4.2.0.RELEASE</version>
81 <scope>test</scope>
82 </dependency>
83
84 <!-- junit的依赖jar包 -->
85 <!-- https://mvnrepository.com/artifact/junit/junit -->
86 <dependency>
87 <groupId>junit</groupId>
88 <artifactId>junit</artifactId>
89 <version>4.12</version>
90 <scope>test</scope>
91 </dependency>
92
93 <!-- redis的依赖包、Spring Data JPA的依赖包。 -->
94 <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
95 <dependency>
96 <groupId>org.springframework.data</groupId>
97 <artifactId>spring-data-redis</artifactId>
98 <version>1.6.0.RELEASE</version>
99 </dependency>
100 <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
101 <dependency>
102 <groupId>redis.clients</groupId>
103 <artifactId>jedis</artifactId>
104 <version>2.7.2</version>
105 </dependency>
106
107
108 </dependencies>
109
110 </project>
Spring整合SpringDataRedis整合配置文件application.xml,配置redis连接信息的redis.properties。
1 # 最大连接数
2 redis.pool.maxtTotal=20
3 # 最大空闲数
4 redis.pool.maxIdle=10
5 # 最小空闲数
6 redis.pool.minIdle=5
7
8 # redis的ip地址
9 redis.hostname=192.168.110.140
10 # redis的端口号
11 redis.port=6379
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context.xsd">
9
10 <!-- 配置读取properties文件的工具类 -->
11 <context:property-placeholder location="classpath:redis.properties"/>
12
13 <!-- Jedis连接池 -->
14 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
15 <property name="maxTotal" value="${redis.pool.maxtTotal}"/>
16 <property name="maxIdle" value="${redis.pool.maxIdle}"/>
17 <property name="minIdle" value="${redis.pool.minIdle}"/>
18 </bean>
19
20 <!-- Jedis连接工厂:创建Jedis对象的工厂 -->
21 <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
22 <!-- IP地址 -->
23 <property name="hostName" value="${redis.hostname}"/>
24 <!-- 端口 -->
25 <property name="port" value="${redis.port}"/>
26 <!-- 连接池 -->
27 <property name="poolConfig" ref="poolConfig"/>
28 </bean>
29
30 <!-- Redis模板对象:是SpringDataRedis提供的用户操作Redis的对象 -->
31 <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
32 <!-- 模板对象注入Jedisd的连接工厂,连接工厂注入redis的ip地址信息,端口号 -->
33 <property name="connectionFactory" ref="jedisConnectionFactory"/>
34 <!-- 默认的序列化器:序列化器就是根据规则将存储的数据中的key与value做字符串的序列化处理 -->
35 <!-- keySerializer、valueSerializer:对应的是Redis中的String类型 -->
36 <!-- hashKeySerializer、hashValueSerializer:对应的是Redis中的Hash类型 -->
37 <property name="keySerializer">
38 <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
39 </property>
40 <property name="valueSerializer">
41 <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
42 </property>
43 </bean>
44
45 </beans>
测试代码,如下所示:
关闭 linux 防火墙,或者在防火墙中开启 6379 端口。
1 import org.junit.Test;
2 import org.junit.runner.RunWith;
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.data.redis.core.RedisTemplate;
5 import org.springframework.test.context.ContextConfiguration;
6 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7
8 /**
9 * @ProjectName: springredis
10 * @Package: PACKAGE_NAME
11 * @ClassName: RedisTest
12 * @Author: biehl
13 * @Description: ${description}
14 * @Date: 2020/5/24 10:16
15 * @Version: 1.0
16 */
17 @RunWith(SpringJUnit4ClassRunner.class)
18 @ContextConfiguration("classpath:applicationContext.xml")
19 public class RedisTest {
20
21 @Autowired
22 private RedisTemplate<String, Object> redisTemplate;
23
24 /**
25 * 添加键值对
26 */
27 @Test
28 public void test1() {
29 this.redisTemplate.opsForValue().set("key", "哈哈哈,学好数理化,走遍天下都不怕");
30 }
31
32 /**
33 * 获取redis中的数据
34 */
35 @Test
36 public void test2() {
37 String str = (String) this.redisTemplate.opsForValue().get("key");
38 System.out.println(str);
39 }
40
41
42 }
Spring Data Redisd 存储实体对象。
1 import com.bie.po.Users;
2 import org.junit.Test;
3 import org.junit.runner.RunWith;
4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.data.redis.core.RedisTemplate;
6 import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
7 import org.springframework.test.context.ContextConfiguration;
8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
9
10 /**
11 * @ProjectName: springredis
12 * @Package: PACKAGE_NAME
13 * @ClassName: RedisTest
14 * @Author: biehl
15 * @Description: ${description}
16 * @Date: 2020/5/24 10:16
17 * @Version: 1.0
18 */
19 @RunWith(SpringJUnit4ClassRunner.class)
20 @ContextConfiguration("classpath:applicationContext.xml")
21 public class RedisTest {
22
23 @Autowired
24 private RedisTemplate<String, Object> redisTemplate;
25
26 /**
27 * 添加Users
28 */
29 @Test
30 public void test3() {
31 // 注意:实体类要实现序列化处理的,不然报异常。
32 Users users = new Users(1, "张三三", 25);
33 //更换序列化器
34 this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
35 this.redisTemplate.opsForValue().set("users", users);
36 }
37
38 /**
39 * 获取Users
40 */
41 @Test
42 public void test4() {
43 //更换序列化器
44 this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
45 Users users = (Users) this.redisTemplate.opsForValue().get("users");
46 System.out.println(users);
47 }
48
49 }
Spring Data Redis 以 JSON 的格式存储实体对象。
1 <!-- jackson的依赖包 -->
2 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
3 <dependency>
4 <groupId>com.fasterxml.jackson.core</groupId>
5 <artifactId>jackson-databind</artifactId>
6 <version>2.8.10</version>
7 </dependency>
8 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
9 <dependency>
10 <groupId>com.fasterxml.jackson.core</groupId>
11 <artifactId>jackson-core</artifactId>
12 <version>2.8.10</version>
13 </dependency>
14 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
15 <dependency>
16 <groupId>com.fasterxml.jackson.core</groupId>
17 <artifactId>jackson-annotations</artifactId>
18 <version>2.8.10</version>
19 </dependency>
测试代码,如所示:
1 import com.bie.po.Users;
2 import org.junit.Test;
3 import org.junit.runner.RunWith;
4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.data.redis.core.RedisTemplate;
6 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
7 import org.springframework.test.context.ContextConfiguration;
8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
9
10 /**
11 * @ProjectName: springredis
12 * @Package: PACKAGE_NAME
13 * @ClassName: RedisTest
14 * @Author: biehl
15 * @Description: ${description}
16 * @Date: 2020/5/24 10:16
17 * @Version: 1.0
18 */
19 @RunWith(SpringJUnit4ClassRunner.class)
20 @ContextConfiguration("classpath:applicationContext.xml")
21 public class RedisTest {
22
23 @Autowired
24 private RedisTemplate<String, Object> redisTemplate;
25
26 /**
27 * 添加Users JSON格式
28 */
29 @Test
30 public void test5() {
31 Users users = new Users(1,"李四四",25);
32
33 this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
34 this.redisTemplate.opsForValue().set("usersjson", users);
35 }
36
37 /**
38 * 获取Uesrs JSON格式
39 */
40 @Test
41 public void test6() {
42 this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
43 Users users = (Users) this.redisTemplate.opsForValue().get("usersjson");
44 System.out.println(users);
45 }
46
47 }