??有時候在項目中,我們并不是每個項目都是 Web 項目,我們也許只是對接一下接口或者單純的操作一下數(shù)據(jù)庫而已,但是如果直接使用 Jdbc 進行又比較麻煩,這時候就比較懷念使用 Spring 進行 Web 開發(fā)的日子,操作數(shù)據(jù)庫不能更簡單了.還要 Spring 的項目基本都可以單獨拿來使用,這樣我們就不必為了一個簡單的數(shù)據(jù)操作引入一些不必要的東西,Spring data jpa 就剛好滿足了操作數(shù)據(jù)庫的需求,而且 Jpa 可以為我們的程序帶來很好的移植性,訪問不同的數(shù)據(jù)庫僅僅是需要修改一下數(shù)據(jù)連接就可以完善搞定.下面我們就以 Mysql 為例,對一個 User 對象進行操作.
1. 引入依賴
??慣例,使用別人的東西,當然得引入別人的包,為了使用 Spring data jpa,我們首先引入Spring Framework,然后再引入Spring data jpa,當然了,使用MySql數(shù)據(jù)庫,我們了得引入它的數(shù)據(jù)庫連接.除此之外還得引入一些其它東西,比如Hibernate這樣的 Orm 框架,還有一些日志相關(guān)的東西,些片省略...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.3.5.RELEASE</spring.version>
<spring-data-jpa.version>1.11.1.RELEASE</spring-data-jpa.version>
<spring-data-commons-core.version>1.4.1.RELEASE</spring-data-commons-core.version>
<hibernate.version>5.2.9.Final</hibernate.version>
<mysql.conn.version>5.1.27</mysql.conn.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring-data-jpa.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.conn.version}</version>
</dependency>
</dependencies>
特別注意的地方需要說明一下:
- 引入Hibernate框架的時候,只引入核心版本就可以了,不用引入Hibernaet entitymanager,因為高版本的 core 帶了 entitymanager,而且 Maven 倉庫里面已經(jīng)標記 entitymanager 過時了;
- 引入 Spring 的時候,需要引入 4.3.X 及其以上的版本,不然運行的時候會報錯,其中的類 MethodClassKey.java 找不到,因為該類是 4.3 以后才引入的.
2. 創(chuàng)建實體
實體就是一個單獨的 User,實現(xiàn)對它CRUD操作就 Okay了.
@Entity
@Table
public class User implements Serializable {
private static final long serialVersionUID = -2407677666514147913L;
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private String userName;
private String password;
}
上面就是一個很簡單的實體對象了,它實現(xiàn)了序例化接口,僅擁有三個屬性,而其中一個還是主鍵.
3. 創(chuàng)建Respository對象
??因為我們使用的是 Spring data jpa,它給我們提供了一系列的操作,我們實現(xiàn)它的接口,并按它的規(guī)則定義接口里面的方法就可以實現(xiàn)數(shù)據(jù)庫的CRUD操作.
@Repository
public interface UserRep extends JpaRepository<User, Long>{
public User findByUserName(String userName);
}
// 不能更簡單
4. 數(shù)據(jù)庫配置
??為了示例的簡單,我們跳過邏輯業(yè)務(wù)層的定義,直接配置數(shù)據(jù)庫相關(guān)的操作,運行程序的時候操作調(diào)用 Repository 操作數(shù)據(jù)庫.標準的 Jpa 需要在 classpath 路徑下面配置 META-INF/persistence.xml 文件,在里面寫 orm 和 數(shù)據(jù)源,用戶名,密碼等.當然我們采用 zero confgi ,這些東西,通通都不要了,只需要創(chuàng)建一個類,把它指定為配置文件就 OK 了.
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
// 把 package names 修改為你的 User 類所在的包名就可以了
em.setPackagesToScan(new String[]{"package names"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/數(shù)據(jù)庫名");
dataSource.setUsername("用戶名");
dataSource.setPassword("密碼");
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(
EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQL5Dialect");
return properties;
}
}
為什么要有這個文件,因為 <b>Spring data jpa</b> 就是這樣規(guī)定的,關(guān)鍵點在于返回的那個 <b>transactionManager</b>,它就是 <b>Jpa</b>操作數(shù)據(jù)庫的東西,也就是 <b>entitymanager</b>,所以才有了這個配置文件,以及里面的一些附加的東西,不然程序怎么知道你的數(shù)據(jù)以及密碼呢?
5. Spring配置
上面的數(shù)據(jù)庫相關(guān)的配置完成了,那是不是就應該啟動程序測試一下了呢,那當然是可以了,但是我們用的是 <b>Spring</b> 的東西,我們還得告訴人家,那些類是做什么用的,比如那個是它的 <b>Spring data jpa</b>應該掃描的對象啊之類的東西,所以啊,就引出了下面這個 <b>Spring</b> 的 <b>Java Config</b>類.
@Configuration
@ComponentScan(basePackages = {"Spring需要掃描的包名"})
@EnableJpaRepositories(basePackages = {"定義的Jpa Respository所在的包位置"})
public class AppConfig {
// ...
}
6. 啟動項目
??到最最關(guān)鍵的一步了就是啟動我們的項目了,大家都知道啟動Spring項目得啟動它的容器,因為我們是采用注解的方式進行的,所以我們啟動的時候得用AnnotationConfigApplicationContext 這個類來啟動.
@ComponentScan(basePackageClasses = {AppConfig.class,PersistenceJPAConfig.class})
public class App {
private static final Logger log = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
log.debug("Start spring ....");
@SuppressWarnings("resource")
ApplicationContext context = new AnnotationConfigApplicationContext(App.class);
UserRep userRep = context.getBean(UserRep.class);
User user = new User();
user.setUserName("UserName");
user.setPassword("password");
System.out.println(userRep.save(user).getId());
}
}
如此整個工作就算完成了,但是這兒跨層級調(diào)用.我們應該把對數(shù)據(jù)庫的操作交給業(yè)務(wù)層來做,頂層只負責請求處理以及調(diào)用就可以了.對 Sprig zero cofig 配置以以及其中的日志等問題不了解的可以能看 Spring 零配置并解決Log日志
7. 總結(jié)
因為本例以最簡單的方式來說明這個問題,其中有的地方比較精簡,詳細內(nèi)容我已經(jīng)放在 GitHub,大家可以 <b>Git</b> 下來看,寫得不好的地方還請多多指點.