<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Spring Boot Maven Plugin – Spring Boot https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/maven-plugin/
[root@d java]# mvn clean; mvn compile;mvn package;
[root@d java]# java -jar target/springMybatis-1.0-SNAPSHOT.jar com.neo.HelloApplication
[root@d java]# tree -I target
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── neo
│ │ ├── controller
│ │ │ └── HelloController.java
│ │ ├── dataAccessObj
│ │ │ └── Student.java
│ │ └── HelloApplication.java
│ └── resources
│ ├── SqlMapConfig.xml
│ └── StudentMapper.xml
└── test
└── java
10 directories, 6 files
[root@d java]#
在spring boot的controller中添加 操作数据库代码
package com.neo.controller;
import com.neo.dataAccessObj.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import java.io.IOException;
import java.io.Reader;
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Hello Spring Boot 2.0!";
}
@RequestMapping("/t123")
public String t123() {
return this.getClass().getName() + Thread.currentThread().getStackTrace()[1].getMethodName();
}
@RequestMapping("/testMyBaits")
public String testMyBaits() throws IOException {
String res = this.getClass().getName() + Thread.currentThread().getStackTrace()[1].getMethodName();
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
try {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sqlSessionFactory.openSession();
try {
//Create a new student object
Student student;
for (int i = 0; i < 10; i++) {
student = new Student("Mohammad", "It", 80, i * i, System.currentTimeMillis() + "Mohammad@gmail.com");
//Insert student data
session.insert("Student.insert", student);
System.out.println("record inserted successfully" + Integer.toString(i));
}
session.commit();
} finally {
session.close();
}
} catch (IndexOutOfBoundsException e) {
System.err.println("IndexOutOfBoundsException: " + e.getMessage());
}
return res;
}
}
Tutorial · Building REST services with Spring https://spring.io/guides/tutorials/bookmarks/
TUTORIAL
Building REST services with Spring
REST has quickly become the de-facto standard for building web services on the web because they’re easy to build and easy to consume.
There’s a much larger discussion to be had about how REST fits in the world of microservices, but - for this tutorial - let’s just look at building RESTful services.
Why REST? REST embraces the precepts of the web, including its architecture, benefits, and everything else. This is no surprise given its author, Roy Fielding, was involved in probably a dozen specs which govern how the web operates.
What benefits? The web and its core protocol, HTTP, provide a stack of features:
-
Suitable actions (
GET
,POST
,PUT
,DELETE
, …) -
Caching
-
Redirection and forwarding
-
Security (encryption and authentication)
These are all critical factors on building resilient services. But that is not all. The web is built out of lots of tiny specs, hence it’s been able to evolve easily, without getting bogged down in "standards wars".
Developers are able to draw upon 3rd party toolkits that implement these diverse specs and instantly have both client and server technology at their fingertips.
So building on top of HTTP, REST APIs provide the means to build flexible APIs that can:
-
Support backward compatibility
-
Evolvable APIs
-
Scaleable services
-
Securable services
-
A spectrum of stateless to stateful services
What’s important to realize is that REST, however ubiquitous, is not a standard, per se, but an approach, a style, a set of constraints on your architecture that can help you build web-scale systems. In this tutorial we will use the Spring portfolio to build a RESTful service while leveraging the stackless features of REST.
Getting Started
As we work through this tutorial, we’ll use Spring Boot. Go to Spring Initializr and select the following:
-
Web
-
JPA
-
H2
-
Lombok
Then choose "Generate Project". A .zip
will download. Unzip it. Inside you’ll find a simple, Maven-based project including a pom.xml
build file (NOTE: You can use Gradle. The examples in this tutorial will be Maven based.)
Spring Boot can work with any IDE. You can use Eclipse, IntelliJ IDEA, Netbeans, etc. The Spring Tool Suite is an open-source, Eclipse-based IDE distribution that provides a superset of the Java EE distribution of Eclipse. It includes features that making working with Spring applications even easier. It is, by no means, required. But consider it if you want that extra oomph for your keystrokes. Here’s a video demonstrating how to get started with STS and Spring Boot. This is a general introduction to familiarize you with the tools.
If you pick up IntelliJ IDEA as your IDE for this tutorial, you have to install lombok plugin. In order to see how we install plugins in IntelliJ IDEA please have a look at managing-plugins. After this you have to ensure that "Enable annotation processing" checkbox is ticked under: Preferences → Compiler → Annotation Processors, as it is described https://stackoverflow.com/questions/14866765/building-with-lomboks-slf4j-and-intellij-cannot-find-symbol-log
The Story so Far…
Let’s start off with the simplest thing we can construct. In fact, to make it as simple as possible, we can even leave out the concepts of REST. (Later on, we’ll add REST to understand the difference.)
Our example models a simple payroll service that manages the employees of a company. Simply put, you need to store employee objects in an H2 in-memory database, and access them via JPA. This will be wrapped with a Spring MVC layer to access remotely.
nonrest/src/main/java/payroll/Employee.java
package payroll;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Data
@Entity
class Employee {
private @Id @GeneratedValue Long id;
private String name;
private String role;
Employee(String name, String role) {
this.name = name;
this.role = role;
}
}
Despite being small, this Java class contains much:
-
@Data
is a Lombok annotation to create all the getters, setters,equals
,hash
, andtoString
methods, based on the fields. -
@Entity
is a JPA annotation to make this object ready for storage in a JPA-based data store. -
id
,name
, androle
are the attribute for our domain object, the first being marked with more JPA annotations to indicate it’s the primary key and automatically populated by the JPA provider. -
a custom constructor is created when we need to create a new instance, but don’t yet have an id.
With this domain object definition, we can now turn to Spring Data JPA to handle the tedious database interactions. Spring Data repositories are interfaces with methods supporting reading, updating, deleting, and creating records against a back end data store. Some repositories also support data paging, and sorting, where appropriate. Spring Data synthesizes implementations based on conventions found in the naming of the methods in the interface.
There are multiple repository implementations besides JPA. You can use Spring Data MongoDB, Spring Data GemFire, Spring Data Cassandra, etc. For this tutorial, we’ll stick with JPA. |
nonrest/src/main/java/payroll/EmployeeRepository.java
package payroll;
import org.springframework.data.jpa.repository.JpaRepository;
interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
This interface extends Spring Data JPA’s JpaRepository
, specifying the domain type as Employee
and the id type as Long
. This interface, though empty on the surface, packs a punch given it supports:
-
Creating new instances
-
Updating existing ones
-
Deleting
-
Finding (one, all, by simple or complex properties)
Spring Data’s repository solution makes it possible to sidestep data store specifics and instead solve a majority of problems using domain-specific terminology.
Believe it or not, this is enough to launch an application! A Spring Boot application is, at a minimum, a public static void main
entry-point and the @SpringBootApplication
annotation. This tells Spring Boot to help out, wherever possible.
nonrest/src/main/java/payroll/PayrollApplication.java
package payroll;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PayrollApplication {
public static void main(String... args) {
SpringApplication.run(PayrollApplication.class, args);
}
}
@SpringBootApplication
is a meta-annotation that pulls in component scanning, autoconfiguration, and property support. We won’t dive into the details of Spring Boot in this tutorial, but in essence, it will fire up a servlet container and serve up our service.
Nevertheless, an application with no data isn’t very interesting, so let’s preload it. The follow class will get loaded automatically by Spring:
nonrest/src/main/java/payroll/LoadDatabase.java
package payroll;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
class LoadDatabase {
@Bean
CommandLineRunner initDatabase(EmployeeRepository repository) {
return args -> {
log.info("Preloading " + repository.save(new Employee("Bilbo Baggins", "burglar")));
log.info("Preloading " + repository.save(new Employee("Frodo Baggins", "thief")));
};
}
}
What happens when it gets loaded?
-
Spring Boot will run ALL
CommandLineRunner
beans once the application context is loaded. -
This runner will request a copy of the
EmployeeRepository
you just created. -
Using it, it will create two entities and store them.
-
@Slf4j
is a Lombok annotation to autocreate an Slf4j-basedLoggerFactory
aslog
, allowing us to log these newly created "employees".
Right-click and Run PayRollApplication
, and this is what you get:
... 2018-08-09 11:36:26.169 INFO 74611 --- [main] payroll.LoadDatabase : Preloading Employee(id=1, name=Bilbo Baggins, role=burglar) 2018-08-09 11:36:26.174 INFO 74611 --- [main] payroll.LoadDatabase : Preloading Employee(id=2, name=Frodo Baggins, role=thief) ...
This isn’t the whole log, but just the key bits of preloading data. (Indeed, check out the whole console. It’s glorious.)
HTTP is the Platform
To wrap your repository with a web layer, you must turn to Spring MVC. Thanks to Spring Boot, there is little in infrastructure to code. Instead, we can focus on actions:
nonrest/src/main/java/payroll/EmployeeController.java
package payroll;
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
class EmployeeController {
private final EmployeeRepository repository;
EmployeeController(EmployeeRepository repository) {
this.repository = repository;
}
// Aggregate root
@GetMapping("/employees")
List<Employee> all() {
return repository.findAll();
}
@PostMapping("/employees")
Employee newEmployee(@RequestBody Employee newEmployee) {
return repository.save(newEmployee);
}
// Single item
@GetMapping("/employees/{id}")
Employee one(@PathVariable Long id) {
return repository.findById(id)
.orElseThrow(() -> new EmployeeNotFoundException(id));
}
@PutMapping("/employees/{id}")
Employee replaceEmployee