/**PageBeginHtml Block Begin **/ /***自定义返回顶部小火箭***/ /*生成博客目录的JS 开始*/ /*生成博客目录的JS 结束*/

SpringBoot +SpringData



一:简介


所涉及的技术:

  • Hibernate
  • JPA 标准
  • Hibernate JPA
  • Spring Data
  • Spring Data JPA
  • Spring Data Redi


1:Hibernate  介绍:

百度百科:hibernate 介绍

image



2:Jpa 标准

 百度百科:Jpa

image



3: Hibernate Jpa

Hibernate 在 3.2 以后根据 JPA 规范提供了一套操作持久层的 API




4: Spring Data


Spring Data 官网



image


SpringData的使命是为数据访问提供一个熟悉和一致的、基于Spring的编程模型,同时仍然保留底层数据存储的特殊特性。

它使得使用数据访问技术、关系数据库和非关系数据库、地图缩减框架和基于云的数据服务变得更加容易。这是一个伞式项目,包含许多特定于给定数据库的子项目。这些项目是通过与许多支持这些令人兴奋的技术的公司和开发人员共同开发的。

特征

  • 强大的存储库和自定义对象映射抽象

  • 存储库方法名的动态查询派生

  • 提供基本属性的实现域基类

  • 对透明审计的支持(创建,最后更改)

  • 集成自定义存储库代码的可能性

  • 通过JavaConfig和自定义XML命名空间实现轻松的Spring集成

  • 与SpringMVC控制器的高级集成

  • 对跨存储持久性的实验支持




5: Spring Data Jpa


Spring Data 官网    SpringData Jpa


image

image



SpringData JPA是更大的Spring数据系列的一部分,它使基于JPA的存储库易于实现。此模块处理对基于JPA的数据访问层的增强支持。它使构建使用数据访问技术的Spring支持的应用程序变得更加容易。

实现应用程序的数据访问层已经很长一段时间了。要执行简单的查询以及执行分页和审核,必须编写过多的样板代码。SpringDataJPA的目标是通过将工作量减少到实际需要的数量来显著改进数据访问层的实现。作为开发人员,您可以编写存储库接口,包括自定义查找器方法,Spring将自动提供实现。

特征

  • 基于Spring和JPA构建存储库的复杂支持

  • 支持Querydsl谓词,因此类型安全的JPA查询。

  • 域类的透明审计

  • 分页支持,动态查询执行,集成自定义数据访问代码的能力

  • 对.的验证@Query引导时带注释的查询

  • 支持基于XML的实体映射

  • 通过引入基于JavaConfig的存储库配置@EnableJpaRepositories.



SpringData Jpa 底层默认使用的时Hibernate 来做JPA实现。




6:SpringData  Redis


Spring Data 官网    spring-data-redis


image


Spring Data Redis

 2.5.1

Spring Data Redis, part of the larger Spring Data family, provides easy configuration and access to Redis from Spring applications. It offers both low-level and high-level abstractions for interacting with the store, freeing the user from infrastructural concerns.

Features


  • Connection package as low-level abstraction across multiple Redis drivers(Lettuce and Jedis).

  • Exception translation to Spring’s portable Data Access exception hierarchy for Redis driver exceptions.

  • RedisTemplate that provides a high-level abstraction for performing various Redis operations, exception translation and serialization support.

  • Pubsub support (such as a MessageListenerContainer for message-driven POJOs).

  • Redis Sentinel and Redis Cluster support.

  • Reactive API using the Lettuce driver.

  • JDK, String, JSON and Spring Object/XML mapping serializers.

  • JDK Collection implementations on top of Redis.

  • Atomic counter support classes.

  • Sorting and Pipelining functionality.

  • Dedicated support for SORT, SORT/GET pattern and returned bulk values.

  • Redis implementation for Spring 3.1 cache abstraction.

  • Automatic implementation of Repository interfaces including support for custom query methods using @EnableRedisRepositories.

  • CDI support for repositories.

Configure RedisTemplate….

<bean id="jedisConnFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:use-pool="true"/>

<!-- redis template definition -->
<bean id="redisTemplate"
    class="org.springframework.data.redis.core.RedisTemplate"
    p:connection-factory-ref="jedisConnFactory"/>


Inject and use RedisTemplate or any of its opsForX() instances….

public class Example {

    // inject the actual template
    @Autowired
    private RedisTemplate<String, String> template;

    // inject the template as ListOperations
    // can also inject as Value, Set, ZSet, and HashOperations
    @Resource(name="redisTemplate")
    private ListOperations<String, String> listOps;

    public void addLink(String userId, URL url) {
        listOps.leftPush(userId, url.toExternalForm());
        // or use template directly
        redisTemplate.boundListOps(userId).leftPush(url.toExternalForm());
    }
}


SpringDataRedis是更大的Spring数据系列的一部分,它提供了从Spring应用程序中轻松配置和访问Redis的功能。它为与商店交互提供了低层次和高级别的抽象,使用户摆脱了基础设施方面的担忧。

特征

  • 连接包作为跨多个Redis驱动程序的低级抽象(生菜吉迪斯).

  • 例如转换为Spring的可移植数据访问异常层次结构的Redis驱动程序异常。

  • RedisTemplate这为执行各种Redis操作、异常翻译和序列化支持提供了高级抽象.

  • Pubsub 支持(例如用于消息驱动的POJO的MessageListenerContainer)。

  • Redis SentinelRedis Cluster支持。

  • 使用生菜驱动程序的反应性API。

  • JDK、String、JSON和Spring对象/XML映射串行化.

  • JDKCollection 在Redis之上的实现。

  • 原子counter计数器)支持classes.

  • 排序和流水线功能。

  • 专用于对排序、排序/获取模式和返回的大容量值的支持。

  • Redis implementation  对于Spring3.1缓存抽象。

  • 自动实现Repository接口,包括对自定义查询方法的支持。@EnableRedisRepositories.

  • CDI对存储库的支持。








二:Spring+Hiberante


1: 项目代码结构

imageimage




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

	<!-- 1: 配置读取 properties 文件的工具类-->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 2: 配置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>
	<!-- 3: 配置hibernate 的sessionFactory  -->
	<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.alan.pojo</value>
			</list>
		</property>
	</bean>
	<!--8:在创建pojo 对象后,并且创建了service 层后, 配置HibernateTemplate 对象-->
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate" >
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	<!-- 4:配置Hibernate 的事务管理器  -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<!-- 5:配置开启注解是事务处理 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	<!-- 6:配置SpringIOC 的注解扫描-->
	<context:component-scan base-package="com.alan.*" />


</beans>




jdbc.properties



jdbc.driver.class=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
jdbc.username=root
jdbc.password=123456


Users

package com.alan.pojo;
/*
 * @author: Alan_liu
 * @date 2021/6/7 21:55
 */

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

}




UsersDao

package com.alan.dao;
/*
 * 接口实现类
 * @author: Alan_liu
 * @date 2021/6/7 22:10
 */

import java.util.List;

import com.alan.pojo.Users;

public interface UsersDao {
	void insertUsers(Users users);

	void updateUsers(Users users);

	void deleteUsers(Users users);

	Users selectUsersById(Integer usersId);

	/**
	 * HQL 查询:
	 *
	 *
	 */
	List<Users> queryUsersByNameUseHQLGetCurrentSession(String name);

	List<Users> queryUsersByNameUseHQLOpenSession(String name);

	/**
	 * SQL 查询:
	 *
	 */
	List<Users> queryUsersByNameUseSQLGetCurrentSession(String name);

	List<Users> queryUsersByNameUseSQLOpenSession(String name);

	/**
	 * QBC 查询: QBC:Query by Criteria
	 *
	 * 面向对象的数据库操作
	 */
	List<Users> queryUsersByNameUseQBCGetCurrentSession(String name);

	List<Users> queryUsersByNameUseQBCOpenSession(String name);

}






UsersDaoImpl

