J2EE笨重的开发、繁多的配置、低下的开发效率、复杂的部署流程、第三方技术集成难度大
Spring Boot是整个Spring技术栈的一个大整合,用来简化Spring应用开发,遵从约定大于配置, 去繁从简,只要点击运行就能创建一个独立的,产品级别的应用。,其实它不是什么新的框架,它只是默认配置了很多框架的使用方式
功能:浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串
说明:本示例程序采用IntelliJ IDEA进行开发,仅供参考
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.testgroupId>
<artifactId>HelloWorldartifactId>
<version>1.0-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.2.RELEASEversion>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
project>
如果第一次使用Maven可能要稍等一会,项目会向远程仓库下载配置依赖中相关JAR包。
package com.test.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloWorldController {
@RequestMapping("/hello")
public String hello() {
return "hello world!";
}
}
package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args){
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>1.5.2.RELEASEversion>
<relativePath>../../spring-boot-dependenciesrelativePath>
parent>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
当前台传参数给后台时,后台需要能够准确的接受并进行处理。
@RequestMapping("/hello")
public String hello(String userName) {
return "hello " + userName + "!";
}
前台请求:http://localhost:8080/hello?userName=SpringBoot
方法会自动接受名称相同参数的值赋给自己,若名称不同可使用@RequestParam注解进行参数说明,也可以达到相同的效果
@RequestMapping("/hello")
public String hello(@RequestParam("userName") String name) {
return "hello " + name + "!";
}
package com.test.model;
import java.util.List;
import java.util.Map;
public class User {
private int userId;
private String userName;
private String password;
private List<String> phoneNum;
private List<Map<Integer,String>> event;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(List<String> phoneNum) {
this.phoneNum = phoneNum;
}
public List<Map<Integer, String>> getEvent() {
return event;
}
public void setEvent(List<Map<Integer, String>> event) {
this.event = event;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", phoneNum=" + phoneNum +
", event=" + event +
'}';
}
}
然后修改HelloWorldController:
在hello的参数上需要加上@RequestBody用来将传入的Json数据转换为对象中属性的值,在下面的hello程序将接受输入的user参数并将user.toString()后输出给前端。
@RequestMapping("/hello")
public String hello(@RequestBody User user) {
return "hello " + user.toString();
}
最后进行测试:
使用工具:Postman
请求地址:http://localhost:8080/hello
请求方法:Post,application/json
请求参数如下:
{
"userId": "1",
"userName": "jack",
"password": "123456",
"phoneNum": ["213123","2312312"],
"event": [
{"1": "1年级"},
{"2": "2年级"},
{"3": "3年级"}
]
}
返回结果:
hello User{userId=1, userName='jack', password='123456',
phoneNum=[213123, 2312312], event=[{1=1年级}, {2=2年级}, {3=3年级}]}
功能:后台对于前台输入的数据往往需要进行校验是否符合规则。
@RequestMapping("/hello1")
public String hello1(@NotBlank(message = "用户名字不能为空")
@Length(min = 2, max = 10, message = "用户名长度必须在 2 - 10 之间")
@RequestParam("userName") String userName) throws Exception {
return "hello "+ userName;
}
package com.test.exception;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = ConstraintViolationException.class)
public ResponseEntity<String> constraintViolationExceptionHandler(ConstraintViolationException e) {
return ResponseEntity.badRequest().body(e.getConstraintViolations().stream()
.map(ConstraintViolation::getMessageTemplate)
.findFirst()
.orElse(e.getMessage())
);
}
}
@RequestMapping("/hello")
public String hello(@Validated @RequestBody User user,
BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
return bindingResult.getAllErrors().get(0).getDefaultMessage();
}
return "hello "+user.toString();
}
public class User {
private int userId;
@NotBlank(message = "用户名字不能为空")
@Length(min = 2, max = 10, message = "用户名长度必须在 {min} - {max} 之间")
private String userName;
private String password;
private List<String> phoneNum;
private List<Map<Integer,String>> event;
{
"userId": "1",
"password": "123456",
"phoneNum": ["213123","2312312"],
"event": [
{"1": "1年级"},
{"2": "2年级"},
{"3": "3年级"}
]
}
校验结果1:
用户名字不能为空
请求参数2:
{
"userId": "1",
"userName": "r12312312321321",
"password": "123456",
"phoneNum": ["213123","2312312"],
"event": [
{"1": "1年级"},
{"2": "2年级"},
{"3": "3年级"}
]
}
校验结果2:
用户名长度必须在 2 - 10 之间
在SpringBoot应用中使用MyBatis作为与数据库相关的持久层框架,该示例将演示两个简单例子,分别为向数据库中添加数据和前台查询并显示数据库中的数据。
该示例使用MySql数据库,仅供参考。
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.4version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
spring:
# 数据源配置信息根据自己的数据库而定
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/test
driver‐class‐name: com.mysql.jdbc.Driver
mybatis:
config-location: classpath:mybatis/mybatis.xml
mapper-locations: classpath:mybatis/mapper/**/*.xml
<configuration>
<settings>
<setting name="cacheEnabled" value="true" />
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="true" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="useGeneratedKeys" value="true" />
<setting name="autoMappingBehavior" value="PARTIAL" />
<setting name="defaultExecutorType" value="SIMPLE" />
<setting name="defaultStatementTimeout" value="3000" />
<setting name="logImpl" value="STDOUT_LOGGING" />
settings>
configuration>
create table `user` (
`user_id` bigint(20) not null auto_increment,
`user_name` varchar(255) default null,
`password` varchar(255) default null,
primary key (`user_id`)
)
package com.test.mapper;
import com.test.model.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
int addUser(User user);
List<User> getUserInfo();
User getUserById(@Param("userId") int userId);
}
<mapper namespace="com.test.mapper.UserMapper">
<resultMap id="userResultMap" type="com.test.model.User">
<result column="user_id" property="userId" />
<result column="user_name" property="userName" />
<result column="password" property="password" />
resultMap>
<select id="getUserInfo" resultMap="userResultMap">
select user_id, user_name, password from user
select>
<select id="getUserById" resultMap="userResultMap">
select user_id, user_name, password
from user where user_id=#{userId}
select>
<insert id="addUser" parameterType="com.test.model.User"
useGeneratedKeys="true" keyProperty="userId">
insert into user(user_name, password)
value(#{userName}, #{password})
insert>
mapper>
@MapperScan("com.test.mapper")
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args){
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
@RequestMapping("/user/addUser")
public int addUser(@RequestBody User user){
return userMapper.addUser(user);
}
@RequestMapping("/user/getUserInfo")
public List<User> getUserInfo(){
return userMapper.getUserInfo();
}
@RequestMapping("/user/getUserById")
public User getUserInfo(int userId){
return userMapper.getUserById(userId);
}
{
"userName": "jack",
"password": "123456"
}
参数2:
{
"userName": "mary",
"password": "ABCDEFG"
}
执行完车后查看数据库中的信息,可以看到数据被成功插入进数据库了:
SELECT * FROM `user`
userId userName paaword
------ -------- ---------
1 jack 123456
2 mary ABCDEFG
[
{
"userId": 1,
"userName": "jack",
"password": "123456",
"phoneNum": null,
"event": null
},
{
"userId": 2,
"userName": "mary",
"password": "ABCDEFG",
"phoneNum": null,
"event": null
}
]
浏览器请求:http://localhost:8080/user/getUserById?userId=2
将会得到下面的结果:
{
"userId": 2,
"userName": "mary",
"password": "ABCDEFG",
"phoneNum": null,
"event": null
}
到此一个简单的SpringBoot应用和MyBatis的整合就完成了。
useGeneratedKeys="true" keyProperty="userId"
<insert id="addUser" parameterType="com.test.model.User"
useGeneratedKeys="true" keyProperty="userId">
insert into user(userName, password)
value(#{userName}, #{password})
insert>
在插入一个user后会把user中的userId字段设置成插入数据库中主键。
修改HelloWorldController中的addUser方法,使得方法的返回值是新插入用户的id:
@RequestMapping("/user/addUser")
public int addUser(@RequestBody User user){
userMapper.addUser(user);
return user.getUserId();
}
重新运行程序后使用postman发送请求http://localhost:8080/user/addUser
请求参数:
{
"userName": "tom",
"password": "@#$%%^^&**"
}
int addUser(User user);
<insert id="addUser" parameterType="com.test.model.User"
useGeneratedKeys="true" keyProperty="userId">
insert into user(userName, password)
value(#{userName}, #{password})
insert>
在UserMapper.java中添加根据用户名和密码获取用户信息的方法
User getUserByNameAndPsd(String userName, String password);
在userMapper.xml中添加SQL
<select id="getUserByNameAndPsd" resultMap="userResultMap">
select user_id, user_name, password from `user`
where user_name=#{param1} and password=#{param2}
select>
#{param1}的值就是传入的userName,#{param2}的值就是传入的password
最后在HelloWorldController.java中添加代码进行请求测试
@RequestMapping("user/getUserInfoByNameAndPsd")
public User getUserInfo(String userName, String password) {
return userMapper.getUserByNameAndPsd(userName, password);
}
运行程序后使用post请求:http://localhost:8080/user/getUserInfoByNameAndPsd?userName=jack&password=123456
输出结果为:
#{param1}和#{param2}亦可以换成#{arg0}和#{arg1},结果相同
User getUserByNameAndPsd(@Param("userName") String userName,
@Param("password") String password);
修改userMapper.xml中的SQL
<select id="getUserByNameAndPsd" resultMap="userResultMap">
select user_id, user_name, password from `user`
where user_name=#{userName} and password=#{password}
select>
重新运行程序后可得到和上面相同的结果
#{userName}, #{password}
<resultMap id="userResultMap" type="com.test.model.User">
<result column="user_id" property="userId" />
<result column="user_name" property="userName" />
<result column="password" property="password" />
resultMap>
resultMap还支持继承、定义数组、结果集嵌套和分步查询等
假设现在我们需要在查询用户信息结果中添加用户号码信息,我们需要将用户的电话号码信息保存到数据库中,为此在数据库中创建电话表并且插入数据:
CREATE TABLE `phone` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` BIGINT(20) UNSIGNED DEFAULT NULL,
`phone_num` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO phone(user_id, phone_num)
VALUES
(1,'123456789'),
(1,'14567'),
(1,'213123'),
(2,'123213'),
(2,'33256'),
(3,'3333333');
定义获取用户号码的SQL
<select id="getPhoneNum" resultType="java.lang.String">
select phone_num from phone where user_id=#{userId}
select>
定义新的resultMap继承自userResultMap并新增获取用户电话号码集合
<resultMap id="newUserResultMap" extends="userResultMap"
type="com.test.model.User">
<collection property="phoneNum" column="{userId=user_id}"
select="getPhoneNum" />
resultMap>
使用newUserResultMap作为获取用户信息的结果映射
<select id="getUserInfo" resultMap="newUserResultMap">
select user_id, user_name, password from user
select>
最后需要在User实体类上添加注解@JsonIgnoreProperties({“handler”}),否则会报错
重新运行程序使用postman发送请求:http://localhost:8080/user/getUserInfo
查询结果为:
动态SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作。MyBatis 采用功能强大的基于OGNL 的表达式来简化操作
<select id="getUserById" resultType="com.test.model.User">
<if test="userId!=null and userId!=''">
select userId, userName, password from user where userId=#{userId}
if>
select>
<select id="getUserById" resultType="com.test.model.User">
select userId,userName,password
from user
<where>
<choose>
<when test="userId!=null and userId!=''">userId=#{userId}when>
<otherwise>userId=-1otherwise>
choose>
where>
select>
<select id="getUserByIds" resultType="com.test.model.User">
select userId,userName,password
from user where userId in
<foreach collection="ids" item="userId" separator="," open="(" close=")">
#{userId}
foreach>
select>
<update id="updateUserInfoById" parameterType="com.test.model.User">
update `user`
<trim prefix="set" suffixOverrides=",">
<if test="userName!=null">user_name=#{userName},if>
<if test="password!=null">password=#{password},if>
trim>
where user_id=#{userId}
update>
上面的update语句不管userName或password是否为空,都会在后面多出一个逗号,但是 suffixOverrides="," 配置会将多余的逗号给去掉,不会影响SQL的正常执行
更多信息可以参考mybatis官方文档
参考百度~~
最后附上源码链接:https://pan.baidu.com/s/1R8l0UK0_KqLch5WgYEZyrw 提取码:dfj7