配置数据源(DataSource)
Java的javax.sql.DataSource接口提供了一个标准的使用数据库连接的方法。 传统做法是, 一个DataSource使用一个URL以及相应的证书去构建一个数据库连接。
内嵌数据库的支持
在开发应用的过程中使用内嵌的内存数据库是非常方便的,很明显,内存数据库不提供数据的持久化存储;当应用启动时你需要填充你的数据库,当应用结束时数据将会丢弃。
Spring Boot可以自动的配置内嵌的H2、HSQL、Derby数据库。你不需要提供任何链接URLs,只需要简单的提供一个你需要使用的内嵌数据库的依赖即可。
如果在测试时要使用内嵌数据库的功能,需要注意在默认情况下无论使用多少个应用上下文在整个测试过程中相同的数据库都是可用复用的。如果想要让每个应用上下文使用隔离的内嵌数据库,应该设置spring.datasource.generate-unique-name为ture。
内嵌数据库的使用
本文通过演示H2内嵌数据库的使用来帮助理解在Spring Boot中如何使用内嵌数据库。
要使用H2内嵌数据库,首先需要添加JPA和H2的依赖,但是我们从数据库读取数据之后,需要展示在页面上,所以需要配置一个模板引擎,本文选择thymeleaf作为我们应用的模板引擎,所以也需要添加对thymeleaf的依赖。
添加之后的pom.xml如下:
4.0.0
com.springboot
demo
0.0.1-SNAPSHOT
jar
demo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.9.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
com.h2database
h2
runtime
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
repackage
对于我们的示例程序来说,我们需要创建一个实体类,类名我们将其命名为Journal,具体详细信息如下。
packagecom.springboot.domain;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.Date;importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.GenerationType;importjavax.persistence.Id;importjavax.persistence.Transient;
@Entitypublic classJournal {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)privateLong id;privateString title;privateDate created;privateString summary;
@Transientprivate SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");public Journal(String title, String summary, String date) throwsParseException{this.title =title;this.summary =summary;this.created =format.parse(date);
}
Journal(){}publicLong getId() {returnid;
}public voidsetId(Long id) {this.id =id;
}publicString getTitle() {returntitle;
}public voidsetTitle(String title) {this.title =title;
}publicDate getCreated() {returncreated;
}public voidsetCreated(Date created) {this.created =created;
}publicString getSummary() {returnsummary;
}public voidsetSummary(String summary) {this.summary =summary;
}publicString getCreatedAsShort(){returnformat.format(created);
}publicString toString(){
StringBuilder value= new StringBuilder("JournalEntry(");
value.append("Id: ");
value.append(id);
value.append(",Title: ");
value.append(title);
value.append(",Summary: ");
value.append(summary);
value.append(",Created: ");
value.append(getCreatedAsShort());
value.append(")");returnvalue.toString();
}
}
在上面的代码片段中,因为使用了JPA技术,所以你需要使用@Entity, @Id和@GeneratedValue注解,因此这个类被标记作为JPA实体并且能够被持久化到数据库中。你也可以看到,在我们的代码中也使用了@Transient注解,这个注解表示JPA引擎不会持久化被注解的属性,因为上面的代码片中被@Transient注解的属性仅仅只是用来格式化日期。这个类有两个构造函数,一个没有参数,JPA引擎需要这个构造函数,另外一个构造函数需要用来填充数据库的参数。
我们覆盖(override)了一个toString方法,主要用来打印记录。
接下来,我们需要为数据创建一个持久化机制,那么我们就需要使用Spring Data JPA技术了,
创建一个接口,继承JpaRepository接口。代码如下。
packagecom.springboot.repository;importcom.springboot.domain.Journal;importorg.springframework.data.jpa.repository.JpaRepository;public interface JournalRepository extends JpaRepository{
}
上面的代码片所展示的是Spring Data Repository JPA技术,要使用这项技术只需要继承JpaRepository接口即可。JpaRepository是一个标记接口,允许Spring Data Repository引擎识别它并提供必要的代理类来实现基本的CRUD (Create, Read, Update, Delete) 和一些自定义的方法。你可以通过一些类似于findByTitleLike、findBySummary、findByTitleAndSummaryIgnoringCase等等命名约定去实现你的方法。默认情况下,这些方法所实现的功能都会被设置成一个事务。JpaRepository也有一些非常便捷的操作可以对数据进行排序和分页的操作。
接下来,我们需要创建一个Web controller。
packagecom.springboot.web;importcom.springboot.repository.JournalRepository;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.RequestMapping;
@Controllerpublic classJournalController {
@Autowired
JournalRepository repo;
@RequestMapping("/")publicString index(Model model){
model.addAttribute("journal", repo.findAll());return "index";
}
}
@Controller注解、@Autowired注解、@RequestMapping注解我们不在详细介绍,如果使用过Spring MVC开发过应用,这些注解基本都已经了如指掌。在我们的index方法中,有一个Model类的参数,他用来添加一个名为journal的属性值,该属性的值通过调用JournalRepository接口repo.findAll() 获取。JournalRepository继承自JpaRepository,所以该接口有很多不同的默认方法,findAll方法就是其中之一。该方法返回数据库中所有的实体。
接下来我们需要构建模板文件,在src/main/resources/templates目录下,需要创建一个index.html文件并写入如下内容。
Spring Boot Journal