package com.alan.dao.Impl;
/*
 *
 * @author: Alan_liu
 * @date 2021/6/7 22:17
 */

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.alan.dao.UsersDao;
import com.alan.pojo.Users;

/**
 * * @Repository 注解是:将数据逻辑服务层对象 放在spring ioc容器中进行实例化
 *
 * 业务服务层 获取hibernate的hibernateTemplate 的2种实现方式: 1: 继承(extends)
 * HibernateDaoSupport 对象 因为: 对象需要 sessionFactory 的,
 * 而该继承了HibernateDaoSupport的方式,来获取 hibernateTemplate 的时候,那么就需要提供一个方法并且在该方法当中
 * 能够将applicationContext.xml配置文件中的sessionFactory 注入给HibernateDaoSupport
 * 。其实,最终不是注入给了HibernateDaoSupport 而是它有个属性叫sessionFactory。 2:在配置文件中配置
 * hibernateTemplate。其好处就在于: *< !--8:在创建pojo 对象后,并且创建了service 层后,
 * 配置HibernateTemplate 对象--> * < bean id="hibernateTemplate"
 * class="org.springframework.orm.hibernate5.HibernateTemplate" > * < property
 * name="sessionFactory" ref="sessionFactory"/> * *< /bean>
 **/
@Repository
public class UsersDaoImpl implements UsersDao {

	@Autowired
	private HibernateTemplate hibernateTemplate;

	@Override
	public void insertUsers(Users users) {
		this.hibernateTemplate.save(users);
	}

	@Override
	public void updateUsers(Users users) {
		this.hibernateTemplate.update(users);
	}

	@Override
	public void deleteUsers(Users users) {
		this.hibernateTemplate.delete(users);
	}

	@Override
	public Users selectUsersById(Integer usersId) {
		return this.hibernateTemplate.get(Users.class, usersId);
	}

	/**
	 * HQL 查询:
	 *
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Users> queryUsersByNameUseHQLGetCurrentSession(String name) {
		/**
		 * openSession : 返回1个session对象。每次都会打开一个新的session对象。加入每次使用多次。
		 * 则获得的是不同session对象。使用完后需要手动的调用colse方法关闭session对象
		 *
		 * getCurrentSession: 返回1个session对象 。 当前session 必须要有事务边界,且只能处于唯一的一个事务。当事务提交 或者回滚
		 * 后 session自动失效。
		 */
		Session session1 = this.hibernateTemplate.getSessionFactory().getCurrentSession();
		// sql:select * from users where username=?
		Query query = session1.createQuery("from Users where username  =:abc");
		Query queryTemp = query.setString("abc", name);// 序号是从0开始的

		return queryTemp.list();
	}

	/**
	 * HQL 查询:
	 *
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Users> queryUsersByNameUseHQLOpenSession(String name) {
		/**
		 * openSession : 返回1个session对象。每次都会打开一个新的session对象。加入每次使用多次。
		 * 则获得的是不同session对象。使用完后需要手动的调用colse方法关闭session对象
		 *
		 * getCurrentSession: 返回1个session对象 。 当前session 必须要有事务边界,且只能处于唯一的一个事务。当事务提交 或者回滚
		 * 后 session自动失效。
		 */
		Session session = this.hibernateTemplate.getSessionFactory().openSession();
		// sql:select * from users where username=?
		String nameString = "from Users where username  =:abc";
		Query query = session.createQuery(nameString);
		Query queryTemp = query.setString("abc", name);// 序号是从0开始的
		List<Users> userList = queryTemp.list();
		session.close();
		return userList;
	}

	/**
	 * SQL 查询:
	 *
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Users> queryUsersByNameUseSQLGetCurrentSession(String name) {
		/**
		 * openSession : 返回1个session对象。每次都会打开一个新的session对象。加入每次使用多次。
		 * 则获得的是不同session对象。使用完后需要手动的调用colse方法关闭session对象
		 *
		 * getCurrentSession: 返回1个session对象 。 当前session 必须要有事务边界,且只能处于唯一的一个事务。当事务提交 或者回滚
		 * 后 session自动失效。
		 */
		Session session1 = this.hibernateTemplate.getSessionFactory().getCurrentSession();
		String nameString = "select * from users where username  = ? ";
		Query query = session1.createSQLQuery(nameString).addEntity(Users.class).setString(0, name);// addEntity:增加对象与表字段的
		return query.list();
	}

	/**
	 * SQL 查询:
	 *
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Users> queryUsersByNameUseSQLOpenSession(String name) {
		/**
		 * openSession : 返回1个session对象。每次都会打开一个新的session对象。加入每次使用多次。
		 * 则获得的是不同session对象。使用完后需要手动的调用colse方法关闭session对象
		 *
		 * getCurrentSession: 返回1个session对象 。 当前session 必须要有事务边界,且只能处于唯一的一个事务。当事务提交 或者回滚
		 * 后 session自动失效。
		 */
		Session session = this.hibernateTemplate.getSessionFactory().openSession();
		String nameString = "select * from users where username  = ? ";
		Query query = session.createSQLQuery(nameString).addEntity(Users.class).setString(0, name);// addEntity:增加对象与表字段的
		List<Users> userList = query.list();
		session.close();
		return userList;
	}

	/**
	 * QBC 查询: QBC:Query by Criteria
	 *
	 * 面向对象的数据库操作
	 */
	@Override
	public List<Users> queryUsersByNameUseQBCGetCurrentSession(String name) {
		Session session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
		// sql:select * from users where username="张三"
		Criteria criteria = session.createCriteria(Users.class);// 该操作等同于:select * from users
		criteria.add(Restrictions.eq("username", name));
		// 获取结果集
		List<Users> list = criteria.list();
		return list;
	}

	/**
	 * QBC 查询: QBC:Query by Criteria
	 *
	 * 面
	 */
	@Override
	public List<Users> queryUsersByNameUseQBCOpenSession(String name) {
		/**
		 * openSession : 返回1个session对象。每次都会打开一个新的session对象。加入每次使用多次。
		 * 则获得的是不同session对象。使用完后需要手动的调用colse方法关闭session对象
		 *
		 * getCurrentSession: 返回1个session对象 。 当前session 必须要有事务边界,且只能处于唯一的一个事务。当事务提交 或者回滚
		 * 后 session自动失效。
		 */
		Session session = this.hibernateTemplate.getSessionFactory().openSession();
		// sql:select * from users where username="张三"
		Criteria criteria = session.createCriteria(Users.class);// 该操作等同于:select * from users
		criteria.add(Restrictions.eq("username", name));
		// 获取结果集
		List<Users> list = criteria.list();
		session.close();

		return list;
	}

}






UsersDaoImplTest

package com.alan.test;
/*
 * 测试UsersDaoImpl
 * @author: Alan_liu
 * @date 2021/6/7 22:37
 */

