SpringDataJpa的与Spring整合和基本查询语句(nosession问题)

依赖文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <groupId>com.itheimagroupId>
  <artifactId>day03_javaee52_springdatajpa_01artifactId>
  <version>0.0.1-SNAPSHOTversion>
  <dependencies>
  	<dependency>
  		<groupId>mysqlgroupId>
  		<artifactId>mysql-connector-javaartifactId>
  		<version>5.1.6version>
  	dependency>
  	<dependency>
  		<groupId>junitgroupId>
  		<artifactId>junitartifactId>
  		<version>4.12version>
  	dependency>
  	<dependency>
  		<groupId>log4jgroupId>
  		<artifactId>log4jartifactId>
  		<version>1.2.12version>
  	dependency>
  	<dependency>
  		<groupId>org.hibernategroupId>
  		<artifactId>hibernate-c3p0artifactId>
  		<version>5.0.7.Finalversion>
  	dependency>
  	<dependency>
  		<groupId>org.hibernategroupId>
  		<artifactId>hibernate-entitymanagerartifactId>
  		<version>5.0.7.Finalversion>
  	dependency>
  	<dependency>
  		<groupId>org.springframeworkgroupId>
  		<artifactId>spring-contextartifactId>
  		<version>5.0.2.RELEASEversion>
  	dependency>
  	<dependency>
  		<groupId>org.aspectjgroupId>
  		<artifactId>aspectjweaverartifactId>
  		<version>1.8.7version>
  	dependency>
  	<dependency>
  		<groupId>org.springframeworkgroupId>
  		<artifactId>spring-ormartifactId>
  		<version>5.0.2.RELEASEversion>
  	dependency>
  	<dependency>
  		<groupId>org.springframework.datagroupId>
  		<artifactId>spring-data-jpaartifactId>
  		<version>2.0.5.RELEASEversion>
  	dependency>
  	<dependency>
  		<groupId>org.springframeworkgroupId>
  		<artifactId>spring-testartifactId>
  		<version>4.3.6.RELEASEversion>
  	dependency>
  	<dependency>
  		<groupId>org.springframeworkgroupId>
  		<artifactId>spring-txartifactId>
  		<version>4.3.2.RELEASEversion>
  	dependency>
  dependencies>
project>

配置文件applicationContext.xml


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
	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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
		
    
	<context:component-scan base-package="com.itheima">context:component-scan>
		
	
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver" />
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" />
		<property name="user" value="root" />
		<property name="password" value="admin" />
	bean>
	
	
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="packagesToScan" value="com.itheima.domain" />
		<property name="persistenceProvider">
			<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
		property>
		
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="generateDdl" value="false" />
				<property name="database" value="MYSQL" />
				<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
				<property name="showSql" value="true" />
			bean>
		property>
		
		<property name="jpaDialect">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
		property>
	bean>
    
	
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	bean>
	
	
	<jpa:repositories 
	   base-package="com.itheima.dao"
	   transaction-manager-ref="transactionManager" 
	   entity-manager-factory-ref="entityManagerFactory">
	jpa:repositories>
		
	
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
			<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
			<tx:method name="*" propagation="REQUIRED" read-only="false"/>
		tx:attributes>
	tx:advice>
	
	
	<aop:config>
		<aop:pointcut id="pointcut" expression="execution(* com.itheima.service.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
	aop:config>
beans>

简单的CRUD

只需要将dao接口继承JpaRepository接口,不需要我们写增删改查的dao方法,这样就可以使用框架自带的简单的增删改查方法
对象导航查询由于会导致一些问题,我们稍后再说
serviceimpl层代码

	@Override
	public void save(Customer customer) {
		customerDao.save(customer);
	}
//Optional框架对实体类通用的一种表示,通过泛型确定具体实体类的类型,通过.get方法可以获得具体查询到的实体对象
	@Override
	public Customer findById(Integer custId) {
		Optional<Customer> op = customerDao.findById(custId);
		if(op.isPresent()){
			return op.get();
		}
		return null;
		
	}

	@Override
	public void update(Customer customer) {
		customerDao.save(customer);
	}

	@Override
	public void delete(Integer custId) {
		Optional<Customer> op = customerDao.findById(custId);
		if(op.isPresent()){
			customerDao.delete(op.get());
		}
	}

	@Override
	public List<Customer> findAll() {
		return customerDao.findAll();
	}

springDataJpa的@Query注解自定义语句查询更改@Modifying

