個人理解
1种吸、定義一個xxxRepository繼承JpaRepository
2闷串、在定義的與數(shù)據(jù)庫對應(yīng)的類上加相應(yīng)的@NamedQuery方法
3窘拯、實現(xiàn)xxxxDaoImple,xxxxrepository和entityManager實現(xiàn)DaoImple中的具體方法瘩蚪,一般簡單的方法則用xxxxRepository類中的方法來實現(xiàn)
4就乓、xxxRepository只是相當(dāng)于把原來在dao層實現(xiàn)的簡單方法汉匙,他本身封裝起來了
javaConfig配置jpa
1、在LifeCircleWebConfig中@import (ApplicationConfig.class)就是引入jpa的配置到configuration的配置文件中去
2生蚁、配置ApplicationConfig類噩翠,它作為配置jpa的文件
圖中數(shù)字解釋:
1、要掃描這個的包邦投,把這個包繼承與JpaRepository的類都裝到容器中成為一個bean
2绎秒、指定他的工廠類
3、導(dǎo)入xml文件尼摹,為后面的datasource的配置引入數(shù)據(jù)
4见芹、引入InfrastructureConfig,和InfrastructureConfig4Question類蠢涝,在這兩個類中主要是配置
entityManagerFactory
和transactionManager
和defaultJdbcTemplate
3玄呛、在MyRepositoryFactoryBean中如何引入代理的ProxyRepositoryImpl來實現(xiàn)的
(1)MyRepositoryFactoryBean在這定義一個內(nèi)部成員類MyRepositoryFactory,這個類繼承與
JpaRepositoryFactory和二,在這個類的構(gòu)造方法中徘铝,把TransactionTemplate,JdbcTemplate惯吕,EntityManager等值給他惕它,與數(shù)據(jù)庫建立連接
(2)編寫getTargetRepository方法,告訴程序要返回的是ProxyRepositoryImpl废登,及所有的實現(xiàn)都是代理來做的淹魄,代理類中保存有具體的Repository
(3)編寫getRepositoryBaseClass方法,獲取baseclass
(4)MyRepositoryFactoryBean實現(xiàn)方法createRepositoryFactory方法堡距,返回MyRepositoryFactory工廠類
通過上面操作實現(xiàn)了指定Repository的工廠類甲锡。
xml和javaconfig配置jpa的區(qū)別參考
數(shù)字對照
在InfrastructureConfig中
在ApplicationConfig
在InfrastructureConfig中
在InfrastructureConfig中
還是有些地方不清楚有時間在仔細(xì)看下,自己配置下
jpa配置自定義方法的
1.根據(jù)方法名稱
2.JPA的NameQueryies
注意命名的時要遵循DomainClass.methodName()的命名規(guī)則
(1):在實體類上使用@NamedQuery羽戒,示例如下:
@NamedQuery(name = "UserModel.findByAge",query = "select o from UserModel o where o.age >= ?1")
(2):在自己實現(xiàn)的DAO的Repository接口里面定義一個同名的方法缤沦,示例如下:
public List<UserModel> findByAge(int age);
(3):然后就可以使用了,Spring會先找是否有同名的NamedQuery易稠,如果有缸废,那么就不會按照接口定義的方法來解析。
3.@Query方式
在接口的方法上加注解,@Query 注解的使用非常簡單企量,只需在聲明的方法上面標(biāo)注該注解测萎,在變量上加上@Param("nn"),并且在sql語句中采用:nn來注入?yún)?shù)
@Query(value="select o from UserModel o where o.name like %:nn")
public List<UserModel> findByUuidOrAge(@Param("nn") String name);
多表查找的時候jpa怎么做
就和平常寫sql語句一樣梁钾,只是table名稱變?yōu)橐粋€個與數(shù)據(jù)庫表關(guān)聯(lián)的
項目中怎么使用的
1绳泉、把所有的Repository的bean放到commonServiceHelper類中的map對象中逊抡,map的key是resType姆泻,使用的時候通過resType獲得相對應(yīng)的Repository
2、在包repository--sdk下找AssetRepository冒嫡,繼承了JpaRepository
3拇勃、增加的方法寫在Asset實體類通過JPA的NameQueryies方式
但是沒得參數(shù)注入,都是where后面直接寫參數(shù)的
4孝凌、具體的使用可參考AssetDaoImpl
先過去EntityManage方咆,直接createNamedQuery獲取Query,再對參數(shù)設(shè)置相應(yīng)的值query.setParameter("category", category);
再運行得值
5蟀架、sql中占位符
JpaRepository常用方法
T save(T entity);//保存單個實體
Iterable<T> save(Iterable<? extends T> entities);//保存集合
T findOne(ID id);//根據(jù)id查找實體
boolean exists(ID id);//根據(jù)id判斷實體是否存在
Iterable<T> findAll();//查詢所有實體,不用或慎用!
long count();//查詢實體數(shù)量
void delete(ID id);//根據(jù)Id刪除實體
void delete(T entity);//刪除一個實體
void delete(Iterable<? extends T> entities);//刪除一個實體的集合
void deleteAll();//刪除所有實體,不用或慎用!
項目中給他封裝為
public T add(T bean)保存
public void del(String id)
public T update(T bean)
public T getByExample(T entity)
public List<T> getAllByExample(T entity)
education = (Education) resourceRepository.add(education);
education = (Education) resourceRepository.update(education)瓣赂;
parentAsset = assetRepository.get(parent);//判斷資源是否存在
獲取這個repository對應(yīng)的entityManager對象public EntityManager getEntityManager()
項目代碼參考
用createNamedQuery
public Chapter getLastChapterOnSameLevel(String mid, String parent) {
Chapter lastOne = null;
Query query = chapterRepository.getEntityManager().createNamedQuery("getLastChapterOnSameLevel");
query.setParameter("tmid", mid);
query.setParameter("pid", parent);
query.setFirstResult(0); //表示的是從查詢記錄的地幾個開始,而不是從第幾頁開始
query.setMaxResults(1); //最多查詢出幾條
List<Chapter> result = query.getResultList();
if(CollectionUtils.isNotEmpty(result)){
lastOne = result.get(0);
}
return lastOne;
}
用em.createNativeQuery
public List<KnowledgeBaseModel> queryKnowledgeBaseListByKpid(String kpid) {
List<KnowledgeBaseModel> returnList = new ArrayList<KnowledgeBaseModel>();
String sql = "SELECT kb.identifier,kb.knid,kb.kpid,nd.title,nd.description,nd.creator,nd.create_time,cd1.title as kcname,cd2.title as kpname FROM knowledge_base kb,ndresource nd,category_relations cr,category_datas cd1,category_datas cd2 where cr.source=cd1.identifier and cr.target = cd2.identifier and cr.source=:kpid and kb.kpid = cr.target and nd.primary_category = 'knowledges' and nd.enable = 1 and kb.knid = nd.identifier";
Query query = em.createNativeQuery(sql);
query.setParameter("kpid", kpid);
List<Object[]> list = query.getResultList();
if(CollectionUtils.isNotEmpty(list)){
for (Object[] o : list) {
KnowledgeBaseModel kbm = new KnowledgeBaseModel();
kbm.setIdentifier((String)o[0]);
kbm.setKnid((String)o[1]);
kbm.setKpid((String)o[2]);
kbm.setTitle((String)o[3]);
kbm.setDescription((String)o[4]);
kbm.setCreator((String)o[5]);
if(o[6] != null){
kbm.setCreateTime(new Date(((BigInteger)o[6]).longValue()));
}
kbm.setKcName((String)o[7]);
kbm.setKpName((String)o[8]);
returnList.add(kbm);
}
}
return returnList;
}
也有使用@Query方式的
public interface ResourceRelationRepository extends ResourceRepository<ResourceRelation>,
JpaRepository<ResourceRelation, String> {
@Query("SELECT DISTINCT(p.target) FROM ResourceRelation p where p.sourceUuid in (?1) AND p.resourceTargetType=?2 AND relationType = ?3")
List<String> findTargetIdsBySourceIdsAndTargetType(List<String> sourceIds,String targetType,String relationType);
@Query("SELECT DISTINCT(p.sourceUuid) FROM ResourceRelation p where p.target in (?1) AND p.resType=?2 AND relationType = ?3")
List<String> findSourceIdsByTargetIdsAndResType(List<String> targetIds,String resType,String relationType);
@Query("SELECT t1 FROM ResourceRelation t1 where t1.resType=?1 and t1.resourceTargetType=?2 and t1.enable=1 and EXISTS(select 1 from Education t2 where t1.sourceUuid=t2.identifier and t2.enable=1) and EXISTS(select 1 from Education t2 where t1.target=t2.identifier and t2.enable=1) and t1.target=?3 ")
List<ResourceRelation> findByResTypeAndTargetTypeAndTargetId(String resType, String targetType, String targetId);
@Query("SELECT t1 FROM ResourceRelation t1 where t1.resType=?1 and t1.resourceTargetType=?2 and t1.enable=1 and EXISTS(select 1 from Education t2 where t1.sourceUuid=t2.identifier and t2.enable=1) and EXISTS(select 1 from Education t2 where t1.target=t2.identifier and t2.enable=1) and t1.sourceUuid=?3 ")
List<ResourceRelation> findByResTypeAndTargetTypeAndSourceId(String resType, String targetType, String sourceId);