import java.util.List;

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.alan.dao.UsersDao;
import com.alan.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsersDaoImplTest {
	@Autowired
	private UsersDao usersDao;

	/***
	 * 添加用户
	 *
	 * @user Alan_liu
	 * @date 2021/6/7 22:39
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void addUsersTest() {
		Users users = new Users();
		users.setUsername("张三");
		users.setUserage(30);
		this.usersDao.insertUsers(users);
	}

	/***
	 * 更新用户
	 *
	 * @user Alan_liu
	 * @date 2021/6/7 22:39
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void updateUsersTest() {
		Users users = new Users();
		users.setUserid(1);
		users.setUsername("李四");
		users.setUserage(20);
		this.usersDao.updateUsers(users);
	}

	@Test
	public void testQueryUserById() {
		Users user = this.usersDao.selectUsersById(1);
		System.out.println(user.toString());
	}

	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testDeleteUserById() {
		Users users = new Users();
		users.setUserid(1);
		this.usersDao.deleteUsers(users);
	}

	/**
	 * HQL 查询 HQL: hibernate Query Language HQL的语法:就是将原来的SQL语句中的表与字段名称换成对象与属性的名称就可以了
	 *
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testQueryUsersByNameUseHQLGetCurrentSession() {
		List<Users> userList = this.usersDao.queryUsersByNameUseHQLGetCurrentSession("张三");
		for (Users u : userList) {
			System.out.println("queryUsersByNameUseGetCurrentSession" + u.toString());
		}
		List<Users> userList1 = this.usersDao.queryUsersByNameUseHQLOpenSession("张三");
		for (Users u : userList1) {
			System.out.println("queryUsersByNameUseOpenSession:" + u.toString());
		}
	}

	/**
	 * SQL 查询
	 *
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testQueryUsersByNameUseSQLGetCurrentSession() {
		List<Users> userList = this.usersDao.queryUsersByNameUseSQLGetCurrentSession("张三");
		for (Users u : userList) {
			System.out.println("queryUsersByNameUseSQLGetCurrentSession" + u.toString());
		}
		List<Users> userList1 = this.usersDao.queryUsersByNameUseSQLOpenSession("张三");
		for (Users u : userList1) {
			System.out.println("queryUsersByNameUseSQLOpenSession:" + u.toString());
		}
	}

	/**
	 * QBC 查询
	 *
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testQueryUsersByNameUseQBCGetCurrentSession() {
		List<Users> userList = this.usersDao.queryUsersByNameUseQBCGetCurrentSession("张三");
		for (Users u : userList) {
			System.out.println("queryUsersByNameUseQBCGetCurrentSession" + u.toString());
		}
		List<Users> userList1 = this.usersDao.queryUsersByNameUseQBCOpenSession("张三");
		for (Users u : userList1) {
			System.out.println("queryUsersByNameUseQBCOpenSession:" + u.toString());
		}
	}

}


 


 


 


 










三:Spring 整合 HibernateJpA

Jpa:由sun 公司提供的 一套对于持久层操作的标准(接口 和 文档)

Hibernate :是 由 Gavin king 开发的一套对于持久层操作的自动ORM框架

HibernateJpa:是在Hibernate3.2版本那种提供对于JPa的标准的实现。提供了一套按照JPA标准来实现持久层开发的API。






1:项目工程代码结构

imageimage


说明: SpingDataHibernateJpa  项目工程与SpringHibernate 项目工程的Lib 相差就一个 hibernate-entitymanager-5.0.7-Final.jar包。但其获取是数据session的配置及其实现方式已经不一样了





jdbc.properties

jdbc.driver.class=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
jdbc.username=root
jdbc.password=123456





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

	<!-- 1: 配置读取 properties 文件的工具类-->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 2: 配置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>
	<!-- 3: Spring 整合JPA  配置EntityManagerFactory   -->
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	 	<property name="dataSource" ref="dataSource"></property>
	 	<property name="jpaVendorAdapter">
	 		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
	 		 <!-- 配置 与hibernate配置相关的属性注入 -->
	 		 <!--1:从org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter类中获取Database的属性值,配置数据库类型  -->
	 		 <property name="database" value="MYSQL" />
	 		 <!--2:从org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter类中获取generateDdl的属性值,正向工程 自动创建表 -->
	 		 <property name="generateDdl" value="true" />
	 		 <!--3:从org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter类中获取showSql的属性值, 设置是否显示SQL -->
	 		 <property name="showSql" value="true" />
	 		</bean>
	 	</property>
	 	<!--4:配置 扫描实体类的包  -->
	 	<property name="packagesToScan">
	 		<list>
	 		  <value>com.alan.*</value>
	 		</list>
	 	</property>
	</bean>
	<!-- 4:配置Hibernate 的事务管理器  -->
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	<!-- 5:配置开启注解是事务处理 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	<!-- 6:配置SpringIOC 的注解扫描-->
	<context:component-scan base-package="com.alan.*" />


</beans>


注意: 本配置文件主要是其 获取session方式出现了变更




Users

package com.alan.pojo;
/*
 * @author: Alan_liu
 * @date 2021/6/7 21:55
 */

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

}




UsersDao


package com.alan.dao;
/*
 * 接口实现类
 * @author: Alan_liu
 * @date 2021/6/7 22:10
 */

import java.util.List;

import com.alan.pojo.Users;

public interface UsersDao {
	void insertUsers(Users users);

	void updateUsers(Users users);

	void deleteUsers(Users users);

	Users selectUsersById(Integer usersId);

	/**
	 * HQL 查询:
	 *
	 *
	 */
	List<Users> queryUsersByNameUseHQL(String name);

	/**
	 * SQL 查询:
	 *
	 */
	List<Users> queryUsersByNameUseSQL(String name);

	/**
	 * QBC 查询: QBC:Query by Criteria
	 *
	 * 面向对象的数据库操作
	 */
	List<Users> queryUsersByNameUseQBC(String name);

}




UsersDaoImpl


package com.alan.dao.Impl;
/*
 *
 * @author: Alan_liu
 * @date 2021/6/7 22:17
 */

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import com.alan.dao.UsersDao;
import com.alan.pojo.Users;

/**
 * * @Repository 注解是:将数据逻辑服务层对象 放在spring ioc容器中进行实例化
 *
 **/
@Repository
public class UsersDaoImpl implements UsersDao {
	/**
	 * 从上下文的工厂 context factory 中取出一个 entityManagerFactory对象 并注入到EntityManager 的属性中
	 *
	 */
	@PersistenceContext(name = "entityManagerFactory")
	private EntityManager entityManager;

	@Override
	public void insertUsers(Users users) {
		this.entityManager.persist(users);
	}

	@Override
	public void updateUsers(Users users) {
		this.entityManager.merge(users);
	}

	@Override
	public void deleteUsers(Users users) {
		// 1:先做查询
		Users u = this.entityManager.find(Users.class, users.getUserid());
		// 2:做对象删除
		this.entityManager.remove(u);
	}

	@Override
	public Users selectUsersById(Integer usersId) {
		return this.entityManager.find(Users.class, usersId);
	}

	/**
	 * HQL 查询:
	 *
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Users> queryUsersByNameUseHQL(String name) {
		String hQLString = "from Users where username = :abc";
		List<Users> userlList = this.entityManager.createQuery(hQLString).setParameter("abc", name).getResultList();
		return userlList;
	}

	/**
	 * SQL 查询:
	 *
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Users> queryUsersByNameUseSQL(String name) {
		// 在hibernate Jpa 中 如果通过?方式来绑定参数,那么它是查数是从1开始的。而hibernate是从0开始的
		String sqlString = "select  * from  users where username =?";
		List<Users> userlList = this.entityManager.createNativeQuery(sqlString, Users.class).setParameter(1, name)
				.getResultList();
		return userlList;
	}

	/**
	 * QBC 查询: QBC:Query by Criteria
	 *
	 * 面向对象的数据库操作
	 */
	@Override
	public List<Users> queryUsersByNameUseQBC(String name) {
		// 1:创建 CriteriaBuilder 对象:该对象可以创建一个 criteriaQuery.并创建查询条件
		CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
		// 2:criteriaQuery对象:执行查询的Criteria对象 .sql: select * from users;
		CriteriaQuery query = builder.createQuery(Users.class);
		// 3:获取要查询的实体类的对象。
		Root<Users> root = query.from(Users.class);
		// 4:封装查询条件
		Predicate cadePredicate = builder.equal(root.get("username"), name);// root.get("username") 谁为查询条件,就取谁的名称
		// select * from users where username ="张三"
		query.where(cadePredicate);
		// 。。。。。。如果还有其他的查询条件,继续用类似:builder.equal的方式继续构建

		// 5:执行查询
		TypedQuery<Users> typedQuery = this.entityManager.createQuery(query);
		return typedQuery.getResultList();
	}

}





UsersDaoImplTest

package com.alan.test;
/*
 * 测试UsersDaoImpl
 * @author: Alan_liu
 * @date 2021/6/7 22:37
 */