dao层

	/**
	 * 

Title: findAll

*

Description: 待条件查询

* @param custName * @param custAddress * @return */
@Query("from Customer where custName = ?1 and custAddress like ?2") List<Customer> findAll(String custName, String custAddress); /** *

Title: findAllByNative

*

Description:本地查询

* @param custName * @param custAddress * @return * 注意本地查询需要开启。默认是关闭,不开启则查询失败nativeQuery=true */
@Query(value="select * from cst_customer where cust_name = ?1 and cust_address like ?2",nativeQuery=true) List<Customer> findAllByNative(String custName, String custAddress); /** *

Title: update

*

Description:自定义更新

* @param custName * @param custAddress * @param custId */
@Query("update Customer set custName = ?1,custAddress = ?2 where custId = ?3") @Modifying void update(String custName, String custAddress, Integer custId); /** *

Title: findByCustNameAndCustAddressLike

*

Description:

* @param custName * @param custAddress * @return * 注意:约定大于配置的思想 */
List<Customer> findByCustNameAndCustAddressLike(String custName, String custAddress);

serviceimpl

	@Override
	public List<Customer> findAll(String custName, String custAddress) {
		return customerDao.findAll(custName,custAddress);
		
	}
	@Override
	public List<Customer> findAllByNative(String custName, String custAddress) {
		// TODO Auto-generated method stub
		return customerDao.findAllByNative(custName,custAddress);
	}

	@Override
	public void update(String custName, String custAddress, Integer custId) {
		customerDao.update(custName,custAddress,custId);
		
	}

	@Override
	public List<Customer> findByNameAndAddress(String custName, String custAddress) {
		return customerDao.findByCustNameAndCustAddressLike(custName,custAddress);
	}

SpringDataJpa的Specification对象的应用

无需编写dao接口,只需给其继承JpaSpecificationExecutor< Customer >接口即可
serviceimpl

@Override
	public List<Customer> findAll(Specification<Customer> spec) {
		// TODO Auto-generated method stub
		return customerDao.findAll(spec);
	}

	@Override
	public Page<Customer> findAllByPage(Specification<Customer> spec,Pageable pageable) {
		// TODO Auto-generated method stub
		return customerDao.findAll(spec, pageable);
	}

web层调用方法的时候有些不一样

@Test
	public void test(){
		Specification<Customer> spec = new Specification<Customer>() {
			
			@Override
			// 动态拼接查询条件
			public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate p = cb.and(cb.equal(root.get("custName"), "修正药业"),cb.like(root.get("custAddress"), "%北%"));
				return p;
			}
		};
		List<Customer> list = customerService.findAll(spec);
		for(Customer l:list){
			System.out.println(l);
		}
	}
	
	/**
	 * 

Title: test1

*

Description: Specification分页查询

*/
@Test public void test1(){ Specification<Customer> spec = new Specification<Customer>() { @Override // 动态拼接查询条件,如果不需要条件查询所有,直接返回null就可以了 public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate p = cb.and(cb.equal(root.get("custName"), "修正药业"),cb.like(root.get("custAddress"), "%北%")); return null; } }; // 创建Pageable对象 Pageable pageable = PageRequest.of(2, 3); Page<Customer> page = customerService.findAllByPage(spec, pageable); List<Customer> list = page.getContent(); for(Customer l:list){ System.out.println(l); } }

对象导航查询

	/**
	 * 

Title: test4

*

Description:对象导航查询

*/
@Test public void test4(){ Customer c = customerService.findById(2); Set<LinkMan> linkMams = c.getLinkMams(); System.out.println(linkMams); }

在进行对象导航查询的时候,由于一对多关系默认情况下,由一的一方导航查询多的一方,默认使用懒加载,由于spring整合远古,对象的创建和事物都交给了ioc容器,我们无法控制,当查询完毕之后由于没有使用linkMams,所以并没有进行查询。当查询结束事物关闭session也就跟着关闭了,当调用c.getLinkMams();方法的时候,会直接查数据库,而这个时候session已经关闭了,因此会出现nosession的问题。如果想解决这个问题就必须在filter配置事物,这时候需要框架给我们提供的一个过滤器OpenEntityManagerInViewFilter通过这个过滤器,我们可以实现事物在过滤器中控制,就可以避免nosession问题

你可能感兴趣的:(SpringDataJpa的与Spring整合和基本查询语句(nosession问题))