摘要:時間年月日星期一說明本文部分內容均來自慕課網。慕課網教學示例源碼個人學習源碼第一章課程介紹課程介紹什么是主旨提供一個熟悉的一致的,基于框架的數據訪問框架。
時間:2017年04月24日星期一
說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com
教學示例源碼:https://github.com/zccodere/s...
個人學習源碼:https://github.com/zccodere/s...
什么是Spring Data
主旨:提供一個熟悉的、一致的,基于Spring框架的數據訪問框架。 簡化數據庫的訪問。 歷史:2010年提出,作者Rod Johnso,Spring Source項目 網址:http://projects.spring.io/spring-data/#quick-start
Spring Data概覽
Spring Data包含多個子項目
Spring Data JPA Spring Data Mongo DB Spring Data Redis Spring Data Solr
課程安排
傳統方式訪問數據庫 Spring Data快速起步 Spring Data JPA進階 Spring Data JPA高級第二章:使用傳統方式訪問數據庫 2-1 使用傳統方式訪問數據庫
傳統方式訪問數據庫
JDBC Spring JdbcTemplate 弊端分析2-2 準備工作
JDBC
Connection Statement ResultSet Test Case
搭建開發環境
創建maven項目 添加數據庫驅動和單元測試依賴 數據庫表的準備,使用mysql數據庫
創建一個Java項目,POM文件如下:
4.0.0 com.zccoder myspringdata 1.0-SNAPSHOT UTF-8 org.springframework spring-jdbc 4.3.6.RELEASE org.springframework spring-context 4.3.6.RELEASE org.springframework.data spring-data-jpa 1.11.3.RELEASE org.hibernate hibernate-entitymanager 5.2.10.Final mysql mysql-connector-java 5.1.38 junit junit 4.10 test
完成后的項目結構圖:
2-3 JDBCUtil開發開發JDBCUtil工具類
獲取Connection,關閉Connection、Statement、ResultSet 注意事項:配置的屬性放置配置文件中,然后通過代碼的方式將配置文件中的數據加載進來即可。
代碼示例:
package com.myimooc.springdata.jdbc.util; import java.io.InputStream; import java.sql.*; import java.util.Properties; /** * JDBC工具類: * 1)獲取Connection * 2)釋放資源 * Created by ZC on 2017/4/24. */ public class JDBCUtils { /** * 獲取Connection * @return 所獲得到的JDBC的Connection */ public static Connection getConnection() throws Exception{ /** * 不建議大家把配置硬編碼到代碼中 * 最佳實踐:配置性的建議寫到配置文件中 * */ // String url = "jdbc:mysql:///springdata"; // String username = "root"; // String password = "root"; // String dirverClass = "com.mysql.jdbc.Driver"; InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties"); Properties properties = new Properties(); properties.load(inputStream); String url = properties.getProperty("jdbc.url"); String username = properties.getProperty("jdbc.username"); String password = properties.getProperty("jdbc.password"); String driverClass = properties.getProperty("jdbc.driverClass"); Class.forName(driverClass); Connection connection = DriverManager.getConnection(url,username,password); return connection; } /** * 釋放DB相關資源 * @param resultSet * @param statement * @param connection */ public static void release(ResultSet resultSet, Statement statement,Connection connection){ if(resultSet != null ){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if(statement != null ){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(connection != null ){ try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }2-4 Dao開發
建立對象模型及DAO層開發。
代碼演示:
1、對象模型
package com.myimooc.springdata.jdbc.domain; /** * Student實體類 * Created by ZC on 2017/4/24. */ public class Student { /** 主鍵ID */ private Integer id; /** 姓名 */ private String name; /** 年齡 */ private int age; @Override public String toString() { return "Student{" + "id=" + id + ", name="" + name + """ + ", age=" + age + "}"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
2、DAO接口
package com.myimooc.springdata.jdbc.dao; import com.myimooc.springdata.jdbc.domain.Student; import java.util.List; /** * StudentDAO訪問接口 * Created by ZC on 2017/4/24. */ public interface StudentDao { /** * 獲取所有學生 * @return 所有學生 */ ListlistStudent(); /** * 添加一個學生 * @param student 待添加的學生 */ void saveStudent(Student student); }
3、DAO實現
package com.myimooc.springdata.jdbc.dao.impl; import com.myimooc.springdata.jdbc.dao.StudentDao; import com.myimooc.springdata.jdbc.domain.Student; import com.myimooc.springdata.jdbc.util.JDBCUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; /** * StudentDAO訪問接口實現類:通過最原始的JDBC的方式操作 * Created by ZC on 2017/4/24. */ public class StudentDaoImpl implements StudentDao { public ListlistStudent() { List studentList = new ArrayList (); Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; String sql = "select id,name,age from student"; try { connection = JDBCUtils.getConnection(); preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); while(resultSet.next()){ Integer id = resultSet.getInt("id"); String name = resultSet.getString("name"); Integer age = resultSet.getInt("age"); Student student = new Student(); student.setId(id); student.setName(name); student.setAge(age); studentList.add(student); } } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.release(resultSet,preparedStatement,connection); } return studentList; } public void saveStudent(Student student) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; String sql = "insert into student(name,age) values(?,?)"; try { connection = JDBCUtils.getConnection(); preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1,student.getName()); preparedStatement.setInt(2,student.getAge()); preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.release(resultSet,preparedStatement,connection); } } }
4、單元測試
package com.myimooc.springdata.jdbc.dao; import com.myimooc.springdata.jdbc.dao.impl.StudentDaoImpl; import com.myimooc.springdata.jdbc.domain.Student; import org.junit.Test; import java.util.List; /** * StudentDao 單元測試類 * Created by ZC on 2017/4/24. */ public class StudentDaoImplTest { @Test public void listStudentTest(){ StudentDao studentDao = new StudentDaoImpl(); List2-5 使用JdbcTemplatestudentList = studentDao.listStudent(); for(Student student : studentList){ System.out.println(student.toString()); } } @Test public void saveStudentTest(){ StudentDao studentDao = new StudentDaoImpl(); Student student = new Student(); student.setName("test"); student.setAge(30); studentDao.saveStudent(student); } }
Spring JdbcTemplate
添加maven依賴 DataSource & JdbcTemplate注入 Test Case
代碼演示:
1、創建DB配置文件
jdbc.url = jdbc:mysql:///springdata jdbc.username = root jdbc.password = root jdbc.driverClass = com.mysql.jdbc.Driver
2、創建配置文件類
package com.myimooc.springdata.jdbctemplate.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.ImportResource; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * 配置參數類 * Created by ZC on 2017/4/24. */ @PropertySource(value="classpath:db.properties") @Component public class Properties { @Value("${jdbc.driverClass}") private String jdbcDriverClass; @Value("${jdbc.url}") private String jdbcUrl; @Value("${jdbc.username}") private String jdbcUser; @Value("${jdbc.password}") private String jdbcPassword; @Override public String toString() { return "Properties{" + "jdbcDriverClass="" + jdbcDriverClass + """ + ", jdbcUrl="" + jdbcUrl + """ + ", jdbcUser="" + jdbcUser + """ + ", jdbcPassword="" + jdbcPassword + """ + "}"; } public String getJdbcDriverClass() { return jdbcDriverClass; } public String getJdbcUrl() { return jdbcUrl; } public String getJdbcUser() { return jdbcUser; } public String getJdbcPassword() { return jdbcPassword; } }
3、配置DataSource、JdbcTemplate和Spring注解掃描
package com.myimooc.springdata.jdbctemplate.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; /** * Created by ZC on 2017/4/24. */ @Configuration @ComponentScan("com.myimooc.springdata.jdbctemplate") public class SpringConfig { @Autowired private Properties properties; @Bean DriverManagerDataSource getDriverManagerDataSource(){ DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); driverManagerDataSource.setDriverClassName(properties.getJdbcDriverClass()); driverManagerDataSource.setUrl(properties.getJdbcUrl()); driverManagerDataSource.setUsername(properties.getJdbcUser()); driverManagerDataSource.setPassword(properties.getJdbcPassword()); return driverManagerDataSource; } @Bean JdbcTemplate getJdbcTemplate(){ JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(getDriverManagerDataSource()); return jdbcTemplate; } }
4、編寫實體類
package com.myimooc.springdata.jdbctemplate.domain; /** * Student實體類 * Created by ZC on 2017/4/24. */ public class Student { /** 主鍵ID */ private Integer id; /** 姓名 */ private String name; /** 年齡 */ private int age; @Override public String toString() { return "Student{" + "id=" + id + ", name="" + name + """ + ", age=" + age + "}"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
5、DAO接口
package com.myimooc.springdata.jdbctemplate.dao; import com.myimooc.springdata.jdbctemplate.domain.Student; import java.util.List; /** * StudentDAO訪問接口 * Created by ZC on 2017/4/24. */ public interface StudentDao { /** * 獲取所有學生 * @return 所有學生 */ ListlistStudent(); /** * 添加一個學生 * @param student 待添加的學生 */ void saveStudent(Student student); }
6、DAO實現
package com.myimooc.springdata.jdbctemplate.dao.impl; import com.myimooc.springdata.jdbctemplate.dao.StudentDao; import com.myimooc.springdata.jdbctemplate.domain.Student; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * StudentDAO訪問接口實現類:通過 JdbcTemplate 的方式操作 * Created by ZC on 2017/4/24. */ @Repository public class StudentDaoImpl implements StudentDao { @Autowired private JdbcTemplate jdbcTemplate; public ListlistStudent() { List studentList = new ArrayList (); String sql = "select id, name, age from student"; List
7、單元測試類
package com.myimooc.springdata.jdbctemplate; import com.myimooc.springdata.jdbctemplate.config.SpringConfig; import com.myimooc.springdata.jdbctemplate.dao.StudentDao; import com.myimooc.springdata.jdbctemplate.domain.Student; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import javax.sql.DataSource; import java.util.List; /** * 使用 JdbcTemplate 實現 StudentDao 單元測試類 * Created by ZC on 2017/4/24. */ public class StudentDaoTest { private ApplicationContext ctx = null; private StudentDao studentDao; @Before public void init(){ ctx = new AnnotationConfigApplicationContext(SpringConfig.class); studentDao = ctx.getBean(StudentDao.class); } @After public void destroy(){ ctx = null; } @Test public void listStudentTest(){ List2-6 弊端分析studentList = studentDao.listStudent(); for (Student student : studentList){ System.out.println(student.toString()); } } @Test public void saveTest(){ Student student = new Student(); student.setName("test-spring-jdbcTemplate"); student.setAge(25); studentDao.saveStudent(student); } }
弊端分析
DAO里面代碼量太多 DAO的實現有很多重復代碼 開發分頁和其它功能,需要重新進行封裝第三章:Spring Data快速入門 3-1 開發環境搭建
Spring Data JPA快速起步
開發環境搭建 Spring Data JPA HelloWorld開發
代碼演示:
1、創建DB配置文件
jdbc.url = jdbc:mysql:///springdata jdbc.username = root jdbc.password = root jdbc.driverClass = com.mysql.jdbc.Driver
2、創建配置文件類
package com.myimooc.springdata.jpa.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * Created by ZC on 2017/4/24. */ @PropertySource(value="classpath:db.properties") @Component public class PropertiesConfig { @Value("${jdbc.driverClass}") private String jdbcDriverClass; @Value("${jdbc.url}") private String jdbcUrl; @Value("${jdbc.username}") private String jdbcUser; @Value("${jdbc.password}") private String jdbcPassword; @Override public String toString() { return "Properties{" + "jdbcDriverClass="" + jdbcDriverClass + """ + ", jdbcUrl="" + jdbcUrl + """ + ", jdbcUser="" + jdbcUser + """ + ", jdbcPassword="" + jdbcPassword + """ + "}"; } public String getJdbcDriverClass() { return jdbcDriverClass; } public String getJdbcUrl() { return jdbcUrl; } public String getJdbcUser() { return jdbcUser; } public String getJdbcPassword() { return jdbcPassword; } }
3、配置TransactionManager、EntityManagerFactory和Spring自動掃描注入
package com.myimooc.springdata.jpa.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import java.util.Properties; /** * Spring配置類 * Created by ZC on 2017/4/24. */ // 聲明為配置類 @Configuration // 啟用事務管理 @EnableTransactionManagement // 啟用自動掃描繼承 JpaRepository 接口的類。 // 注意,此注解需要配置 entityManagerFactory 和 transactionManager // 方式一:定義獲取Bean方法名為 entityManagerFactory 和 transactionManager // 方式二:配置 @EnableJpaRepositories注解的 entityManagerFactoryRef 屬性 為自定義獲取Bean的方法名。 @EnableJpaRepositories(basePackages = "com.myimooc.springdata.jpa") // 啟用自動掃描 @Component 注解的Bean @ComponentScan(basePackages = "com.myimooc.springdata.jpa") public class SpringConfig{ @Autowired private PropertiesConfig propertiesConfig; /** * 配置數據源 * @return */ @Bean public DriverManagerDataSource dataSource(){ DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); driverManagerDataSource.setDriverClassName(propertiesConfig.getJdbcDriverClass()); driverManagerDataSource.setUrl(propertiesConfig.getJdbcUrl()); driverManagerDataSource.setUsername(propertiesConfig.getJdbcUser()); driverManagerDataSource.setPassword(propertiesConfig.getJdbcPassword()); return driverManagerDataSource; } /** * 配置事務管理器 JpaTransactionManager * @return */ @Bean(name="transactionManager") public PlatformTransactionManager transactionManager(){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setDataSource(this.dataSource()); transactionManager.setEntityManagerFactory(this.entityManagerFactory().getObject()); return transactionManager; // return new DataSourceTransactionManager(this.dataSource()); // return new JpaTransactionManager(this.entityManagerFactory().getObject()); } /** * 配置JPA的 EntityManagerFactory * @return */ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setDataSource(dataSource()); HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(true); jpaVendorAdapter.setDatabase(Database.MYSQL); entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter); entityManagerFactory.setPackagesToScan("com.myimooc.springdata.jpa"); Properties jpaProperties = new Properties(); // jpaProperties.setProperty("hibernate.ejb.naming_strategy","org.hibernate.cfg.ImprovedNamingStrategy"); jpaProperties.setProperty("hibernate.dialect","org.hibernate.dialect.MySQL5InnoDBDialect"); jpaProperties.setProperty("hibernate.show_sql","true"); jpaProperties.setProperty("hibernate.format_sql","true"); jpaProperties.setProperty("hibernate.hbm2ddl.auto","update"); entityManagerFactory.setJpaProperties(jpaProperties); return entityManagerFactory; } }
4、編寫實體類:Employee
package com.myimooc.springdata.jpa.domain; import javax.persistence.*; /** * 雇員:先開發實體類,然后自動生成實體表 * Created by ZC on 2017/4/24. */ @Entity @Table(name = "test_employee") public class Employee { @Id @GeneratedValue private Integer id; @Column(length = 20) private String name; private Integer age; @Override public String toString() { return "Employee{" + "id=" + id + ", name="" + name + """ + ", age=" + age + "}"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }3-2 起步程序開發
代碼演示:
1、編寫EmployeeRepository接口
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.domain.Employee; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * 使用 Repository 接口 * Created by ZC on 2017/4/25. */ // 方式二:使用 @RepositoryDefinition 注解 // @RepositoryDefinition(domainClass = Employee.class,idClass = Integer.class) public interface EmployeeRepository extends Repository{//方式一:繼承 Repository 接口 /** * 獲取雇員對象通過名稱 * @param name * @return */ Employee findByName(String name); }
2、編寫單元測試類:EmployeeRepositoryTest
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.config.SpringConfig; import com.myimooc.springdata.jpa.domain.Employee; import com.myimooc.springdata.jpa.repository.EmployeeRepository; import com.myimooc.springdata.jpa.service.EmployeeService; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import java.util.ArrayList; import java.util.List; /** * EmployeeRepository單元測試類 * Created by ZC on 2017/4/24. */ public class EmployeeRepositoryTest { private ApplicationContext ctx = null; private EmployeeRepository employeeRepository = null; @Before public void init(){ ctx = new AnnotationConfigApplicationContext(SpringConfig.class); employeeRepository = ctx.getBean(EmployeeRepository.class); } @After public void destroy(){ ctx = null; } @Test public void entityManageFactoryTest(){ LocalContainerEntityManagerFactoryBean entityManagerFactory = (LocalContainerEntityManagerFactoryBean)ctx.getBean(LocalContainerEntityManagerFactoryBean.class); Assert.assertNotNull(entityManagerFactory); } @Test public void findByNameTest(){ System.out.println(employeeRepository); Employee employee = employeeRepository.findByName("cc"); if( null == employee){ System.out.println("查詢數據為空"); }else{ System.out.println(employee.toString()); } } }
Repository
Repository:Spring Data核心類 RepositoryDefinition:使用該注解進行配置 Repository Query Specification:查詢時,方法命名不能亂寫 Query Annotation:使用該注解,可以實現原生SQL查詢 Update/Delete/Transaction:更新、刪除操作,支持事務
Repository Hierarchy
CrudRepository:內置了新增、更新、刪除、查詢方法 PagingAndSortingRespository:分頁和排序 JpaRepository JpaSpecificationExcutor第四章:Spring Data JPA進階 4-1 關于Repository接口
Repository接口詳解
Repository接口是Spring Data的核心接口,不提供任何方法 public interface Repository{} @RepositoryDefinition注解的使用
Repository類的定義:
1)Repository是一個空接口,標記接口。沒有包含方法聲明的接口 2)如果我們定義的接口EmployeeRepository extends Repository,會被Spring管理。 如果我們自己的接口沒有extends Repository,運行時會報錯,沒有這個Bean。4-2 Repository子接口詳解
Repository子接口詳解
CrudRepository:繼承Repository,實現了CRUD相關的方法 PagingAndSortingRepository:繼承CrudRepository,實現了分頁排序相關的方法 JpaRepository:繼承PagingAndSortingRepositor,實現JPA規范相關的方法4-3 查詢方法定義規則和使用
Repository中查詢方法定義規則和使用
了解Spring Data中查詢方法名稱的定義規則 使用Spring Data完成復雜查詢方法名稱的命名
查詢方法定義規則
代碼演示:
1、在EmployeeRepository接口編寫以下代碼
// 使用JPA規范查詢 // where name like ?% and age < ? ListfindByNameStartingWithAndAgeLessThan(String name,Integer age); // where name like %? and age < ? List findByNameEndingWithAndAgeLessThan(String name,Integer age); // where name in (?,?...) or age < ? List findByNameInOrAgeLessThan(List name,Integer age); // where name in (?,?...) and age < ? List findByNameInAndAgeLessThan(List name,Integer age);
2、在EmployeeRepositoryTest單元測試類進行測試
@Test public void findByNameStartingWithAndAgeLessThanTest(){ System.out.println(employeeRepository); Listemployees = employeeRepository.findByNameStartingWithAndAgeLessThan("test",22); if( null != employees){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } } @Test public void findByNameEndingWithAndAgeLessThanTest(){ System.out.println(employeeRepository); List employees = employeeRepository.findByNameEndingWithAndAgeLessThan("6",23); if( null != employees && employees.size() > 0){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } } @Test public void findByNameInOrAgeLessThanTest(){ List names = new ArrayList (); names.add("test1"); names.add("test2"); names.add("test3"); List employees = employeeRepository.findByNameInOrAgeLessThan(names,22); if( null != employees && employees.size() > 0){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } } @Test public void findByNameInAndAgeLessThanTest(){ List names = new ArrayList (); names.add("test1"); names.add("test2"); names.add("test3"); List employees = employeeRepository.findByNameInAndAgeLessThan(names,22); if( null != employees && employees.size() > 0){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } }
對于按照方法命名規則來使用的話,有弊端:
1)方法名比較長:約定大于配置 2)對于一些復雜的查詢,是很難實現。
使用@Query注解來解決。
4-4 Query注解使用Query注解使用
在Respository方法中使用,不需要遵循查詢方法命令規則 只需要將@Query定義在Respository中的方法之上即可 命名參數及索引參數的使用 本地查詢
代碼演示:
1、在EmployeeRepository接口編寫以下代碼
// 使用@Query注解查詢 /** * 自定義查詢SQL * */ @Query("select o from Employee o where id=(select max(id) from Employee t1)") Employee getEmployeeByMaxId(); /** * 使用占位符進行參數綁定 * */ @Query("select o from Employee o where o.name=?1 and o.age=?2") ListlistEmployeeByNameAndAge(String name, Integer age); /** * 使用命名參數進行參數綁定 * */ @Query("select o from Employee o where o.name=:name and o.age=:age") List listEmployeeByNameAndAge2(@Param("name") String name, @Param("age")Integer age); /** * 自定義查詢SQL,like,占位符進行參數綁定 * */ @Query("select o from Employee o where o.name like %?1%") List listEmployeeByLikeName(String name); /** * 自定義查詢SQL,like,命名參數進行參數綁定 * */ @Query("select o from Employee o where o.name like %:name%") List listEmployeeByLikeName2(@Param("name") String name); /** * 使用原生態SQL查詢 * @return */ @Query(nativeQuery = true,value = "select count(1) from employee") long getCount();
2、在EmployeeRepositoryTest單元測試類進行測試
// 使用 @Query 注解查詢 @Test public void getEmployeeByMaxIdTest(){ Employee employee = employeeRepository.getEmployeeByMaxId(); if( null != employee ){ System.out.println(employee.toString()); }else{ System.out.println("查詢數據為空"); } } @Test public void listEmployeeByNameAndAgeTest(){ List4-5 更新操作整合事務使用employees = employeeRepository.listEmployeeByNameAndAge("zhangsan",20); if( null != employees && employees.size() > 0){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } } @Test public void listEmployeeByNameAndAge2Test(){ List employees = employeeRepository.listEmployeeByNameAndAge2("zhangsan",20); if( null != employees && employees.size() > 0){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } } @Test public void listEmployeeByLikeNameTest(){ List employees = employeeRepository.listEmployeeByLikeName("test1"); if( null != employees && employees.size() > 0){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } } @Test public void listEmployeeByLikeName2Test(){ List employees = employeeRepository.listEmployeeByLikeName2("test"); if( null != employees && employees.size() > 0){ for (Employee employee : employees) { System.out.println(employee.toString()); } }else{ System.out.println("查詢數據為空"); } } @Test public void getCountTest(){ long count = employeeRepository.getCount(); System.out.println(count); }
更新及刪除操作整合事務的使用
@Modifying注解使用 @Modifying結合@Query注解執行更新操作 @Transaction在Spring Data中的使用
事務在Spring data中的使用:
1)事務一般是在Service層 2)@Query、@Modifying、@Transaction的綜合使用
代碼演示:
1、基于javaconfig在SpringConfig類進行事務配置
package com.myimooc.springdata.jpa.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import java.util.Properties; /** * Spring配置類 * Created by ZC on 2017/4/24. */ // 聲明為配置類 @Configuration // 啟用事務管理 @EnableTransactionManagement // 啟用自動掃描繼承 JpaRepository 接口的類。 // 注意,此注解需要配置 entityManagerFactory 和 transactionManager // 方式一:定義獲取Bean方法名為 entityManagerFactory 和 transactionManager // 方式二:配置 @EnableJpaRepositories注解的 entityManagerFactoryRef 屬性 為自定義獲取Bean的方法名。 @EnableJpaRepositories(basePackages = "com.myimooc.springdata.jpa") // 啟用自動掃描 @Component 注解的Bean @ComponentScan(basePackages = "com.myimooc.springdata.jpa") public class SpringConfig{ @Autowired private PropertiesConfig propertiesConfig; /** * 配置數據源 * @return */ @Bean public DriverManagerDataSource dataSource(){ DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); driverManagerDataSource.setDriverClassName(propertiesConfig.getJdbcDriverClass()); driverManagerDataSource.setUrl(propertiesConfig.getJdbcUrl()); driverManagerDataSource.setUsername(propertiesConfig.getJdbcUser()); driverManagerDataSource.setPassword(propertiesConfig.getJdbcPassword()); return driverManagerDataSource; } /** * 配置事務管理器 JpaTransactionManager * @return */ @Bean(name="transactionManager") public PlatformTransactionManager transactionManager(){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setDataSource(this.dataSource()); transactionManager.setEntityManagerFactory(this.entityManagerFactory().getObject()); return transactionManager; // return new DataSourceTransactionManager(this.dataSource()); // return new JpaTransactionManager(this.entityManagerFactory().getObject()); } /** * 配置JPA的 EntityManagerFactory * @return */ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setDataSource(dataSource()); HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(true); jpaVendorAdapter.setDatabase(Database.MYSQL); entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter); entityManagerFactory.setPackagesToScan("com.myimooc.springdata.jpa"); Properties jpaProperties = new Properties(); // jpaProperties.setProperty("hibernate.ejb.naming_strategy","org.hibernate.cfg.ImprovedNamingStrategy"); jpaProperties.setProperty("hibernate.dialect","org.hibernate.dialect.MySQL5InnoDBDialect"); jpaProperties.setProperty("hibernate.show_sql","true"); jpaProperties.setProperty("hibernate.format_sql","true"); jpaProperties.setProperty("hibernate.hbm2ddl.auto","update"); entityManagerFactory.setJpaProperties(jpaProperties); return entityManagerFactory; } }
2、在EmployeeRepository接口編寫以下代碼
// 更新數據 @Transactional @Modifying @Query("update Employee o set o.age = :age where o.id = :id") void updateAgeById(@Param("id")Integer id,@Param("age")Integer age);
3、定義Service層,實際開發中,需要定義接口,這里為了演示方便,直接使用類。
package com.myimooc.springdata.jpa.service; import com.myimooc.springdata.jpa.domain.Employee; import com.myimooc.springdata.jpa.repository.EmployeeCrudRepository; import com.myimooc.springdata.jpa.repository.EmployeeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * Created by ZC on 2017/4/25. */ @Service public class EmployeeService { @Autowired private EmployeeRepository employeeRepository; @Autowired private EmployeeCrudRepository employeeCrudRepository; @Transactional public void updateAgeById(Integer id, Integer age){ this.employeeRepository.updateAgeById(id,age); }; @Transactional public void save(Listemployees){ this.employeeCrudRepository.save(employees); } }
4、編寫EmployeeService單元測試類
package com.myimooc.springdata.jpa.service; import com.myimooc.springdata.jpa.config.SpringConfig; import com.myimooc.springdata.jpa.repository.EmployeeRepository; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; /** * EmployeeService單元測試類 * Created by ZC on 2017/4/25. */ public class EmployeeServiceTest { private ApplicationContext ctx = null; private EmployeeService employeeService = null; @Before public void init(){ ctx = new AnnotationConfigApplicationContext(SpringConfig.class); employeeService = ctx.getBean(EmployeeService.class); } @After public void destroy(){ ctx = null; } @Test public void transactionManagerTest(){ PlatformTransactionManager transactionManager = (PlatformTransactionManager)ctx.getBean(PlatformTransactionManager.class); Assert.assertNotNull(transactionManager); } // 更新操作 @Test public void updateAgeByIdTest(){ employeeService.updateAgeById(1,55); } }第五章:Spring Data JPA高級 5-1 CrudRepository接口使用詳解
CrudRepository接口使用詳解
save(entity):保存一個實體 save(entities):保存多個實體 findOne(id):找到一個對象 exists(id):根據ID判斷對象是否存在 findAll():找到所有實體對象 delete(id):根據ID刪除實體對象 delete(entity):根據實體對象刪除實體對象 delete(entities):刪除多個實體對象 deleteAll():刪除所有實體對象
代碼演示:
1、編寫EmployeeCrudRepository接口
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.domain.Employee; import org.springframework.data.repository.CrudRepository; /** * 使用 CrudRepository 接口 * Created by ZC on 2017/4/26. */ public interface EmployeeCrudRepository extends CrudRepository{ }
2、編寫EmployeeCrudRepositoryTest單元測試類
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.config.SpringConfig; import com.myimooc.springdata.jpa.domain.Employee; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.ArrayList; import java.util.List; /** * EmployeeRepository單元測試類 * Created by ZC on 2017/4/24. */ public class EmployeeCrudRepositoryTest { private ApplicationContext ctx = null; private EmployeeCrudRepository employeeCrudRepository = null; @Before public void init(){ ctx = new AnnotationConfigApplicationContext(SpringConfig.class); employeeCrudRepository = ctx.getBean(EmployeeCrudRepository.class); } @After public void destroy(){ ctx = null; } @Test public void saveTest(){ List5-2 PagingAndSortingRespository接口使用詳解employees = new ArrayList (); Employee employee = null; for(int i=0;i<100;i++){ employee = new Employee(); employee.setName("test"+i); employee.setAge(100 - i); employees.add(employee); } employeeCrudRepository.save(employees); } }
PagingAndSortingRespository接口使用詳解
該接口包含分頁和排序的功能 帶排序的查詢:findAll(Sort sort) 帶排序的分頁查詢:findAll(Pageable pageable)
代碼演示:
1、編寫EmployeePagingAndSortingRepository接口
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.domain.Employee; import org.springframework.data.repository.PagingAndSortingRepository; /** * 使用 PagingAndSortingRepository 實現分頁和排序功能 * Created by ZC on 2017/4/26. */ public interface EmployeePagingAndSortingRepository extends PagingAndSortingRepository{ }
2、編寫EmployeePagingAndSortingRepositoryTest單元測試類
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.config.SpringConfig; import com.myimooc.springdata.jpa.domain.Employee; import com.myimooc.springdata.jpa.repository.EmployeePagingAndSortingRepository; import com.myimooc.springdata.jpa.service.EmployeeService; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import java.util.ArrayList; import java.util.List; /** * PagingAndSortingRepository 單元測試類 * Created by ZC on 2017/4/26. */ public class EmployeePagingAndSortingRepositoryTest { private ApplicationContext ctx = null; private EmployeePagingAndSortingRepository employeePagingAndSortingRepository = null; @Before public void init(){ ctx = new AnnotationConfigApplicationContext(SpringConfig.class); employeePagingAndSortingRepository = ctx.getBean(EmployeePagingAndSortingRepository.class); } @After public void destroy(){ ctx = null; } /** * 分頁功能測試 */ @Test public void pageTest(){ // page: index是從0開始的,不是從1開始的 Pageable pageable = new PageRequest(0,9); Page5-3 JpaRepository接口使用詳解employeePage = employeePagingAndSortingRepository.findAll(pageable); System.out.println("查詢的總頁數:"+employeePage.getTotalPages()); System.out.println("查詢的總記錄數:"+employeePage.getTotalElements()); System.out.println("查詢的當前第幾頁:"+(employeePage.getNumber() + 1)); System.out.println("查詢的當前頁面的集合:"+employeePage.getContent()); System.out.println("查詢的當前頁面的記錄數:"+employeePage.getNumberOfElements()); } /** * 分頁和排序功能測試 */ @Test public void pageAndSort(){ Sort.Order order = new Sort.Order(Sort.Direction.ASC,"id"); Sort sort = new Sort(order); // page: index是從0開始的,不是從1開始的 Pageable pageable = new PageRequest(0,5,sort); Page employeePage = employeePagingAndSortingRepository.findAll(pageable); System.out.println("查詢的總頁數:"+employeePage.getTotalPages()); System.out.println("查詢的總記錄數:"+employeePage.getTotalElements()); System.out.println("查詢的當前第幾頁:"+(employeePage.getNumber() + 1)); System.out.println("查詢的當前頁面的集合:"+employeePage.getContent()); System.out.println("查詢的當前頁面的記錄數:"+employeePage.getNumberOfElements()); } }
JpaRepository接口使用詳解
finaAll:查詢所有記錄 findAll(Sort sort):查詢所有記錄并排序 save(entities):保存多個實體對象 fiush: deleteInBatch(entities):一個批次里面刪除那些實體
代碼演示:
1、編寫EmployeeJpaRepository接口
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.domain.Employee; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.PagingAndSortingRepository; /** * 使用 JpaRepository 接口 * Created by ZC on 2017/4/26. */ public interface EmployeeJpaRepository extends JpaRepository{ }
2、編寫EmployeeJpaRepositoryTest單元測試類
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.config.SpringConfig; import com.myimooc.springdata.jpa.domain.Employee; import com.myimooc.springdata.jpa.repository.EmployeeJpaRepository; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.PagingAndSortingRepository; /** * EmployeeJpaRepository 單元測試類 * Created by ZC on 2017/4/26. */ public class EmployeeJpaRepositoryTest { private ApplicationContext ctx = null; private EmployeeJpaRepository employeeJpaRepository = null; @Before public void init(){ ctx = new AnnotationConfigApplicationContext(SpringConfig.class); employeeJpaRepository = ctx.getBean(EmployeeJpaRepository.class); } @After public void destroy(){ ctx = null; } @Test public void findTest(){ Employee employee = employeeJpaRepository.findOne(99); System.out.println("employee"+employee.toString()); System.out.println("employee(10)"+employeeJpaRepository.exists(10)); System.out.println("employee(102)"+employeeJpaRepository.exists(102)); } }5-4 JpaSpecificationExecutor接口使用詳解
JpaSpecificationExecutor接口使用詳解
Specification封裝了JPA Criteria查詢條件
代碼演示:
1、編寫EmployeeJpaSpecificationExecutor接口
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.domain.Employee; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; /** * 使用 JpaSpecificationExecutor 接口 * Created by ZC on 2017/4/26. */ public interface EmployeeJpaSpecificationExecutor extends JpaRepository, JpaSpecificationExecutor { }
2、編寫EmployeeJpaSpecificationExecutorTest單元測試類
package com.myimooc.springdata.jpa.repository; import com.myimooc.springdata.jpa.config.SpringConfig; import com.myimooc.springdata.jpa.domain.Employee; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import javax.persistence.criteria.*; /** * EmployeeJpaSpecificationExecutor 單元測試類 * Created by ZC on 2017/4/26. */ public class EmployeeJpaSpecificationExecutorTest { private ApplicationContext ctx = null; private EmployeeJpaSpecificationExecutor employeeJpaSpecificationExecutor = null; @Before public void init(){ ctx = new AnnotationConfigApplicationContext(SpringConfig.class); employeeJpaSpecificationExecutor = ctx.getBean(EmployeeJpaSpecificationExecutor.class); } @After public void destroy(){ ctx = null; } /** * 1、分頁 * 2、排序 * 3、查詢條件:age > 50 */ @Test public void queryTest(){ Sort.Order order = new Sort.Order(Sort.Direction.DESC,"id"); Sort sort = new Sort(order); // page: index是從0開始的,不是從1開始的 Pageable pageable = new PageRequest(0,5,sort); /** * root : 就是我們要查詢的類型 (Employee) * query : 添加查詢條件 * cb : 構建 Predicate */ Specification第六章:課程總結 6-4 課程總結specification = new Specification () { // 查詢條件 public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) { // root (employee (age)) Path path = root.get("age"); return cb.gt(path,50); } }; Page employeePage = employeeJpaSpecificationExecutor.findAll(specification,pageable); System.out.println("查詢的總頁數:"+employeePage.getTotalPages()); System.out.println("查詢的總記錄數:"+employeePage.getTotalElements()); System.out.println("查詢的當前第幾頁:"+(employeePage.getNumber() + 1)); System.out.println("查詢的當前頁面的集合:"+employeePage.getContent()); System.out.println("查詢的當前頁面的記錄數:"+employeePage.getNumberOfElements()); } }
課程總結
Spring Data概覽 傳統方式訪問數據庫 Spring Data快速起步 Spring Data JPA進階 Spring Data JAP高級
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69926.html
摘要:起步學習總結時間年月日星期四說明本文部分內容均來自慕課網。慕課網教學示例源碼個人學習源碼第一章簡介起步課程簡介簡介基本概念項目搭建用進行開發課程總結前端控制器開發應用的通用架構方式。 《SpringMVC起步》學習總結 時間:2017年2月16日星期四說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/z...
摘要:攔截器學習總結時間年月日星期六說明本文部分內容均來自慕課網。慕課網教學示例源碼暫無。攔截器不依賴與容器,過濾器依賴與容器。攔截器只能對請求起作用,而過濾器則可以對幾乎所有的請求起作用。共性問題在攔截器中處理,可以減少重復代碼,便于維護。 《SpringMVC攔截器》學習總結 時間:2017年2月18日星期六說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.co...
摘要:小時學會學習總結時間年月日星期六說明本文部分內容均來自慕課網。慕課網教學示例源碼暫無。數據庫操作下第六章事務管理事務管理只有查詢的時候不加事務,其它任何操作都要加事務。第七章課程回顧課程回顧總結介紹安裝配置的使用數據庫操作 《2小時學會SpringBoot》學習總結 時間:2017年2月18日星期六說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示...
摘要:事務管理學習總結時間年月日星期二說明本文部分內容均來自慕課網。一致性一致性指事務前后數據的完整性必須保持一致。聲明式事務管理基于的方式很少使用需要為每個進行事務管理的類,配置一個進行增強。 《Spring事務管理》學習總結 時間:2017年2月7日星期二說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com/教學示例源碼:https://github.com...
閱讀 845·2019-08-30 15:54
閱讀 3316·2019-08-29 15:33
閱讀 2701·2019-08-29 13:48
閱讀 1213·2019-08-26 18:26
閱讀 3333·2019-08-26 13:55
閱讀 1476·2019-08-26 10:45
閱讀 1164·2019-08-26 10:19
閱讀 305·2019-08-26 10:16