import java.util.List;

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.alan.dao.UsersDao;
import com.alan.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsersDaoImplTest {
	@Autowired
	private UsersDao usersDao;

	/***
	 * 添加用户
	 *
	 * @user Alan_liu
	 * @date 2021/6/7 22:39
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void addUsersTest() {
		Users users = new Users();
		users.setUsername("李四");
		users.setUserage(20);
		this.usersDao.insertUsers(users);
	}

	/***
	 * 更新用户
	 *
	 * @user Alan_liu
	 * @date 2021/6/7 22:39
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void updateUsersTest() {
		Users users = new Users();
		users.setUserid(3);
		users.setUsername("李四1");
		users.setUserage(25);
		this.usersDao.updateUsers(users);
	}

	@Test
	public void testQueryUserById() {
		Users user = this.usersDao.selectUsersById(3);
		System.out.println(user.toString());
	}

	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testDeleteUserById() {
		Users users = new Users();
		users.setUserid(3);
		this.usersDao.deleteUsers(users);
	}

	/**
	 * HQL 查询 HQL: hibernate Query Language HQL的语法:就是将原来的SQL语句中的表与字段名称换成对象与属性的名称就可以了
	 *
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testqueryUsersByNameUseHQL() {
		List<Users> userList = this.usersDao.queryUsersByNameUseHQL("李四");
		for (Users u : userList) {
			System.out.println("testqueryUsersByNameUseHQL" + u.toString());
		}
	}

	/**
	 * SQL 查询
	 *
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testqueryUsersByNameUseSQL() {
		List<Users> userList = this.usersDao.queryUsersByNameUseSQL("张三");
		for (Users u : userList) {
			System.out.println("testqueryUsersByNameUseSQL" + u.toString());
		}

	}

	/**
	 * QBC 查询
	 *
	 */
	@Test
	// 事务处理:
	@Transactional
	/**
	 * junit 的test 对事务处理的提交有自动回滚操作。应该需要进行取消其主动回滚操作机制
	 **/
	@Rollback(value = false)
	public void testqueryUsersByNameUseQBC() {
		List<Users> userList = this.usersDao.queryUsersByNameUseQBC("张三");
		for (Users u : userList) {
			System.out.println("testqueryUsersByNameUseQBC" + u.toString());
		}
	}

}


 


 




 


 


 





四:Spring Data-Spring Data JPA

1:代码整合

1-1:代码结构

imageimage


1-2:jdbc.properties

jdbc.driver.class=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
jdbc.username=root
jdbc.password=123456




1-3: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"
	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">

	<!-- 1: 配置读取 properties 文件的工具类-->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 2: 配置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>
	<!-- 3: Spring 整合JPA  配置EntityManagerFactory   -->
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	 	<property name="dataSource" ref="dataSource"></property>
	 	<property name="jpaVendorAdapter">
	 		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
	 		 <!-- 配置 与hibernate配置相关的属性注入 -->
	 		 <!--1:从org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter类中获取Database的属性值,配置数据库类型  -->
	 		 <property name="database" value="MYSQL" />
	 		 <!--2:从org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter类中获取generateDdl的属性值,正向工程 自动创建表 -->
	 		 <property name="generateDdl" value="true" />
	 		 <!--3:从org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter类中获取showSql的属性值, 设置是否显示SQL -->
	 		 <property name="showSql" value="true" />
	 		</bean>
	 	</property>
	 	<!--4:配置 扫描实体类的包  -->
	 	<property name="packagesToScan">
	 		<list>
	 		  <value>com.alan.*</value>
	 		</list>
	 	</property>
	</bean>
	<!-- 4:配置Hibernate 的事务管理器  -->
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	<!-- 5:配置开启注解是事务处理 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	<!-- 6:配置SpringIOC 的注解扫描-->
	<context:component-scan base-package="com.alan.*" />
	<!--7:Spring Data Jpa 的配置base-package:配置扫描Dao接口所在的包  -->
	<jpa:repositories base-package="com.alan.dao"  />


</beans>



1-4:编写pojo层:Users

package com.alan.pojo;
/*
 * @author: Alan_liu
 * @date 2021/6/7 21:55
 */

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "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 + "]";
	}

}



1-5:编写Dao层:UsersDaoJpaRepository

package com.alan.dao;
/*
 * 接口实现类
 * JpaRepository接口是开发人员进行开发使用最多的接口:其特点可以帮助开发人员将其他接口的方法的返回值做适配处理
 * 可以使开发人员在开发时候更方便使用这些方法
 *
 * @author: Alan_liu
 * @date 2021/6/7 22:10
 */

import org.springframework.data.jpa.repository.JpaRepository;

import com.alan.pojo.Users;

public interface UsersDaoJpaRepository extends JpaRepository<Users, Integer> {

}

1-6:编写测试代码JpaRepositoryTest

package com.alan.test;
/*
 * 测试UsersDaoImpl
 * @author: Alan_liu
 * @date 2021/6/7 22:37
 */

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
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.alan.dao.UsersDaoJpaRepository;
import com.alan.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaRepositoryTest {
	@Autowired
	private UsersDaoJpaRepository usersDao;
	/**
	* 添加用户
	**/
	@Test
	@Transactional
	@Rollback(false)
	public void testInsertUsers() {
		Users users = new Users();
		users.setUserage(24);
		users.setUsername("王武");
		this.usersDao.save(users);
	}



}

ZOA$Q6N(~R0{JXVI$YYM]3B




2:Spring Data JPA 的接口继承结构

image




3:Spring Data JPA 的运行原理

package com.alan.test;
/*
 * 测试UsersDaoImpl
 * @author: Alan_liu
 * @date 2021/6/7 22:37
 */

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
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.alan.dao.UsersDaoJpaRepository;
import com.alan.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaRepositoryTest {


	// 动态代理
	@Test
	public void test1() {
		// org.springframework.data.jpa.repository.support.SimpleJpaRepository@188d0fe
		System.out.println(this.usersDao);
		// class com.sun.proxy.$Proxy30 :-->
		// $Proxy30代理对象:-->基于JDK的动态代理方式创建的代理对象:-->SimpleJpaRepository
		System.out.println(this.usersDao.getClass());
	}

	// 手动创建 代理对象
	@PersistenceContext(name = "entityManagerFactory")
	private EntityManager em;

	@Test
	public void test2() {
		JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
		// getRepository(UsersDao.class):-->可以帮助开发人员进行接口生成实现类。而这个接口实现类为:SimpleJpaRepository的代理对象
		// 要求:该接口必须要继承Repository接口
		UsersDaoJpaRepository uDao = factory.getRepository(UsersDaoJpaRepository.class);
		System.out.println(uDao);// 打印结果:打印结果:org.springframework.data.jpa.repository.support.SimpleJpaRepository@4ccf8
		System.out.println(uDao.getClass());// 打印结果:class com.sun.proxy.$Proxy30
	}


}


4:Repository 接口

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

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

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

2)基于@Query 注解查询</DI< div>

关键字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEqual findByAgeGreaterThanEqual where age >= ?
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 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

findByAaaTue

where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)
top findTop100 top 10/where ROWNUM <=10

4-1:创建接口:UsersDaoRepository

package com.alan.dao;

import java.util.List;

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;

import com.alan.pojo.Users;

/**
 * Repository 接口: Repository 接口是SpringDataJpa 中为开发人员提供的所有接口中的顶层接口
 * Repository提供了2种查询方式的支持 1):基于方法命名的规则查询 2):基于@query注解查询,Update
 *
 * @author Alan-_-Liu
 *
 */
public interface UsersDaoRepository extends Repository<Users, Integer> {
	/**
	 * 1:方法名称命名规则查询:(规则)findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
	 */
	List<Users> findByUsernameIs(String userName);

	/**
	 * 1:方法名称命名规则查询:(规则)findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
	 */
	List<Users> findByUsernameLike(String userName);

	/**
	 * 1:方法名称命名规则查询:(规则)findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
	 */
	List<Users> findByUsernameAndUserageGreaterThanEqual(String userName, int age);

