1. 程式人生 > >jpa/springdata(1)springdata

jpa/springdata(1)springdata

improve vendor div .config 增刪改查 idc man 包括 drive

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都添加這個方法(基本不用)

jpa/springdata(1)springdata