zoukankan      html  css  js  c++  java
  • jpa/springdata(2)springdata

    1.这里只说与jpa配合使用的部分

    2.配置文件

    <?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: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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
    		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
    	<!-- 配置自动扫描的包 -->
    	<context:component-scan base-package="springdata"></context:component-scan>
    
    	<!-- 1. 配置数据源 -->
    	<context:property-placeholder location="classpath:db.properties"/>
    
    	<bean id="dataSource"
    		class="com.mchange.v2.c3p0.ComboPooledDataSource">
    		<property name="user" value="${jdbc.user}"></property>
    		<property name="password" value="${jdbc.password}"></property>	
    		<property name="driverClass" value="${jdbc.driverClass}"></property>
    		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    		
    		<!-- 配置其他属性 -->
    	</bean>
    
    	<!-- 2. 配置 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"></bean>
    		</property>
    		<property name="packagesToScan" value="springdata"></property>
    		<property name="jpaProperties">
    			<props>
    				<!-- 二级缓存相关 -->
    				<!--  
    				<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
    				<prop key="net.sf.ehcache.configurationResourceName">ehcache-hibernate.xml</prop>
    				-->
    				<!-- 生成的数据表的列的映射策略 -->
    				<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
    				<!-- hibernate 基本属性 -->
    				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
    				<prop key="hibernate.show_sql">true</prop>
    				<prop key="hibernate.format_sql">true</prop>
    				<prop key="hibernate.hbm2ddl.auto">update</prop>
    			</props>
    		</property>
    	</bean>
    
    	<!-- 配置事务管理器 -->
    	<bean id="transactionManager"
    		class="org.springframework.orm.jpa.JpaTransactionManager">
    		<property name="entityManagerFactory" ref="entityManagerFactory"></property>	
    	</bean>
    
    	<!-- 配置支持注解的事务 -->
    	<tx:annotation-driven transaction-manager="transactionManager"/>
    
             <!-- 配置 以上配置就是spring与jpa的整合-->
    	
           <!-- 配置 SpringData -->
    	<!-- 加入  jpa 的命名空间 -->
    	<!-- base-package: 扫描 Repository Bean 所在的 package -->
    	<jpa:repositories base-package="springdata"
    		entity-manager-factory-ref="entityManagerFactory"
                  ></jpa:repositories>
    
    </beans>                
    
    @RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)//或者继承Repository(Person,Integer)接口,Person实体类类型,Integer主键类型
    public interface PersonRepository {
        Person getBylastName(String  str);/*getBy相应的表示get   lastName表示数据库的名称(这里的配置使用了_的策略,变成last_name),在@RepositoryDefinition定义的方法需要满足一定的规范,
    否则会报错,多个参数类似object...,find/read/get by 都表示查询的意思*/
      java.util.List<Person> getBylastNameLike(String str);/*这的方法名可以连着写*/ }
         @org.junit.Test
    	public  void   testRepository(){
    		PersonRepository bean = ctx.getBean(PersonRepository.class);
    		Person bylastName = bean.getBylastName("john");
      		System.out.println(bylastName);
        }
    
        @org.junit.Test
    	public  void   testLike(){
    		PersonRepository bean = ctx.getBean(PersonRepository.class);
    		List<Person> bylastNameLike = bean.getBylastNameLike("%john%");
    		System.out.println(bylastNameLike);
    	}
    

    方法需要满足的规范如下

    2.需要的jar

     3.注解

    1)@Query//在实现了这个注解之后就不会按照方法的方式去查询

    @Query("select p from  Person p   where  p.lastName  like  ?")/*添加注解后方法名会失效,写法类似hql或者jpql,但是多个参数在?的前提下需要如下表示参数序列1,单个可以不用标写,
    但是在设置参数的时候略有不同,在hibernate与jpa中使用的是creatquery(sql).setParameter(),在问号时key为1表示第1个?value表示对于的值,在使用:时,使用相同的键,但是在springdata的使用中
    略有不同,在springdata中?后面的1,2已经在sql中书写,所以可以不用写了,但是在使用:时,需要使用@param(键)来映射*/ java.util.List<Person> getBylastName(String str);

    @Query(value="select * from tbl_user where name like %?1" ,nativeQuery=true)//表示使用标准的sql语句,也可以按如下使用,更为方便

    @Query(value="select * from tbl_user where name like :lastName" ,nativeQuery=true)//写法类似hql或者jpql,但是不同在于,在jpa中

    @Query(value="select * from tbl_user where name like % :lastName%" ,nativeQuery=true)

    java.util.List<Person> getBylastNameLike(@param(“lastName”) String str)

    @Query(value="select * from tbl_user where name like % ?1%" ,nativeQuery=true)

    2)修改,需要在query上添加Modifying注解才表示修改(包括update与delete),必须开启事物(@Transactional,因为默认情况下springdata是一个只读的事物)。

     @Modifying
        @Query("UPDATE Person p SET p.email = :email WHERE id = :id")/*sql支持update和delete的书写方式,但是不支持insert的书写方式,delete的书写方式类同*/
        void updatePersonEmail(@Param("id") Integer id, @Param("email") String email);
    
    @Service
    public class PersonService {
    
    	@Autowired
    	private PersonRepsotory personRepsotory;
    	
    	@Transactional
    	public void updatePersonEmail(String email, Integer id){
    		personRepsotory.updatePersonEmail(id, email);
    	}
    }
    

     4.CrudRepository接口//Repository的子接口

    public interface PersonRepository   extends  CrudRepository<Person, Integer>//Person实体类,Integer主键,CrudRepository也有增删改查,用法基本一致,详情可以查看源码

    @Service
    public class PersonService {
    
    	@Autowired
    	private PersonRepsotory personRepsotory;
    	
    	@Transactional
    	public void savePersons(List<Person> persons){
    		personRepsotory.save(persons);//批量保存
    	}
    	
    }
    

    CrudRepository的方法

    save(T entity);//保存单个实体 

    save(Iterable<? extends T> entities);//保存集合       

    findOne(ID id);//根据id查找实体        

    boolean exists(ID id);//根据id判断实体是否存在        

    findAll();//查询所有实体,不用或慎用!        

    long count();//查询实体数量        

    void delete(ID id);//根据Id删除实体        

    void delete(T entity);//删除一个实体 

    void delete(Iterable<? extends T> entities);//删除一个实体的集合        

    void deleteAll();//删除所有实体,不用或慎用! 

     5.分页与排序

    public interface PersonRepository   extends  PagingAndSortingRepository<Person, Integer> 

    	@org.junit.Test
    	public  void   testLike2(){
    		PersonRepository bean = ctx.getBean(PersonRepository.class);
    		Order  order=new  Order(Direction.ASC, "id");
    		Sort  sort=new  Sort(order);
    		Pageable page =new  PageRequest(1, 2, sort);
    		Page<Person> findAll = bean.findAll(page);
    		System.out.println(findAll.getContent());//返回list
    		System.out.println(findAll.getSize());
              System.out.println(findAll.getTotalPages()); }

     PagingAndSortingRepository的方法

    findAll://查询所有排序或者分页查询排序

    6.JpaRepository接口//PagingAndSortingRepository的子类

    方法(基本看名字就能明白,就不做说明了)

     7.JpaSpecificationExecutor接口

    public interface PersonRepository   extends  JpaRepository<Person, Integer>,JpaSpecificationExecutor<Person>//必须继承JpaRepository,否则无法建立,因为需要PersonRepository bean = ctx.getBean(PersonRepository.class);

    @org.junit.Test
    	public  void   testLike3(){
    		PersonRepository bean = ctx.getBean(PersonRepository.class);
    		Order  order=new  Order(Direction.ASC, "id");
    		Sort  sort=new  Sort(order);
    		Pageable page =new  PageRequest(0, 2, sort);
    //		Specification<Person>  specification=(x,y,z)->{//老版本的eclipse对lambda表达的支持还是有限,这里报错
    //			Path<Integer> path = x.get("id");
    //			Predicate predicate = z.gt(path, 1);
    //			return predicate;
    //		};
    		Specification<Person>  specification=new  Specification<Person>() {
    			@Override
    			public Predicate toPredicate(Root<Person> x, CriteriaQuery<?> y, CriteriaBuilder z) {
    				Path<Integer> path = x.get("id");
    				Predicate predicate = z.gt(path, 1);
    				return predicate;
    			}
    		};
    		Page<Person> findAll = bean.findAll(specification, page);
    		System.out.println(findAll.getContent());
    	}
    

    8.自定义 Repository 方法(作用不大)

     public interface PersonRepository   extends  JpaRepository<Person, Integer>,PersonDao

    public class PersonRepsotoryImpl implements PersonDao {//需要是类名PersonRepository 的impl的样式,实际是在调用PersonDao接口中的方法时,调用的是PersonRepsotoryImpl中的方法(代理模式)
    	
    	@PersistenceContext
    	private EntityManager entityManager;
    	
    	@Override
    	public void test() {
    		Person person = entityManager.find(Person.class, 11);
    		System.out.println("-->" + person);
    	}
    
    }
    
    @org.junit.Test
    	public  void  test5(){
    		PersonRepository bean = ctx.getBean(PersonRepository.class);
    		System.out.println(bean);
    		bean.test();
    	}
    

     还可以是全局的Repository 方法,对所有的Repository都添加这个方法(基本不用)

  • 相关阅读:
    并发学习之:不使用内核对象同步的并发队列
    破解C#的readonly只读字段
    并发学习之:乱序执行和内存屏障
    并发学习之:缓存一致性
    并发学习之:Keyed Events(没看懂,要调试下才能明白,伤心!)
    静态和非静态的访问
    asc2码
    学习报告
    11号学习总结
    9号总结
  • 原文地址:https://www.cnblogs.com/gg128/p/9738033.html
Copyright © 2011-2022 走看看