	/**
	 * 2:基于@Query注解的查询: 2.1:通过JPQL语句查询: JPQL:通过hibernate的HQL演变而来的。和其他HQL引发及其相似
	 */
	@Query(value = "from Users where username =? and userage=?")
	List<Users> QueryUsersByNameUseJPQL(String useraName, Integer userAge);

	/**
	 * 2:基于@Query注解的查询: 2.1:通过JPQL语句查询: JPQL:通过hibernate的HQL演变而来的。和其他HQL引发及其相似
	 */
	@Query(value = "from Users where username like ? and userage > ?")
	List<Users> QueryUsersByLikeNameUseJPQL(String useraName, Integer userAge);

	/**
	 * 2:基于@Query注解的查询: 2.2:通过SQL语句查询: nativeQuery 默认为false 表示不开启SQL查询。
	 * trule/false表示:是否对value中的sql语句做转义
	 */
	@Query(value = "select * from users t where  t.username=? ", nativeQuery = true)
	List<Users> QueryByUsernameIs(String userName);

	/**
	 * 2:基于@Query注解的查询: 2.2:通过SQL语句查询: nativeQuery 默认为false 表示不开启SQL查询。
	 * trule/false表示:是否对value中的sql语句做转义
	 */
	@Query(value = "select * from users t where  t.username like ? ", nativeQuery = true)
	List<Users> QueryByUsernameLike(String userName);

	/**
	 * 2:基于@Query注解的查询: 2.2:通过SQL语句查询: nativeQuery 默认为false 表示不开启SQL查询。
	 * trule/false表示:是否对value中的sql语句做转义
	 */
	@Query(value = "select * from users t where  t.username=?  and t.userage >=?", nativeQuery = true)
	List<Users> QueryUsernameAndUserageGreaterThanEqual(String userName, int age);

	/**
	 * 2:基于@Query注解的更新操作
	 *
	 * *@Modifying:当前的语句是一个更新语句
	 */
	@Query("update Users set userage=? where userid=?")
	@Modifying
	void updateUserAgeById(Integer userage, Integer id);

}



4-2:测试类:RepositoryTest

package com.alan.test;

import java.util.List;

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.alan.dao.UsersDaoRepository;
import com.alan.pojo.Users;

