您好,登錄后才能下訂單哦!
今天小編給大家分享一下Spring JPA使用案例分析的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
JPA
(Java Persistence API) 是 Sun
官方提出的 Java
持久化規范。它為 Java
開發人員提供了一種對象/關聯映射工具來管理 Java
應用中的關系數據。他的出現主要是為了簡化現有的持久化開發工作和整合 ORM
技術,結束現在 Hibernate
,TopLink
,JD
O 等 ORM
框架各自為營的凌亂局面。JPA
在充分吸收了現有Hibernate
,TopLink
,JDO
等ORM
框架的基礎上發展而來的,具有易于使用,伸縮性強等優點。從上面的解釋中我們可以了解到JPA
是一套規范,而類似 Hibernate
,TopLink
,JDO
這些產品是實現了 JPA
規范。
了解了什么是 JPA
,我們來看看本文的主角——spring data jpa
。
pring Data JPA
是 Spring
基于 ORM
框架、JPA
規范的基礎上封裝的一套 JPA
應用框架,底層使用了 Hibernate
的 JPA
技術實現,可使開發者用極簡的代碼即可實現對數據的訪問和操作。它提供了包括增刪改查等在內的常用功能,且易于擴展!學習并使用 Spring Data JPA
可以極大提高開發效率。
什么意思呢?如果用過Hibernate
或者MyBatis
的話,就會知道對象關系映射(ORM)框架有多么方便。但是Spring Data JPA
框架功能更進一步,為我們做了 一個數據持久層框架幾乎能做的任何事情。以Springboot
整合MyBatis
為例,比如我們要向數據庫中插入一些用戶的數據,那么我們需要先定義用戶的實體類,然后我們要定義一個UserDao
:
@Repository public class UserDao { @Autowired JdbcTemplate jdbcTemplate; public int addUser(User user){ return jdbcTemplate.update("INSERT INTO t_user(username,jobs,phone) VALUE (?,?,?)", user.getName,user.getJobs,user.getPhone); } public int updateUser(User user){ return jdbcTemplate.update("UPDATE t_user SET username=?,jobs=?,phone=? WHERE id=?", user.getName,user.getJobs,user.getPhone,user.getId); } public int deleteUser(Integer id){ return jdbcTemplate.update("DELETE FROM t_user WHERE id=?",id); } public User getUserById(Integer id){ return jdbcTemplate.queryForObject("SELECT * FROM t_user WHERE id =?",new BeanPropertyRowMapper<>(User.class),id); } public List<User> getAllUser{ return jdbcTemplate.query("SELECT * FROM t_user",new BeanPropertyRowMapper<>(User.class)); } }
以及UserService
@Service public class UserService { @Autowired UserDao userDao; public int addUser(User user){ return userDao.addUser(user); } public int updateUser(User user){ return userDao.updateUser(user); } public int deleteUser(Integer id){ return userDao.deleteUser(id); } public User getUserById(Integer id){ return userDao.getUserById(id); } public List<User> getAllUser{ return userDao.getAllUser; } }
最后,我們在去調用對應的service
中的方法。這是傳統的方式,如果使用mapper
,會稍微簡單一些,比如我們要添加mapper
@Mapper public interface UserMapper { int addUser(User user); int deleteUser(int id); int updateUser(User user); User getUserById(Integer id); List<User> getAllUsers; }
然后定義一個UserMapper.xml
,添加對應的CURD SQL
語句,做好映射,然后改造service
,例如
@Service public class UserService { @Autowired UserMapper userMapper; public int addUser(User user){ return userMapper.addUser(user); } public int updateUser(User user){ return userMapper.updateUser(user); } public int deleteUser(Integer id){ return userMapper.deleteUser(id); } public User getUserById(Integer id){ return userMapper.getUserById(id); } public List<User> getAllUser{ return userMapper.getAllUsers; } }
發現什么問題了嗎?如果我們要去實現多個表的操作,我們需要定義不同的實體類,然后實現對應的mapper
,然后寫同樣的增刪改查方法,最后調用。這也太麻煩了些,而Spring data jpa
則可以輕松的幫我們實現這些繁瑣重復且沒有技術含量的操作。我們一起看下吧!
1.首先,我們需要配置pom.xml
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
2.然后是application.properties
的配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=create spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.show-sql=true
這里重點簡單介紹下spring.jpa.properties.hibernate.hbm2ddl.auto
有幾種配置:
create
:表示每次加載Hibernate
時都會刪除上一次生成的表(包括數據),然后重新生成新表,即使兩次沒有任何修改也會這樣執行。適用于每次執行單測前清空數據庫的場景。
create-drop
:表示每次加載Hibernate
時都會生成表,但當SessionFactory
關閉時,所生成的表將自動刪除。
update
:最常用的屬性值,第一次加載Hibernate
時創建數據表(前提是需要先有數據庫),以后加載Hibernate
時不會刪除上一次生成的表,會根據實體更新,只新增字段,不會刪除字段(即使實體中已經刪除)。
validate
:每次加載Hibernate
時都會驗證數據表結構,只會和已經存在的數據表進行比較,根據model
修改表結構,但不會創建新表。
不配置此項,表示禁用自動建表功能
spring.jpa.show-sql=true
該配置當在執行數據庫操作的時候會在控制臺打印 sql
語句,方便我們檢查排錯等。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
這是數據庫的方言配置。
3.接下來我們建立用戶實體類
@Entity public class User { @Id @GeneratedValue private long id; @Column(nullable = false, unique = true) private String userName; @Column(nullable = false) private String password; @Column(nullable = false) private int age; }
這里的一些注解解釋如下:
@Entity 是一個類注解,用來注解該類是一個實體類用來進行和數據庫中的表建立關聯關系,首次啟動項目的時候,默認會在數據中生成一個同實體類相同名字的表(table),也可以通過注解中的 name
屬性來修改表(table)名稱, 如@Entity(name=“user”) , 這樣數據庫中表的名稱則是 user
。該注解十分重要,如果沒有該注解首次啟動項目的時候你會發現數據庫沒有生成對應的表。
@Table 注解也是一個類注解,該注解可以用來修改表的名字,該注解完全可以忽略掉不用,@Entity 注解已具備該注解的功能。
@Id 類的屬性注解,該注解表明該屬性字段是一個主鍵,該屬性必須具備,不可缺少。
@GeneratedValue 該注解通常和 @Id 主鍵注解一起使用,用來定義主鍵的呈現形式,該注解通常有多種使用策略,先總結如下:
@GeneratedValue(strategy= GenerationType.IDENTITY) 該注解由數據庫自動生成,主鍵自增型,在 mysql 數據庫中使用最頻繁,oracle 不支持。
@GeneratedValue(strategy= GenerationType.AUTO) 主鍵由程序控制,默認的主鍵生成策略,oracle
默認是序列化的方式,mysql
默認是主鍵自增的方式。
@GeneratedValue(strategy= GenerationType.SEQUENCE) 根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列,Oracle
支持,Mysql
不支持。
@GeneratedValue(strategy= GenerationType.TABLE) 使用一個特定的數據庫表格來保存主鍵,較少使用。
上面這些主鍵生成策略中,以 mysql
為例, IDENTITY
和 AUTO
用的較多,二者當中IDENTIT
用的多些,以下文章當中演示的 demo
主鍵均使用 @GeneratedValue(strategy= GenerationType.IDENTITY) 的生成策略。
@Column 是一個類的屬性注解,該注解可以定義一個字段映射到數據庫屬性的具體特征,比如字段長度,映射到數據庫時屬性的具體名字等。
@Transient 是一個屬性注解,該注解標注的字段不會被映射到數據庫當中。
4. 聲明 UserRepository
接口,繼承JpaRepository
,如下所示
public interface UserRepository extends JpaRepository<User, Long> { }
這里的 JpaRepository
繼承了接口PagingAndSortingRepository
和QueryByExampleExecutor
。而,PagingAndSortingRepository
又繼承CrudRepository
。
因此,JpaRepository
接口同時擁有了基本CRUD
功能以及分頁功能。因此,這里我們可以繼承JpaRepository
,從而獲得Spring
為我們預先定義的多種基本數據操作方法。
5.然后我們定義一個測試類, 這里我們演示下添加操作, @Transactional 表示開啟事務防止出現臟數據。
…… @Autowired private UserRepository userRepository; @Test @Transactional public void userAddTest() { User user = new User(); user.setUserName("吳彥祖"); user.setAge(30); user.setPassword("123456"); userRepository.save(user); User item = userRepository.findByUserName("wyk"); log.info(JsonUtils.toJson(item)); }
6.接下來我們說下查詢,查詢可以分為基本查詢和自定義查詢,一種是 spring data
默認已經實現,只需要要繼承JpaRepository
,一種是根據查詢的方法來自動解析成 SQL
。
@Test public void testQuery() throws Exception { User user=new User(); userRepository.findAll(); userRepository.findOne(1l); userRepository.save(user); userRepository.delete(user); userRepository.count(); userRepository.exists(1l); …… }
7.自定義的簡單查詢就是根據方法名來自動生成SQL
,主要的語法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy
后面跟屬性名稱,舉幾個例子:
User findByUserName(String userName); User findByUserNameOrEmail(String username, String email); Long deleteById(Long id); Long countByUserName(String userName); List<User> findByEmailLike(String email); User findByUserNameIgnoreCase(String userName); List<User> findByUserNameOrderByEmailDesc(String email);
8.接下來,我們說下復雜的查詢,在實際的開發中我們需要用到分頁、刪選、連表等查詢的時候就需要特殊的方法或者自定義 SQL
,以分頁查詢為例,分頁查詢在實際使用中非常普遍了,spring data jpa
已經幫我們實現了分頁的功能,在查詢的方法中,需要傳入參數Pageable
,當查詢中有多個參數的時候Pageabl
e建議做為最后一個參數傳入。Pageable
是 spring
封裝的分頁實現類,使用的時候需要傳入頁數、每頁條數和排序規則
Page<User> findALL(Pageable pageable); Page<User> findByUserName(String userName,Pageable pageable);
9.我們看下下面的測試用例
@Test public void testPageQuery() throws Exception { int page=1,size=5; Sort sort = new Sort(Direction.DESC, "id"); Pageable pageable = new PageRequest(page, size, sort); userRepository.findALL(pageable); userRepository.findByUserName("testName", pageable); }
Spring data
大部分的SQL
都可以根據方法名定義的方式來實現,但是由于某些原因我們想使用自定義的 SQL
來查詢,spring data
也是完美支持的,如下所示:
@Modifying @Query("update User u set u.userName = ?1 where c.id = ?2") int modifyByIdAndUserId(String userName, Long id); @Transactional @Modifying @Query("delete from User where id = ?1") void deleteByUserId(Long id); @Transactional(timeout = 10) @Query("select u from User u where u.emailAddress = ?1") User findByEmailAddress(String emailAddress);
以上就是“Spring JPA使用案例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。