<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>
<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>
只需要将dao接口继承JpaRepository
对象导航查询由于会导致一些问题,我们稍后再说
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();
}
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);
}
无需编写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问题