/**
 * Repository 接口测试
 *
 * @author Alan-_-Liu
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {

	@Autowired
	private UsersDaoRepository usersDao;

	/**
	 * 需求:使用用户名进行查询
	 */
	@Test
	public void findByUsernameIs() {
		/**
		 * 判断相等的条件:有三种表示方式: 1:什么都不写,默认的就是相等判断 2:Is 3:Equal
		 */
		List<Users> uList = this.usersDao.findByUsernameIs("王武");
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 需求:根据用户名做like处理
	 *
	 */

	@Test
	public void findByUsernameLike() {
		List<Users> uList = this.usersDao.findByUsernameLike("王%");
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 需求:做多个条件查询 --》 名称为 王武 且 年龄 大于等于22
	 */
	@Test
	public void findByUsernameAndUserageGreaterThanEqual() {
		List<Users> uList = this.usersDao.findByUsernameAndUserageGreaterThanEqual("王武", 22);
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 测试@Query查询 JPQL风格
	 */
	@Test
	public void QueryUsersByNameUserJPQL() {
		List<Users> uList = this.usersDao.QueryUsersByNameUseJPQL("王武", 24);
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 测试@Query查询 JPQL风格
	 */
	@Test
	public void QueryUsersByLikeNameUseJPQL() {
		List<Users> uList = this.usersDao.QueryUsersByLikeNameUseJPQL("%武", 22);
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 测试@Query查询 SQL风格
	 */
	@Test
	public void QueryByUsernameIs() {
		List<Users> uList = this.usersDao.QueryByUsernameIs("王武");
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 测试@Query查询 SQL风格
	 */
	@Test
	public void QueryByUsernameLike() {
		List<Users> uList = this.usersDao.QueryByUsernameLike("%武");
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 测试@Query查询 SQL风格
	 */
	@Test
	public void QueryUsernameAndUserageGreaterThanEqual() {
		List<Users> uList = this.usersDao.QueryUsernameAndUserageGreaterThanEqual("王武", 22);
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 2:基于@Query注解的更新操作
	 *
	 * *@Modifying:当前的语句是一个更新语句
	 */
	@Test
	@Transactional
	@Rollback(false)
	public void updateUserAgeById() {
		this.usersDao.updateUserAgeById(22, 5);
	}
}

}3}75OC}NH`LTWP3W59%~4MEMH7}7OLK[8WR_IB9{6OWT6


U)0KF$HSI9Q7{U2}GP3FL6EH~YF6US$()B}TXVG5@F1E$5WEZ3OBX6)B`)SGBEB]1`7~DCLK8}LB]A8@7P1RVXKP82YS

ZHHX9%TXUR~YRJQXM@MHE%B63PFS7G7`CI6RE([U(JO9~DAJ720[DN%)EFH(%{J4_S(AM





5:CrudRepository 接口

5-1:创建接口:UsersDaoCrudRepository

package com.alan.dao;

import org.springframework.data.repository.CrudRepository;

import com.alan.pojo.Users;

/**
 * CrudRepository 接口讲解:
 *
 * @author Alan-_-Liu
 *
 */
public interface UsersDaoCrudRepository extends CrudRepository<Users, Integer> {

}



5-2:测试代码:CrudRepositoryTest


package com.alan.test;

import java.util.ArrayList;
import java.util.List;

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.alan.dao.UsersDaoCrudRepository;
import com.alan.pojo.Users;

/**
 * CrudRepository 接口测试
 *
 * @author Alan-_-Liu
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class CrudRepositoryTest {

	@Autowired
	private UsersDaoCrudRepository usersDao;

	/**
	 * 单条业务数据添加
	 */
	@Test
	public void AddTest() {
		Users user = new Users();
		user.setUserage(22);
		user.setUsername("林冲");
		this.usersDao.save(user);
	}

	/**
	 * 批量业务数据添加
	 */
	@Test
	public void batchAddTest() {
		Users user1 = new Users();
		user1.setUserage(34);
		user1.setUsername("晁盖");
		Users user2 = new Users();
		user2.setUserage(26);
		user2.setUsername("高俅");
		Users user3 = new Users();
		user3.setUserage(24);
		user3.setUsername("岳飞");
		Users user4 = new Users();
		user4.setUserage(25);
		user4.setUsername("赵世雄");
		List<Users> uList = new ArrayList<Users>();
		uList.add(user1);
		uList.add(user2);
		uList.add(user3);
		uList.add(user4);
		this.usersDao.save(uList);
	}

	/**
	 * 根据ID查询单条数据
	 */
	@Test
	public void findOneTest() {
		System.out.println(this.usersDao.findOne(16).toString());
	}

	/**
	 * 查询全部数据
	 */
	@Test
	public void findAllTest() {
		List<Users> uList = (List<Users>) this.usersDao.findAll();
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}

	/**
	 * 删除数据
	 */
	@Test
	public void deleteTest() {
		this.usersDao.delete(15);
	}

	/**
	 * 更新数据
	 */
	@Test
	public void UpdateBySaveTest() {
		Users users = this.usersDao.findOne(16);
		users.setUsername("林教头");
		this.usersDao.save(users);
	}

	/**
	 * 更新数据:基于hibernate的持久化进行数据更新操作。必须要开始事务机制
	 */
	@Test
	@Transactional
	@Rollback(false)
	public void UpdateBySaveSecondTest() {
		Users users = this.usersDao.findOne(13);// hibernate 的持久化状态
		users.setUsername("高鸡儿");
	}

}

F95{ME`U$O~BB@$SLGC`V~O2C)%)OK)02~]3%22G}CSTNB~D8}U6PZT1%RYWB6]7U400S{{D%RAI$I{TA_5GHBP1D%`I`O3~XA~319JC}73U]%N$8C80{TT5X%B6J_1`JVR)29EFB9







6:PagingAndSortingRepository 接口

6-1:创建接口:UsersDaoPagingAndSortingRepository

package com.alan.dao;

import org.springframework.data.repository.PagingAndSortingRepository;

import com.alan.pojo.Users;

/**
 * PagingAndSortingRepository 分页接口
 *
 * @author Alan-_-Liu
 *
 */
public interface UsersDaoPagingAndSortingRepository extends PagingAndSortingRepository<Users, Integer> {

}


6-2:测试代码:PagingAndSortingRepositoryTest


package com.alan.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alan.dao.UsersDaoPagingAndSortingRepository;
import com.alan.pojo.Users;

/**
 * PagingAndSortingRepository 分页接口测试
 *
 * @author Alan-_-liu
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class PagingAndSortingRepositoryTest {
	@Autowired
	private UsersDaoPagingAndSortingRepository userDao;

	/**
	 * 分页查询
	 */
	@Test
	public void findAllToPage() {
		int page = 0;// page:当前 页的索引,注意索引是从0开始的
		int size = 8;// size:每页显示3条数据
		Pageable p = new PageRequest(page, size);
		Page<Users> uPage = this.userDao.findAll(p);
		System.out.println("数据的总页数:" + uPage.getTotalPages());
		System.out.println("数据的每页数:" + uPage.getSize());
		System.out.println("数据的总条数:" + uPage.getTotalElements());
		List<Users> uList = uPage.getContent();
		for (Users u : uList) {
			System.out.println(u.toString());
		}
	}

	/**
	 * 对单列做排序处理
	 */
	@Test
	public void findAllBySort() {
		// sort:该对象封装了排序规则以及指定的排序字段(对象属性来表示)
		// direction:排序规则
		// properties:指定做排序的属性
		Sort sort = new Sort(Direction.DESC, "userid");
		List<Users> uList = (List<Users>) this.userDao.findAll(sort);
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}

	/**
	 * 对多列的排序处理
	 */
	@Test
	public void findAllBySortToMore() {
		// sort:该对象封装了排序规则以及指定的排序字段(对象属性来表示)
		// direction:排序规则
		// properties:指定做排序的属性
		Order order = new Order(Direction.DESC, "userid");
		Order order2 = new Order(Direction.ASC, "username");
		Sort sort = new Sort(order, order2);
		List<Users> uList = (List<Users>) this.userDao.findAll(sort);
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}
}

Y5`8H_N~[D`(]YPLP)GHXRKI1$O9ISH4UK$K2I)AFY7@(9~_[)TF3}FMT(I~05[)JV%3Q





7:JpaRepository 接口

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

7-1:创建接口UsersDaoJpaRepository


package com.alan.dao;
/*
 * 接口实现类
 * JpaRepository接口是开发人员进行开发使用最多的接口:其特点可以帮助开发人员将其他接口的方法的返回值做适配处理
 * 可以使开发人员在开发时候更方便使用这些方法
 *
 * @author: Alan_liu
 * @date 2021/6/7 22:10
 */

import org.springframework.data.jpa.repository.JpaRepository;

import com.alan.pojo.Users;

public interface UsersDaoJpaRepository extends JpaRepository<Users, Integer> {

}


7-2:测试代码:JpaRepositoryTest

package com.alan.test;
/*
 * 测试UsersDaoImpl
 * @author: Alan_liu
 * @date 2021/6/7 22:37
 */

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
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.alan.dao.UsersDaoJpaRepository;
import com.alan.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaRepositoryTest {
	@Autowired
	private UsersDaoJpaRepository usersDao;
 
	/**
	 * 查询是有数据
	 */
	@Test
	public void ListByFindAll() {
		List<Users> ulList = this.usersDao.findAll();
		for (Users users : ulList) {
			System.out.println(users.toString());
		}
	}

}

[1P{C9DKFT~8I28JFE[Y5@G







8:JpaSpecificationExecutor 接口

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

8-1:创建接口:UsersDaoJpaSpecificationExecutor


package com.alan.dao;

import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;

import com.alan.pojo.Users;

/**
 * JpaSpecificationExecutor 接口讲解:1:该接口不能单独使用,需要配合jpa其他接口一起使用
 *
 * @author Alan-_-Liu
 *
 */
public interface UsersDaoJpaSpecificationExecutor
		extends CrudRepository<Users, Integer>, JpaSpecificationExecutor<Users> {

}



8-2:测试代码:JpaSpecificationExecutorTest


package com.alan.test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alan.dao.UsersDaoJpaSpecificationExecutor;
import com.alan.pojo.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaSpecificationExecutorTest {
	@Autowired
	private UsersDaoJpaSpecificationExecutor userDao;

	/**
	 * 单条件查询
	 *
	 * 需求:根据用户姓名查询数据
	 */
	@Test
	public void FindOneTest() {

		Specification<Users> specification = new Specification<Users>() {
			/**
			 * *@return :定义了查询条件(如:https://www.cnblogs.com/ios9/p/14854700.html 一文中:“Spring
			 * 整合 HibernateJpA”中的“UsersDaoImpl ”的“public List<Users>
			 * queryUsersByNameUseQBC(String name) ”方法逻辑所写一般)
			 *
			 * *@param Root<Users> :root根对象。封装查询条件的对象的指定
			 *
			 * *@param CriteriaQuery<?> query:是实现了一个基本的查询功能。一般不使用
			 *
			 * *@param CriteriaBuilder cb:创建一个查询条件
			 *
			 */
			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate predicate = cb.equal(root.get("username"), "王武");
				return predicate;
			}
		};
		List<Users> uList = this.userDao.findAll(specification);
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}

	/**
	 * 多条件查询:方式一
	 *
	 * 需求:使用用户名字和年龄进行数据查询
	 *
	 */
	@Test
	public void findAllByAndTest() {

		Specification<Users> specification = new Specification<Users>() {
			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> preList = new ArrayList<Predicate>();
				preList.add(cb.equal(root.get("username"), "王武"));
				preList.add(cb.greaterThanOrEqualTo(root.get("userage"), 22));
				// 此时条件之间是没有任何关系的
				Predicate[] arrayPredicates = new Predicate[preList.size()];
				return cb.and(preList.toArray(arrayPredicates));
			}
		};
		List<Users> uList = this.userDao.findAll(specification);
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}

	/**
	 * 多条件查询:方式二
	 *
	 * 需求:使用用户名字或者年龄进行数据查询
	 *
	 */
	@Test
	public void findAllByOrTest() {

		Specification<Users> specification = new Specification<Users>() {
			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.or(cb.equal(root.get("username"), "王武"), cb.greaterThanOrEqualTo(root.get("userage"), 22));
			}
		};
		List<Users> uList = this.userDao.findAll(specification);
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}

	/**
	 * 需求:查询姓 王 用户,并做分页处理
	 */
	@Test
	public void findAllToPageTest() {
		// 查询条件
		Specification<Users> specification = new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.like(root.get("username").as(String.class), "王%");
			}

		};
		// 分页
		Pageable pageable = new PageRequest(0, 5);
		Page<Users> uPage = this.userDao.findAll(specification, pageable);
		System.out.println("总记录记录数:" + uPage.getTotalElements());
		System.out.println("总页数" + uPage.getTotalPages());
		List<Users> uList = uPage.getContent();
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}

	/**
	 * 需求:查询数据库在王姓用户,并且根据 用户id倒序排序
	 */
	@Test
	public void findAllToMoreQueryBySort() {
		// 查询条件
		Specification<Users> specification = new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.like(root.get("username").as(String.class), "王%");
			}

		};
		// 排序:
		Sort sort = new Sort(Direction.DESC, "userid");
		List<Users> uList = this.userDao.findAll(specification, sort);
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}

	/**
	 * 需求:查询数据库在王姓用户,做分页处理 并且根据 用户id倒序排序
	 */
	@Test
	public void findAllToMoreQueryPageBySort() {
		// 排序定义:
		Sort sort = new Sort(Direction.DESC, "userid");
		// 分页定义
		Pageable pageable = new PageRequest(0, 2, sort);
		// 查询条件
		Specification<Users> specification = new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.like(root.get("username").as(String.class), "王%");
			}

		};
		Page<Users> uPage = this.userDao.findAll(specification, pageable);
		System.out.println("总记录记录数:" + uPage.getTotalElements());
		System.out.println("总页数" + uPage.getTotalPages());
		List<Users> uList = uPage.getContent();
		for (Users users : uList) {
			System.out.println(users.toString());
		}
	}
}

OKEBD(1I$B6Q}KZ9M@YT`RS]O04W(O`LV)3SL73_J%83P68T]FOVG][$M89%@)IXLII1WDA%%$8H]33{U}[~(TL{$}Y6(N_(TNFTT[XHN95~]]~MGXY}(G_QQ)96J{Z_8(HN2HJ17Q3}[37HEXYL1~)D7N@05Q{_E





9:用户自定义 Repository 接口

9-1:创建接口:SelfRepository

package com.alan.dao;

import com.alan.pojo.Users;

/**
 * 用户自定义Repository接口 讲解:
 *
 * @author Alan-_-liu
 *
 */
public interface SelfRepository<T, ID> {
	/**
	 * 根据用户id查询用户信息
	 *
	 * @param userId
	 * @return Users
	 */
	public Users findUserById(Integer userId);

}

9-2:创建接口实现类:SelfRepositoryImpl

package com.alan.dao;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

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

import com.alan.pojo.Users;

/**
 * 用户自定义Repository接口 讲解:
 *
 *
 * @author Alan-_-liu
 *
 */
@Service
public class SelfRepositoryImpl implements SelfRepository<Users, Integer> {

	@Autowired
	@PersistenceContext(name = "entityManagerFactory")
	private EntityManager em;

	@Override
	public Users findUserById(Integer userid) {
		System.out.println("MyRepository......");
		return this.em.find(Users.class, userid);
	}

}





9-3:使用接口  UsersDaoSelfRepository


package com.alan.dao;

import org.springframework.stereotype.Repository;

/**
 * 用户自定义Repository接口 讲解:
 *
 * @author Alan-_-liu
 *
 */
@Repository
public interface UsersDaoSelfRepository
		extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users>,  SelfRepository {

}


9-4:编写测试代码:SelfRepositoryTest

package com.alan.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alan.dao.UsersDaoSelfRepository;
import com.alan.pojo.Users;

/**
 * 用户自定义Repository接口 讲解:
 *
 *
 * @author Alan-_-liu
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SelfRepositoryTest {

	@Autowired(required = true)
	private UsersDaoSelfRepository usersDao;

	@Test
	public void findeUsersByIdTest() {
		Users users = this.usersDao.findUserById(5);
		System.out.println(users);
	}
}








10:一对多 关联映射操作

一对一的关联关系

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

用户:一方

角色:一方

10-1:创建Users实体类:Users


package com.alan.pojo;
/*
 * @author: Alan_liu
 * @date 2021/6/7 21:55
 */

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "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)
	// @JoinColum:就是维护一个外键
	@JoinColumn(name = "roles_id")
	private Roles roles;

	public Roles getRoles() {
		return roles;
	}

	public void setRoles(Roles roles) {
		this.roles = roles;
	}

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

}



10-2:创建Roles实体:Roles

package com.alan.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * 一对一 关联关系
 *
 * @author Alan-_-liu
 *
 */
@Entity
@Table(name = "roles")
public class Roles {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "roleid")
	private Integer roleid;
	@Column(name = "rolename")
	private String rolename;

	public Users getUsers() {
		return users;
	}

	public void setUsers(Users users) {
		this.users = users;
	}

	@OneToOne(mappedBy = "roles")
	private Users users;

	public Integer getRoleid() {
		return roleid;
	}

	public void setRoleid(Integer roleid) {
		this.roleid = roleid;
	}

	public String getRolename() {
		return rolename;
	}

	public void setRolename(String rolename) {
		this.rolename = rolename;
	}

	@Override
	public String toString() {
		return "Roles [roleid=" + roleid + ", rolename=" + rolename + ", users=" + users + "]";
	}

}



10-3:一对一关联关系操作

package com.alan.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.alan.dao.OneToOneUsersDao;
import com.alan.pojo.Roles;
import com.alan.pojo.Users;

/**
 * 一对一关联关系操作
 *
 *
 * @author Alan-_-liu
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class OneToOneTest {
	@Autowired
	private OneToOneUsersDao usersDao;

	/**
	 * 需求:添加用户同时添加角色信息
	 */
	@Test
	@Transactional
	@Rollback(false)
	public void OneToOneAddSaveTest() {
		// 创建角色
		Roles r = new Roles();
		r.setRolename("管理员");
		// 创建用户
		Users u = new Users();
		u.setUsername("张丽英");
		u.setUserage(25);
		// 建立关系
		u.setRoles(r);
		r.setUsers(u);
		// 保存数据
		this.usersDao.save(u);
	}

	/**
	 * 根据用户ID 查询用户,同时查询用户角色
	 */
	@Test
	public void queryUserInfoByID() {
		Users u = this.usersDao.findOne(17);
		System.out.println("用户信息" + u.toString());
		Roles roles = u.getRoles();
		System.out.println(roles);

	}
}

TT07X79GCHY0MA4]A)_E[V0FBEIK1U_RI2F_YKJ]D_{)Q5








11:多对多的关联关系

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

角色:多方

菜单:多方

11-1:创建实体:RolesManyToMany

package com.alan.pojo;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

/**
 * 一对一 关联关系
 *
 * @author Alan-_-liu
 *
 */
@Entity
@Table(name = "roles")
public class RolesManyToMany {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "roleid")
	private Integer roleid;
	@Column(name = "rolename")
	private String rolename;

	@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER /* 立即加载,取消其延迟的懒加载问题 */)
	// @JoinTable 配置中间表
	// joinColumns = @JoinColumn(name = "role_id") 建立当前表在中间表的外键字段
	// inverseJoinColumns = @JoinColumn(name = "menu_id") 另外一方外键表的主键
	@JoinTable(name = "rolesMenus", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "menu_id"))
	private Set<MenusManyToMany> mnSet = new HashSet<MenusManyToMany>();

	public Set<MenusManyToMany> getMnSet() {
		return mnSet;
	}

	public void setMnSet(Set<MenusManyToMany> mnSet) {
		this.mnSet = mnSet;
	}

	public Integer getRoleid() {
		return roleid;
	}

	public void setRoleid(Integer roleid) {
		this.roleid = roleid;
	}

	public String getRolename() {
		return rolename;
	}

	public void setRolename(String rolename) {
		this.rolename = rolename;
	}

	@Override
	public String toString() {
		return "Roles [roleid=" + roleid + ", rolename=" + rolename + "]";
	}

}




11-2:创建实体:MenusManyToMany


package com.alan.pojo;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "menus")
public class MenusManyToMany {

	@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 = "mnSet")
	private Set<RolesManyToMany> rmSet = new HashSet<RolesManyToMany>();

	public Set<RolesManyToMany> getRmSet() {
		return rmSet;
	}

	public void setRmSet(Set<RolesManyToMany> rmSet) {
		this.rmSet = rmSet;
	}

	public Integer getMenusid() {
		return menusid;
	}

	public void setMenusid(Integer menusid) {
		this.menusid = menusid;
	}

	public String getMenusname() {
		return menusname;
	}

	public void setMenusname(String menusname) {
		this.menusname = menusname;
	}

	public String getMenusurl() {
		return menusurl;
	}

	public void setMenusurl(String menusurl) {
		this.menusurl = menusurl;
	}

	public Integer getFatherid() {
		return fatherid;
	}

	public void setFatherid(Integer fatherid) {
		this.fatherid = fatherid;
	}

	@Override
	public String toString() {
		return "MenusMoreToMore [menusid=" + menusid + ", menusname=" + menusname + ", menusurl=" + menusurl
				+ ", fatherid=" + fatherid + "]";
	}

}

11-3:创建多对多关联关系操作:ManyToManySaveTest

package com.alan.test;

import java.util.Set;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alan.dao.ManyToManyRolesDao;
import com.alan.pojo.MenusManyToMany;
import com.alan.pojo.RolesManyToMany;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ManyToManyTest {

	@Autowired
	private ManyToManyRolesDao rolesDao;

	/**
	 * 需求:添加角色的同时添加菜单
	 */
	@Test
	public void ManyToManySaveTest() {
		// 创建角色对象
		RolesManyToMany r = new RolesManyToMany();
		r.setRolename("超级管理员");
		// 创建菜单对象 XXX管理平台---》用户管理
		MenusManyToMany m = new MenusManyToMany();
		m.setMenusname("xxxx管理平台");
		m.setFatherid(-1);
		m.setMenusurl(null);

		MenusManyToMany mm = new MenusManyToMany();
		mm.setMenusname("用户管理");
		mm.setMenusurl(null);
		mm.setFatherid(1);
		// 建立关系
		r.getMnSet().add(m);
		r.getMnSet().add(mm);
		m.getRmSet().add(r);
		mm.getRmSet().add(r);
		// 保存数据
		this.rolesDao.save(r);
	}

	/**
	 * 查询操作 此处处理延迟加载的问题方案: 方案1:在 application.properties 配置文件中增加
	 * spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true 方案2:在
	 * rolesjava类的 private Set<Menus> menusSet =new HashSet<Menus>(); 的注解上增加fetch
	 * =FetchType.EAGER 开启立即加载 如 * @ManyToMany(cascade = CascadeType.PERSIST,fetch
	 * =FetchType.EAGER)
	 */
	@Test
	public void findOneTest() {
		RolesManyToMany roles = this.rolesDao.findOne(2);
		System.out.println(roles.getRolename());
		Set<MenusManyToMany> rolesMenusSet = roles.getMnSet();
		for (MenusManyToMany menus1 : rolesMenusSet) {
			System.out.println(menus1);
		}
	}

}

FBEIK1U_RI2F_YKJ]D_{)Q54QF_KG0]O@A2FSZXDCTKP50







五:SpringBoot 整合 Jpa


请参考该文内容:《SpringBoot 整合 jpa




六:Spring Data-Spring Data Redis


1:Spring Data Redis 简介


Spring Data Redis

 2.5.1

Spring Data Redis, part of the larger Spring Data family, provides easy configuration and access to Redis from Spring applications. It offers both low-level and high-level abstractions for interacting with the store, freeing the user from infrastructural concerns.

Features

  • Connection package as low-level abstraction across multiple Redis drivers(Lettuce and Jedis).

  • Exception translation to Spring’s portable Data Access exception hierarchy for Redis driver exceptions.

  • RedisTemplate that provides a high-level abstraction for performing various Redis operations, exception translation and serialization support.

  • Pubsub support (such as a MessageListenerContainer for message-driven POJOs).

  • Redis Sentinel and Redis Cluster support.

  • Reactive API using the Lettuce driver.

  • JDK, String, JSON and Spring Object/XML mapping serializers.

  • JDK Collection implementations on top of Redis.

  • Atomic counter support classes.

  • Sorting and Pipelining functionality.

  • Dedicated support for SORT, SORT/GET pattern and returned bulk values.

  • Redis implementation for Spring 3.1 cache abstraction.

  • Automatic implementation of Repository interfaces including support for custom query methods using @EnableRedisRepositories.

  • CDI support for repositories.


SpringDataRedis是更大的Spring数据系列的一部分,它提供了从Spring应用程序中轻松配置和访问Redis的功能。它为与商店交互提供了低层次和高级别的抽象,使用户摆脱了基础设施方面的担忧。

特征

  • 连接包作为跨多个Redis驱动程序的低级抽象(生菜吉迪斯).

  • 例外转换为Spring的可移植数据访问异常层次结构的Redis驱动程序异常。

  • RedisTemplate这为执行各种Redis操作、异常翻译和序列化支持提供了高级抽象.

  • 普贝支持(例如用于消息驱动的POJO的MessageListenerContainer)。

  • 红哨红系簇支持。

  • 使用生菜驱动程序的反应性API。

  • JDK、String、JSON和Spring对象/XML映射串行化.

  • JDK收藏在Redis之上的实现。

  • 原子计数器支援班。

  • 排序和流水线功能。

  • 专用于对排序、排序/获取模式和返回的大容量值的支持。

  • 雷迪斯实施对于Spring3.1缓存抽象。

  • 自动实现Repository接口,包括对自定义查询方法的支持。@EnableRedisRepositories.

  • CDI对存储库的支持。




Spring Initializr

Quickstart Your Project

Bootstrap your application with Spring Initializr.




2:Redis 安装

VMware安装CentOS7超详细版

Centos7安装redis6.0.6教程


3:搭建整合环境


image

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

	<!-- 1: 配置读取 properties 文件的工具类-->
	<context:property-placeholder location="classpath:redis.properties" />

	<!--2:配置 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>

	<!--3: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="password" value="${redis.conn.password}"/>
		<property name="poolConfig" ref="poolConfig"/>
	</bean>

	<!--4:Jedis的模板的对象  -->
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory"/>
		<!--序列化器:能够帮助开发人员进行存储的key和 value做序列化处理的对象  -->
		<!--配置默认的序列化器  -->
		<!--keySerializer 、valueSerializer 配置Redis 中的 String 类型的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>

		<!--hashKeySerializer、hashValueSerializer 配置 redis 中的 hash 类型的 key 和value的序列化器  -->
	   <!-- <property name="hashKeySerializer">
			<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
		</property>
		<property name="hashValueSerializer">
			<bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer"></bean>
		</property>  -->
	</bean>




</beans>



redis.properties

redis.pool.maxTotal=20
redis.pool.maxIdle=10
redis.pool.minIdle=5


redis.conn.hostName=192.168.0.100
redis.conn.password=12345678
redis.conn.port=6379

Users

package com.alan.pojo;

import java.io.Serializable;

/**
 *
 * @author Alan-_-liu
 *
 */
public class Users implements Serializable {

	/**
	 *
	 */
	private Integer id;
	private String name;
	private Integer age;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Users [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}


RedisTest

package com.alan.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alan.pojo.Users;

/**
 * Redis 测试
 *
 * @author Alan-_-liu
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RedisTest {

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	/**
	 * 添加键值对
	 */
	@Test
	public void opsForValueSetStringTest() {
		this.redisTemplate.opsForValue().set("Key", "redisTemplate");
	}

	/**
	 * 获取redis中的键值对
	 */
	@Test
	public void opsForValueGetStringTest() {
		String keyString = (String) this.redisTemplate.opsForValue().get("Key");
		System.out.println(keyString);
	}

	/**
	 * 添加Users
	 */
	@Test
	public void setUsersObjectTest() {
		Users u = new Users();
		u.setAge(30);
		u.setId(1);
		u.setName("张山");
		this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
		this.redisTemplate.opsForValue().set("users", u);
	}

	/**
	 * 获取users
	 */
	@Test
	public void opsForValueGetObjectTest() {
		// 更换序列化器
		this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
		Users users = (Users) this.redisTemplate.opsForValue().get("users");
		System.out.println(users.toString());
	}

	/**
	 * 添加Users JSON格式
	 */
	@Test
	public void setUsersObjectJsonTest() {
		Users users = new Users();
		users.setAge(23);
		users.setId(2);
		users.setName("李四");

		this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
		this.redisTemplate.opsForValue().set("usersjson", users);
	}

	/**
	 * 获取Uesrs JSON格式
	 */
	@Test
	public void getUsersObjectJsonTest() {
		this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
		Users users = (Users) this.redisTemplate.opsForValue().get("usersjson");
		System.out.println(users);
	}
}














posted @ 2021-06-06 10:25  一品堂.技术学习笔记  阅读(129)  评论(0编辑  收藏  举报