结构:
build.gradle
buildscript {
ext {
springBootVersion = '2.0.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'
group = 'com.spring'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2')
runtime('org.postgresql:postgresql')
testCompile('org.springframework.boot:spring-boot-starter-test')
compile('org.projectlombok:lombok:1.18.2')
}
create database
create table d_user (id varchar, username varchar, password varchar, email varchar)
application.yml
server:
port: 8085
spring:
datasource:
url: jdbc:postgresql://{ip}/{databaseName}
username: postgres
password: p
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.postgresql.Driver
mybatis:
mapper-locations: classpath:mapping
创建实体model User.java
- 采用 lombok, 节省getter setter
- Alias() 作用于UserMapper.xml 的 resultType (如果没有注解默认是model 的小写)
package com.spring.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.ibatis.type.Alias;
/**
* @author derrick.liang
*/
@Getter
@Setter
@ToString
@Alias(value = "User")
public class User {
private String id;
private String username;
private String password;
private String email;
public User(String id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public User() {
}
}
创建Mapper 接口 UserMapper.java
package com.spring.mapper;
import com.spring.model.User;
import org.apache.ibatis.annotations.Mapper;
/**
* @author derrick.liang
*/
@Mapper
public interface UserMapper {
User findUserByUsernam username);
}
创建 UserMapper.xml 映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spring.mapper.UserMapper">
<select id="findUserByUsername" resultType="User">
select * from d_user where username = #{username}
</select>
</mapper>
Dao
UserDao.java
package com.spring.dao;
import com.spring.model.User;
import java.util.Optional;
/**
* @author derrick.liang
*/
public interface UserDao {
Optional<User> findUserByUsername(String username);
}
UserDaoImpl.java
package com.spring.dao;
import com.spring.mapper.UserMapper;
import com.spring.model.User;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.Optional;
/**
* @author derrick.liang
*/
@Repository
public class UserDaoImpl implements UserDao {
@Resource
UserMapper userMapper;
@Override
public Optional<User> findUserByUsername(String username) {
User user = userMapper.findUserByUsername(username);
return Optional.ofNullable(user);
}
}
Service
UserService.java
package com.spring.service;
import com.spring.model.User;
import java.util.Optional;
/**
* @author derrick.liang
*/
public interface UserService {
Optional<User> findUserByName(String username);
}
UserServiceImpl.java
package com.spring.service;
import com.spring.dao.UserDao;
import com.spring.model.User;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Optional;
/**
* @author derrick.liang
*/
@Service
public class UserServiceImpl implements UserService {
@Resource
UserDao userDao;
@Override
public Optional<User> findUserByName(String username) {
Optional<User> optionalUser = userDao.findUserByUsername(username);
User user = optionalUser.orElse(new User());
user.setId("test");
return Optional.of(user);
}
}
Controller
UserController.java
package com.spring.controller;
import com.spring.model.User;
import com.spring.service.UserService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author derrick.liang
*/
@RestController
@RequestMapping("/api")
public class UserController {
@Resource
UserService userService;
@RequestMapping("/get/{username}")
public User getUserInfo(@PathVariable(value = "username") String username) {
return userService.findUserByName(username).orElse(new User());
}
}
Application
package com.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MybatisApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisApplication.class, args);
}
}
确保webapp 可以部署到Tomcat, 需要实现自定义ServletContainerInitializer 配置加载
ServletInitializer.java
package com.spring;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* @author derrick.liang
*/
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MybatisApplication.class);
}
}
postman 测试
需要注意的点
- 当指定了@service/@repository的name值时, 在@Resource中要么不指示,如果指示的话,则要与之相对应。
- 当没有指定@service的name值是,在@Resource中随意。但是前提是,实现该接口的只有这一个类。
- 所以,建议是最好在@service/@repository和@Resoure中同时指定名称,并且做到一一对应。
- 如果采用@Autowired来注解,则同样无需指定name属性,若是实现该接口有多个类,则需要通过@Qualifier来做区分