SpringData整合hibernate
CRUD操作:
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置读取properties文件的工具类 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置c3p0数据库连接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="driverClass" value="${jdbc.driver.class}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- 配置Hibernate的SeesionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- hibernateProperties属性:配置与hibernate相关的内容,如显示sql语句,开启正向工程 --> <property name="hibernateProperties"> <props> <!-- 显示当前执行的sql语句 --> <prop key="hibernate.show_sql">true</prop> <!-- 开启正向工程 --> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <!-- 扫描实体所在的包 --> <property name="packagesToScan"> <list> <value>com.fly.pojo</value> </list> </property> </bean> <!-- 配置HibernateTemplate对象 --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 配置Hibernate的事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 配置开启注解事务处理 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 配置springIOC的注解扫描 --> <context:component-scan base-package="com.fly" /> </beans> |
jdbc.properties:
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.driver.class=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=root
实体类:
package com.fly.pojo;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="t_users")
public class Users implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) //自增长
@Column(name="userid")
private Integer userid;
@Column(name="username")
private String username;
@Column(name="userage")
private Integer userage;
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getUserage() {
return userage;
}
public void setUserage(Integer userage) {
this.userage = userage;
}
@Override
public String toString() {
return "Users [userid=" + userid + ", username=" + username + ", userage=" + userage + "]";
}
}
UsersDaoImpl:
package com.fly.dao.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;
import com.fly.dao.UsersDao;
import com.fly.pojo.Users;
@Repository
public class UsersDaoImpl implements UsersDao{
@Autowired
private HibernateTemplate hibernateTemplate;
@Override
public void insertUsers(Users user) {
this.hibernateTemplate.save(user);
}
@Override
public void updateUsers(Users user) {
this.hibernateTemplate.update(user);
}
@Override
public void deleteUsers(Users user) {
this.hibernateTemplate.delete(user);
}
@Override
public Users selectUsersById(Integer userid) {
Users users = this.hibernateTemplate.get(Users.class, userid);
return users;
}
}
测试类:
package com.fly.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import com.fly.dao.UsersDao;
import com.fly.pojo.Users;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserTest {
@Autowired
private UsersDao usersDao;
@Test
@Transactional //测试类中事务默认提交方式是回滚
@Rollback(false) //取消自动回滚
public void testInsertUser() {
Users user = new Users();
user.setUserage(20);
user.setUsername("张三");
this.usersDao.insertUsers(user );
}
@Test
@Transactional //测试类中事务默认提交方式是回滚
@Rollback(false) //取消自动回滚
public void testUpdateUser() {
Users user = new Users();
user.setUserid(1);
user.setUserage(21);
user.setUsername("李四");
this.usersDao.updateUsers(user);
}
@Test
public void testSeleteUser() {
Users users = this.usersDao.selectUsersById(1);
System.out.println(users);
}
@Test
@Transactional //测试类中事务默认提交方式是回滚
@Rollback(false) //取消自动回滚
public void testdeleteUser() {
Users user = new Users();
user.setUserid(1);
this.usersDao.deleteUsers(user);
}
}
HQL查询:
SQL查询:
QBC查询:
/**
* HQL
* 将原来的sql语句中的表与字段名换成对象与属性的名称
*/
@Override
public List<Users> selectUserByName(String username) {
//getCurrentSession:当前session必须要有事务边界,且只能处理唯一的一个事务。当事务提交或者回滚后session自动失效
//openSession:每次都会打开一个新的session.加入每次使用多次。则获得的是不同session对象。使用完毕后我们需要手动的调用colse方法关闭session
Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
//sql:select * from t_users where username =
Query query = session.createQuery("from Users where username = :name").setString("name", username);
return query.list();
}
/**
* SQL
*/
@Override
public List<Users> selectUserByNameUseSQL(String username) {
Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
Query query = session.createSQLQuery("select * from t_users where username=?").addEntity(Users.class).setString(0, username);
return query.list();
}
/**
* QBC
*/
@Override
public List<Users> selectUserByNameUseCriteria(String username) {
Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
//sql:select * from t_users where username =
Criteria criteria = session.createCriteria(Users.class);
criteria.add(Restrictions.eq("username", username));
return criteria.list();
}
测试:
/**
* HQL
*/
@Test
@Transactional
public void testselectUserByName() {
List<Users> list = this.usersDao.selectUserByName("张三");
for (Users users : list) {
System.out.println(users);
}
}
/**
* SQL
*/
@Test
@Transactional
public void testselectUserByNameUseSQL() {
List<Users> list = this.usersDao.selectUserByNameUseSQL("张三");
for (Users users : list) {
System.out.println(users);
}
}
/**
* QBC
*/
@Test
@Transactional
public void testselectUserByNameUseCriteria() {
List<Users> list = this.usersDao.selectUserByNameUseCriteria("张三");
for (Users users : list) {
System.out.println(users);
}
}
SpringData整合hibernate基于JPA规范:
多一个jar hibernate-entitymanager-5.0.7.Final.jar
CRUD操作:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置读取properties文件的工具类 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置c3p0数据库连接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="driverClass" value="${jdbc.driver.class}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- Spring整合JPA 配置EntityManagerFactory--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <!-- hibernate相关的属性的注入 --> <!-- 配置数据库类型 --> <property name="database" value="MYSQL"/> <!-- 正向工程 自动创建表 --> <property name="generateDdl" value="true"/> <!-- 显示执行的SQL --> <property name="showSql" value="true"/> </bean> </property> <!-- 扫描实体的包 --> <property name="packagesToScan"> <list> <value>com.fly.pojo</value> </list> </property> </bean> <!-- 配置Hibernate的事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- 配置开启注解事务处理 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 配置springIOC的注解扫描 --> <context:component-scan base-package="com.fly" /> </beans> |
UsersDaoImpl:
package com.fly.dao.impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import com.fly.dao.UsersDao;
import com.fly.pojo.Users;
@Repository
public class UsersDaoImpl implements UsersDao{
@PersistenceContext(name="entityManagerFactory")
private EntityManager entityManager;
@Override
public void insertUsers(Users user) {
this.entityManager.persist(user);
}
@Override
public void updateUsers(Users user) {
this.entityManager.merge(user);
}
@Override
public void deleteUsers(Users user) {
Users users = this.selectUsersById(user.getUserid());
this.entityManager.remove(users);
}
@Override
public Users selectUsersById(Integer userid) {
Users users = this.entityManager.find(Users.class, userid);
return users;
}
}
HQL
SQL
QBC
/**
* HQL
* 将原来的sql语句中的表与字段名换成对象与属性的名称
*/
@Override
public List<Users> selectUserByName(String username) {
return this.entityManager.createQuery("from Users where username=:name").setParameter("name", username).getResultList();
}
/**
* SQL
*/
@Override
public List<Users> selectUserByNameUseSQL(String username) {
//在 Hibernate JPA 中 如果通过?方式来帮顶参数,那么他的查数是从 1开始的。而 hibernate 中是从 0 开始的。
return this.entityManager.createNativeQuery("select * from t_users where username=?",Users.class).setParameter(1, username).getResultList();
}
/**
* QBC
*/
@Override
public List<Users> selectUserByNameUseCriteria(String username) {
//CriteriaBuilder 对象:创建一个 CriteriaQuery,创建查询条件。
CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
//CriteriaQuery 对象:执行查询的 Criteria 对象
//select * from t_users
CriteriaQuery<Users> query = builder.createQuery(Users.class);
//获取要查询的实体类的对象
Root<Users> root = query.from(Users.class);
//封装查询条件
Predicate predicate = builder.equal(root.get("username"), username);
//select * from t_users where username =
query.where(predicate);
//执行
TypedQuery<Users> typedQuery = this.entityManager.createQuery(query);
return typedQuery.getResultList();
}
Spring Data JPA:
Spring Data JPA:Spring Data JPA 是 spring data 项目下的一个模块。提供了一套基于 JPA标准操作数据库的简化方案。底层默认的是依赖 Hibernate JPA 来实现的。
Spring Data JPA 的技术特点:我们只需要定义接口并集成 Spring Data JPA 中所提供的接口就可以了。不需要编写接口实现类
在hibernate jpa的基础上:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置读取properties文件的工具类 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置c3p0数据库连接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="driverClass" value="${jdbc.driver.class}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- Spring整合JPA 配置EntityManagerFactory--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <!-- hibernate相关的属性的注入 --> <!-- 配置数据库类型 --> <property name="database" value="MYSQL"/> <!-- 正向工程 自动创建表 --> <property name="generateDdl" value="true"/> <!-- 显示执行的SQL --> <property name="showSql" value="true"/> </bean> </property> <!-- 扫描实体的包 --> <property name="packagesToScan"> <list> <value>com.fly.pojo</value> </list> </property> </bean> <!-- 配置Hibernate的事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- 配置开启注解事务处理 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 配置springIOC的注解扫描 --> <context:component-scan base-package="com.fly" /> <!-- Spring Data JPA 的配置 --> <!-- base-package:扫描 dao 接口所在的包 --> <jpa:repositories base-package="com.fly.dao"/> </beans> |
Dao:
public interface UsersDao extends JpaRepository<Users, Integer> {
}
Repository 接口
Repository 接口是 Spring Data JPA 中为我我们提供的所有接口中的顶层接口
Repository 提供了两种查询方式的支持
1)基于方法名称命名规则查询
2)基于@Query 注解查询
方法名称命名规则查询:
规则:findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
关键字 |
方法命名 |
sql where 字句 |
And |
findByNameAndPwd |
where name= ? andpwd =? |
Or |
findByNameOrSex |
where name= ? orsex=? |
Is,Equal,都不写 |
findById,findByIdEqual |
where id= ? |
Between |
findByIdBetween |
where id between ?and ? |
LessThan |
findByIdLessThan |
where id < ? |
LessThanEqual |
findByIdLessThanEquals |
where id <= ? |
GreaterThan |
findByIdGreaterThan |
where id > ? |
GreaterThanEqual |
findByIdGreaterThanEquals |
where id > = ? |
After |
findByIdAfter |
where id > ? |
Before |
findByIdBefore |
where id < ? |
IsNull |
findByNameIsNull |
where name is null |
isNotNull,NotNull |
findByNameNotNull |
where name is not null |
Like |
findByNameLike |
where name like ? |
NotLike |
findByNameNotLike |
where name notlike ? |
StartingWith |
findByNameStartingWith |
where name like '?%' |
EndingWith |
findByNameEndingWith |
where name like '%?' |
Containing |
findByNameContaining |
where name like'%?%' |
OrderBy |
findByIdOrderByXDesc |
where id=? order by x desc |
Not |
findByNameNot |
where name <> ? |
In |
findByIdIn(Collection<?> c) |
where id in (?) |
NotIn |
findByIdNotIn(Collection<?> c) |
where id not in(?) |
True |
findByAaaTue |
where aaa = true |
False |
findByAaaFalse |
where aaa = false |
IgnoreCase |
findByNameIgnoreCase |
where UPPER(name)=UPPER( |
Dao:
package com.fly.dao;
import java.util.List;
import org.springframework.data.repository.Repository;
import com.fly.pojo.Users;
/**
* * Repository 接口测试
*/
public interface UsersDao extends Repository<Users, Integer> {
List<Users> findByUsernameIs(String string);
List<Users> findByUsernameLike(String string);
//查询名称为 ,并且他的年龄大于等于
List<Users> findByUsernameAndUserageGreaterThanEqual(String name,Integer age);
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {
@Autowired
private UsersDao usersDao;
@Test
public void test1() {
List<Users> list = this.usersDao.findByUsernameIs("李四");
for (Users users : list) {
System.out.println(users);
}
}
@Test
public void test2() {
List<Users> list = this.usersDao.findByUsernameLike("李%");
for (Users users : list) {
System.out.println(users);
}
}
@Test
public void test3() {
List<Users> list = this.usersDao.findByUsernameAndUserageGreaterThanEqual("李四",18);
for (Users users : list) {
System.out.println(users);
}
}
}
基于@Query 注解的查询:
- 通过 JPQL 语句查询
JPQL:通过 Hibernate 的 HQL 演变过来的。他和 HQL 语法及其相似。
//使用@Query 注解查询
//通过 JPQL 语句查询
@Query(value="from Users where username=?")
List<Users> quertUserByNameUseJPQL(String name);
@Query(value="from Users where username like ?")
List<Users> quertUserByLikeNameUseJPQL(String name);
@Query(value="from Users where username=? and userage >= ?")
List<Users> quertUserByNameAndAgeUseJPQL(String name,Integer age);
测试:
//使用@Query 注解查询
//通过 JPQL 语句查询
@Test
public void test4() {
List<Users> list = this.usersDao.quertUserByNameUseJPQL("李四");
for (Users users : list) {
System.out.println(users);
}
}
@Test
public void test5() {
List<Users> list = this.usersDao.quertUserByLikeNameUseJPQL("李%");
for (Users users : list) {
System.out.println(users);
}
}
@Test
public void test6() {
List<Users> list = this.usersDao.quertUserByNameAndAgeUseJPQL("李四",18);
for (Users users : list) {
System.out.println(users);
}
}
- 通过 SQL 语句查询:
//通过 SQL 语句查询
//nativeQuery:默认的是 false.表示不开启 sql 查询。
@Query(value="select * from t_users where username=?",nativeQuery=true)
List<Users> quertUserByNameUseSQL(String name);
@Query(value="select * from t_users where username like ?",nativeQuery=true)
List<Users> quertUserByLikeNameUseSQL(String name);
@Query(value="select * from t_users where username=? and userage >= ?",nativeQuery=true)
List<Users> quertUserByNameAndAgeUseSQL(String name,Integer age);
通过@Query 注解完成数据更新:
//通过@Query 注解完成数据更新
@Query("update Users set username = ? where userid = ?")
@Modifying //当前语句是一个更新语句
void updateUserNameById(String name,Integer id);
测试:
//通过@Query 注解完成数据更新
@Test
@Transactional
@Rollback(false)
public void test10() {
this.usersDao.updateUserNameById("赵六", 4);
}
CrudRepository接口:
接口:
public interface UsersDao extends CrudRepository<Users, Integer> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class CrudRepositoryTest {
@Autowired
private UsersDao usersDao;
/**
* 添加单条数据
* 源码已开启事务
*/
@Test
public void test1() {
Users user = new Users();
user.setUserage(21);
user.setUsername("王五");
this.usersDao.save(user);
}
/**
* 批量添加数据
*/
@Test
public void test2() {
Users user = new Users();
user.setUserage(23);
user.setUsername("王五22");
Users user1 = new Users();
user1.setUserage(22);
user1.setUsername("王五33");
List<Users>list = new ArrayList<>();
list.add(user);
list.add(user1);
this.usersDao.save(list);
}
/**
* 根据id查询单条数据
*/
@Test
public void test3() {
Users users = this.usersDao.findOne(4);
System.out.println(users);
}
/**
* 查询全部数据
*/
@Test
public void test4() {
List<Users> list = (List<Users>) this.usersDao.findAll();
for (Users users : list) {
System.out.println(users);
}
}
/**
* 更新方式一
*/
@Test
public void test5() {
Users users = this.usersDao.findOne(4);
users.setUsername("王六");
this.usersDao.save(users);
}
/**
* 更新方式二
*/
@Test
@Transactional
@Rollback(false)
public void test6() {
Users users = this.usersDao.findOne(4);
users.setUsername("王七");
}
/**
* 删除
*/
/**
* 更新方式一
*/
@Test
public void test7() {
this.usersDao.delete(4);
}
}
PagingAndSortingRepository 接口:
分页,排序:
接口:
public interface UsersDao2 extends PagingAndSortingRepository<Users, Integer> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class PagingAndSortingRepositoryTest {
@Autowired
private UsersDao2 usersDao;
/**
* 分页处理
*/
@Test
public void test1() {
int page = 0;//page:当前页的索引。注意索引都是从 0 开始的。
int size = 3;// size:每页显示 3 条数据
Pageable pageable = new PageRequest(page, size);
Page<Users> findAll = this.usersDao.findAll(pageable);
System.out.println("数据的总条数:"+findAll.getTotalElements());
System.out.println("总页数:"+findAll.getTotalPages());
List<Users> list = findAll.getContent();
for (Users users : list) {
System.out.println(users);
}
}
/**
* 对单列做排序处理
*/
@Test
public void test2() {
//Sort:该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
//direction:排序规则
//properties:指定做排序的属性
Sort sort = new Sort(Direction.DESC,"userid");
List<Users> list = (List<Users>) this.usersDao.findAll(sort);
for (Users users : list) {
System.out.println(users);
}
}
/**
* 多列的排序处理
*/
@Test
public void test3() {
//import org.springframework.data.domain.Sort.Order;
//Sort:该对象封装了排序规则以及指
//direction:排序规则
//properties:指定做排序的
Order order1 = new Order(Direction.DESC,"userage");
Order order2 = new Order(Direction.ASC,"userid");
Sort sort = new Sort(order1,order2);
List<Users> list = (List<Users>) this.usersDao.findAll(sort );
for (Users users : list) {
System.out.println(users);
}
}
}
JpaRepository 接口:
JpaRepository 接口其特点是将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法
接口类:
public interface UsersDao3 extends JpaRepository<Users, Integer> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaRepositoryTest {
@Autowired
private UsersDao3 usersDao;
/**
* 查询所有数据
*/
@Test
public void test1() {
List<Users> list = this.usersDao.findAll();
for (Users users : list) {
System.out.println(users);
}
}
}
JpaSpecificationExecutor 接口:
完成多条件查询,并且支持分页与排序
- 单条件查询:
接口:
/**
* JpaSpecificationExecutor 接口讲解
* 注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着 jpa 中的其他接口一起使用
*/
public interface UsersDao4 extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaSpecificationExecutorTest {
@Autowired
private UsersDao4 usersDao;
/**
* 需求:根据用户姓名查询数据
*/
@Test
public void test1() {
List<Users> list = this.usersDao.findAll(new Specification<Users>() {
/**
* Predicate:定义了查询条件
* Root<Users> root:根对象。封装了查询条件的对象
* CriteriaQuery<?> query:定义了一个基本的查询.一般不使用
* CriteriaBuilder cb:创建一个查询条件
*/
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
Predicate predicate = builder.like(root.get("username"), "王%");
return predicate;
}
});
for (Users users : list) {
System.out.println(users);
}
}
}
- 多条件查询:
/**
* 多条件查询 方式一 数组
* 需求:使用用户姓名以及年龄查询数据
*/
@Test
public void test2() {
List<Users> list = this.usersDao.findAll(new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> list = new ArrayList<>();
list.add(builder.equal(root.get("username"), "张三"));
list.add(builder.equal(root.get("userage"), 20));
Predicate[] arr = new Predicate[list.size()];
return builder.and(list.toArray(arr));
}
});
for (Users users : list) {
System.out.println(users);
}
}
/**
* 多条件查询 方式二 多参数
* 需求:使用用户姓名或者年龄查询数据
*/
@Test
public void test3() {
List<Users> list = this.usersDao.findAll(new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.or(builder.equal(root.get("username"), "张三"),builder.equal(root.get("userage"), 20));
}
});
for (Users users : list) {
System.out.println(users);
}
}
分页排序:
/**
* 分页
* 需求:查询王姓用户,并且做分页处理
*/
@Test
public void test4() {
Specification<Users> specification = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.like(root.get("username").as(String.class), "王%");
}
};
Pageable pageable = new PageRequest(0, 3);
Page<Users> findAll = this.usersDao.findAll(specification, pageable);
System.out.println("总条数"+findAll.getTotalElements());
System.out.println("总页数"+findAll.getTotalPages());
for (Users users : findAll) {
System.out.println(users);
}
}
/**
* 排序
* 需求:查询数据库中王姓的用户,并且根据用户 id 做倒序排序
*/
@Test
public void test5() {
Specification<Users> specification = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.like(root.get("username").as(String.class), "王%");
}
};
Sort sort = new Sort(Direction.DESC,"userid");
List<Users> findAll = this.usersDao.findAll(specification, sort);
for (Users users : findAll) {
System.out.println(users);
}
}
/**
* 分页+排序
* 需求:查询数据库中王姓的用户,做分页处理,并且根据用户 id 做倒序排序
*/
@Test
public void test6() {
Specification<Users> specification = new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.like(root.get("username").as(String.class), "王%");
}
};
Sort sort = new Sort(Direction.DESC,"userid");
Pageable pageable = new PageRequest(0, 2, sort);
Page<Users> findAll = this.usersDao.findAll(specification, pageable);
for (Users users : findAll) {
System.out.println(users);
}
}
用户自定义 Repository 接口:
/**
* 自定义 Repository 接口讲
* @author Administrator
*
*/
public interface UsersRepository {
public Users findUserById(Integer userid);
}
//注意UsersDao5Impl ,UsersDao5
public class UsersDao5Impl implements UsersRepository{
@PersistenceContext(name="entityManagerFactory")
private EntityManager entityManager;
@Override
public Users findUserById(Integer userid) {
return this.entityManager.find(Users.class, userid);
}
}
public interface UsersDao5 extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>,UsersRepository{
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsersRepositoryTest {
@Autowired
private UsersDao5 usersDao;
//需求:根据用户 ID 查询数据
@Test
public void test1() {
Users users = this.usersDao.findUserById(5);
System.out.println(users);
}
}
关联映射操作:
一对一的关联关系
需求:用户与角色的一对一的关联关系
用户:一方
角色:一方
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users> {
}
/**
* Users实体类
* @author Administrator
*
*/
@Entity
@Table(name="t_users")
public class Users implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) //自增长
@Column(name="userid")
private Integer userid;
@Column(name="username")
private String username;
@Column(name="userage")
private Integer userage;
@OneToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name="roles_id") //维护的外键
private Roles roles;
/**
* 角色实体类
* @author Administrator
*
*/
@Entity
@Table(name="t_roles")
public class Roles {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="roleid")
private Integer rodeid;
@Column(name="rolename")
private String rolename;
@OneToOne(mappedBy="roles")
private Users users;
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class CrudRepositoryTest {
@Autowired
private UsersDao usersDao;
/**
* 一对一关联关系测试
* * 添加用户同时添加角色
*/
@Test
public void test1() {
Roles roles = new Roles();
roles.setRolename("员工1");
Users user = new Users();
user.setUserage(21);
user.setUsername("黄三1");
user.setRoles(roles);
roles.setUsers(user);
this.usersDao.save(user);
}
/**
* 根据用户 ID 查询用户,同时查询用户角色
*/
@Test
public void test2() {
Users users = this.usersDao.findOne(5);
System.out.println("用户信息"+users);
Roles roles = users.getRoles();
System.out.println(roles);
}
}
一对多的关联关系
需求:从角色到用户的一对多的关联关系
角色:一方
用户:多方
Users.java:
@ManyToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name="roles_id")
private Roles roles;
Roles.java:
@OneToMany(mappedBy="roles")
private Set<Users> users = new HashSet<>();
测试:
/**
*添加用户同时添加角色
*/
@Test
public void test3() {
Roles roles = new Roles();
roles.setRolename("员工2");
Users user = new Users();
user.setUserage(21);
user.setUsername("黄三2");
user.setRoles(roles);
roles.getUsers().add(user);
this.usersDao.save(user);
}
/**
* 根据用户 ID 查询用户信息,同时查询角色
*/
@Test
public void test4() {
Users users = this.usersDao.findOne(17);
System.out.println("用户姓名:"+users.getUsername());
Roles roles = users.getRoles();
System.out.println(roles);
}
多对多的关联关系
需求:一个角色可以拥有多个菜单,一个菜单可以分配多个角色。多对多的关联关系
角色:多方
菜单:多方
public interface RolesDao extends JpaRepository<Roles, Integer>,JpaSpecificationExecutor<Roles> {
}
/**
* 菜单实体类
* @author Administrator
*
*/
@Entity
@Table(name="t_menus")
public class Menus {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="menusid")
private Integer menusid;
@Column(name="menusname")
private String menusname;
@Column(name="menusurl")
private String menusurl;
@Column(name="fatherid")
private Integer fatherid;
@ManyToMany(mappedBy="menus")
private Set<Roles>roles = new HashSet<>();
Roles.java:
@ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)//EAGER 立即加载
//@JoinTable:配置中间表信息//joinColumns:建立当前表在中间表中的外键字段
@JoinTable(name="t_roles_menus",joinColumns=@JoinColumn(name="role_id"),inverseJoinColumns=@JoinColumn(name="menu_id"))
private Set<Menus> menus = new HashSet<>();
测试:
@Autowired
private RolesDao rolesDao;
/**
* 添加角色同时添加菜单
*/
@Test
public void test5() {
Roles roles = new Roles();
roles.setRolename("前台");
Menus menus = new Menus();
menus.setMenusname("xx平台");
menus.setFatherid(-1);
menus.setMenusurl(null);
Menus menus1 = new Menus();
menus1.setMenusname("用户管理");
menus1.setFatherid(1);
menus1.setMenusurl(null);
roles.getMenus().add(menus);
roles.getMenus().add(menus1);
menus.getRoles().add(roles);
menus1.getRoles().add(roles);
this.rolesDao.save(roles);
}
/**
* 查询 Roles
*/
@Test
public void test6() {
Roles roles = this.rolesDao.findOne(4);
System.out.println("角色信息"+roles);
Set<Menus>menus = roles.getMenus();
for (Menus menus2 : menus) {
System.out.println("菜单信息:"+menus2);
}
}
Spring Data Redis :
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置读取properties文件的工具类 --> <context:property-placeholder location="classpath:redis.properties"/> <!-- Jedis连接池 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.pool.maxTotal}"/> <property name="maxIdle" value="${redis.pool.maxIdle}"/> <property name="minIdle" value="${redis.pool.minIdle}"/> </bean> <!-- Jedis的连接工厂 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.conn.hostName}"/> <property name="port" value="${redis.conn.port}"/> <property name="poolConfig" ref="poolConfig"/> </bean> <!-- Redis模板对象 --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory"/> <!-- 序列化器:能够把我们储存的key与value做序列化处理的对象 --> <!-- 配置默认的序列化器 --> <!-- keySerializer、valueSerializer 配置Redis中的String类型key与value的序列化器 --> <!-- HashKeySerializer、HashValueSerializer 配置Redis中的Hash类型key与value的序列化器 --> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> </bean> </beans> |
redis.properties:
redis.pool.maxTotal=20
redis.pool.maxIdle=10
redis.pool.minIdle=5
redis.conn.hostName=127.0.0.1
redis.conn.port=6379
Users.java:
public class Users implements Serializable{
private Integer id;
private String name;
private Integer age;
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RedisTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 添加键值对
*/
@Test
public void test1() {
this.redisTemplate.opsForValue().set("key", "test");
}
/**
* 获取redis中的数据
*/
@Test
public void test2() {
String string = (String) this.redisTemplate.opsForValue().get("key");
System.out.println(string);
}
/**
* 添加 Users
*/
@Test
public void test3() {
Users users = new Users();
users.setAge(20);
users.setId(1);
users.setName("张三");
//更换序列器
this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
this.redisTemplate.opsForValue().set("users", users);
}
/**
* 获取users
*/
@Test
public void test4() {
this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
Users users = (Users) this.redisTemplate.opsForValue().get("users");
System.out.println(users);
}
/**
* 添加 Users JSON 格式
*/
@Test
public void test5() {
Users users = new Users();
users.setAge(21);
users.setId(2);
users.setName("李四");
this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
this.redisTemplate.opsForValue().set("userjson", users);
}
/**
* 获取 Uesrs JSON 格式
*/
@Test
public void test6() {
this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
Users users = (Users) this.redisTemplate.opsForValue().get("userjson");
System.out.println(users);
}
}
构建Maven工程 Spring Data Redis
Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。
spring-data-redis针对jedis提供了如下功能:
1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
<!-- 集中定义依赖版本号 --> <properties> <spring.version>4.2.4.RELEASE</spring.version> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> </dependency> <!-- 缓存 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.2.RELEASE</version> </dependency> </dependencies> |
redis-config.properties:
# Redis settings
# server IP
redis.host=127.0.0.1
# server port
redis.port=6379
# server pass
redis.pass=
# use dbIndex
redis.database=0
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
applicationContext-redis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<context:property-placeholder
location="classpath*:properties/*.properties" />
<!-- redis 相关配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- 连接时的最大等待毫秒数 -->
<property name="maxWaitMillis" value="${redis.maxWait}" />
<!-- 在提取一个jedis实例时,是否提前进行验证操作;如果为true,则得到的jedis实例均是可用的; -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<bean id="JedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}" p:port="${redis.port}"
p:password="${redis.pass}" p:pool-config-ref="poolConfig" />
<bean id="redisTemplate"
class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory"
ref="JedisConnectionFactory" />
</bean>
</beans>
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext-redis.xml")
public class TestRedis {
@Autowired
private RedisTemplate redisTemplate;
/**
* 值类型操作
*/
@Test
public void setValue() {
redisTemplate.boundValueOps("name").set("test");
}
@Test
public void getValue() {
String string = (String) redisTemplate.boundValueOps("name").get();
System.out.println(string);
}
@Test
public void deleteValue() {
redisTemplate.delete("name");
}
/**
* Set类型操作
* set是无序的
*/
@Test
public void setSetValue() {
redisTemplate.boundSetOps("nameset").add("曹操");
redisTemplate.boundSetOps("nameset").add("曹植");
redisTemplate.boundSetOps("nameset").add("曹呸");
}
@Test
public void getSetValue() {
Set set = redisTemplate.boundSetOps("nameset").members();
System.out.println(set);
}
@Test
public void deleteSetValue() {
redisTemplate.boundSetOps("nameset").remove("曹操");
}
@Test
public void deleteAllSetValue() {
redisTemplate.delete("nameset");
}
/**
* List类型操作
*/
@Test
public void setListValue() {
redisTemplate.boundListOps("namelist1").rightPush("刘备");
redisTemplate.boundListOps("namelist1").rightPush("关羽");
redisTemplate.boundListOps("namelist1").rightPush("张飞");
}
@Test
public void setListValue2() {
redisTemplate.boundListOps("namelist2").leftPush("刘备2");
redisTemplate.boundListOps("namelist2").leftPush("关羽2");
redisTemplate.boundListOps("namelist2").leftPush("张飞2");
}
@Test
public void getListValue() {
List list = redisTemplate.boundListOps("namelist1").range(0, 10);
System.out.println(list);
}
@Test
public void getListValue2() {
List list = redisTemplate.boundListOps("namelist2").range(0, 10);
System.out.println(list);
}
//根据索引查询元素
@Test
public void SearchList(){
String string = (String) redisTemplate.boundListOps("namelist1").index(1);
System.out.println(string);
}
// 移除集合某个元素
@Test
public void removeList(){
redisTemplate.boundListOps("namelist1").remove(1, "刘备");//移除一个
}
@Test
public void removeAllList(){
redisTemplate.delete("namelist1");
}
/**
* Hash类型操作
*/
@Test
public void setHashValue() {
redisTemplate.boundHashOps("namehash").put("a", "唐僧");
redisTemplate.boundHashOps("namehash").put("b", "唐僧1");
redisTemplate.boundHashOps("namehash").put("c", "唐僧2");
redisTemplate.boundHashOps("namehash").put("d", "唐僧3");
}
@Test
public void getHashKeyValue() {
Set set = redisTemplate.boundHashOps("namehash").keys();
System.out.println(set);
}
@Test
public void getHashValValue() {
List list = redisTemplate.boundHashOps("namehash").values();
System.out.println(list);
}
//根据KEY提取值
@Test
public void testGetValueByKey(){
Object object = redisTemplate.boundHashOps("namehash").get("b");
System.out.println(object);
}
//根据KEY移除值
@Test
public void testRemoveValueByKey(){
redisTemplate.boundHashOps("namehash").delete("c");
}
}