1. 前言
前面文章整合過了ssm的,是相對spring的,不過在現在微服務流行之際,為了往后面的springcloud發展學習,先學習一下springboot,在學習的過程中用spring boot+spring mvc+mybatis進行搭建接口平臺。
2. 簡介
spring boot:Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Spring Boot致力于在蓬勃發展的快速應用開發領域(rapid application development)成為領導者。(來自百度百科)。
2.1 spring boot特點
- 創建獨立的Spring應用程序
- 嵌入的Tomcat,無需部署WAR文件
- 開箱即用,提供各種默認配置來簡化項目配置
- 沒有冗余代碼生成和XML配置的要求
2.2 個人理解
在我看來,spring boot并不是什么新的框架,它只是默認配置了很多框架的使用方式;類似于maven整合了jar,而spring boot整合了很多的框架。從本質上來講,spring boot就是spring,它做了那些你需要去做的復雜配置。它使用“習慣優于配置”的理念讓你的項目快速運行起來。
2.2 回顧一下spring web項目步驟
- 配置web.xml,加載spring和spring mvc
- 配置數據庫連接、配置spring事務
- 配置加載配置文件的讀取,開啟注解
- 配置日志文件
......
配置完成后部署tomcat調試...
2.3 spring boot項目
只需要非常少的幾個配置就可以迅速方便的搭建起來一套web項目或者是構建一個微服務!下面就讓我們一起來領略spring boot的魅力
3. 項目搭建
整個項目使用maven構建,有關idea集成maven、jdk、tomcat等可翻我上一篇文章。
3.1 在這里使用spring提供的SPRING INITIALIZR工具來產生基礎項目。
- 訪問 :http://start.spring.io/
- 選擇構建工具maven、語言java、版本1.5.10(支持jdk1.7)
initializr.png
- 點擊Generate Project下載項目壓縮包
- 解壓項目,導入進idea,說一下簡要步驟
- File -> New -> Project from Existing Sources
- 選擇你解壓的項目文件夾
- 點擊OK
- 選擇Import project from external model并選擇Maven,點擊Next到底為止。
3.2 編譯錯誤
若在項目編譯過程中,遇到[Information:java: javacTask: 源發行版 1.8 需要目標發行版 1.8]這個錯誤,可按照如下更改,這里我統一改為了1.7
1,Project Structure里確認兩個地方:Project sdk以及project language level
2,Project Structure->Modules里Sources里的Language level
3,Preferences->java Compiler->Per-module bytecode Version
至此基礎項目準備完畢,運行一下項目
image.png
看見Spring Boot這個圖案證明基礎項目搭建成功。
4. 編寫代碼
4.1 項目結構
項目結構.png
系統整個架構為springboot+springmvc+mybatis,restful的接口風格。只是一個示例項目,也沒有進行模塊分包。整個結構的話還是controller、service、dao的三層結構。在這里面dao層多寫了一個接口和實現。對于service層沒有寫接口,因為我覺得簡單的業務沒必要寫接口(包括這里的dao也是)。
我也一直在思考,對于service和dao層,到底需不需要接口和實現。網上查了一些,有些是瞎扯了一堆“接口和實現分離”、“面向接口編程”、“設計模式”、“解耦”等,但是也沒說出個所以然;有些是說沒必要分離,或者看系統架構。自己也是經歷不多,不知道確切的區別或者說有什么效率上的區別。這個待我日后慢慢積累,有機會咨詢長者學習,或者評論區靜待大神的解答。
4.2 項目配置
springboot 遵循"習慣優于配置"原則,使用Spirng Boot只需很少的配置,大部分時候可以使用默認配置。
使用INITIALIZR工具創建的springboot項目,默認會在resource目錄下創建application.properties文件,另外也可以使用yml類型的配置文件代替properties文件。在這里我是使用的是yml文件。
application.yml
spring:
datasource:
# 驅動配置信息
url: jdbc:mysql://localhost:3306/spring_boot?useUnicode=true&characterEncoding=utf8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
# 連接池的配置信息
filters: stat
maxActive: 20
initialSize: 1
maxWait: 60000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
這里主要就是配置了阿里的druid連接池信息。上面的就是類型和驅動這些,然后就是mysql數據庫的url、用戶名和密碼,相應改成自己的就行。下面的是druid的參數配置項,這里隨便設置了一些,具體可詳查Druid。
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true" /><!-- 全局映射器啟用緩存 -->
<setting name="useGeneratedKeys" value="true" /> <!--把新增加的主鍵賦值到自己定義的keyProperty(id)中-->
<setting name="defaultExecutorType" value="REUSE" /> <!--配置和設定執行器-->
<setting name="logImpl" value="STDOUT_LOGGING"/> <!--打印sql語句在控制臺-->
</settings>
<typeAliases>
<package name="com.bgy.springboot.model"/>
</typeAliases>
</configuration>
這個配置主要就是關于mybatis的配置了,這里就提兩點,一個是setting里面的logImpl配置,可以把執行的sql語句打印在控制臺,便于排查sql錯誤;二個是使用typeAliases標簽元素來對類型進行別名控制,也就是給具體的實體類一個別名,不用寫完整路徑。具體使用在后面mapper中會講到。
以上就是這個項目目前用到的兩個配置了,是不是比起spring來說簡便多了。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<groupId>com.bgy</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--自己添加的包-->
<dependency>
<!-- spring boot 引入Web模塊。自動配置:tomcat、springmvc、jackson等 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- log4j2 依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- springboot 依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<!-- 阿里druid連接池依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
<!-- mysql 依賴-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis依賴-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<!-- fastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.27</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!--aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
這些就是當前項目中用到的一些maven依賴了。
DbDataSource.class
@Configuration
@MapperScan(basePackages = "com.bgy.springboot.dao",sqlSessionTemplateRef = "dbSqlSessionTemplate")
public class DbDataSource {
@Bean(name="dbData")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dbDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "dbSqlSessionFactory")
public SqlSessionFactory dbSqlSessionFactory(@Qualifier("dbData") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
sqlSessionFactoryBean.setConfigLocation( new ClassPathResource("mybatis-config.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean(name="dbSqlSessionTemplate")
public SqlSessionTemplate dbSqlSessionTemplate(@Qualifier("dbSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception{
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "dbTransactionManager")
public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("dbData") DataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
SqlSessionTemplate是MyBatis提供的持久層訪問模板化的工具,這個類負責管理MyBatis的SqlSession,用于調用MyBatis的SQL方法。因為SqlSessionTemplate是線程安全的,可以被多個DAO所共享使用,所以項目中只建立了一個SqlSessionTemplate。
在這里使用的是mybatis注解需要的配置。mybatis3開始支持java注解,使用java注解可以替代xml配置文件,簡化代碼。上面的代碼中,使用@MapperScan來掃描注冊mybatis數據庫接口類,其中basePackages屬性表明接口類所在的包,sqlSessionTemplateRef表明接口類使用的SqlSessionTemplate。
@Configuration 申明這是一個配置類相當于xml配置文件,@Bean表示這是一個Spring管理的bean。
@ConfigurationProperties用于裝載yml的配置信息
這里面其他關于SqlSessionTemplate的用法和細節就不一一講了,不明白的可百度學習一下SqlSessionTemplate。提一下setMapperLocations是用于加載以xml結尾的mapper配置文件,這里注意路徑就行了,根路徑是resources。setConfigLocation是加載mybatis的配置文件mybatis-config.xml。
4.3 數據庫文件
這個在上篇文章已經介紹過作用,就是方便對sql語句的查閱和修改。
db_ddl.sql
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` VARCHAR (45) NOT NULL ,
`user_name` VARCHAR (100) ,
`nick_name` VARCHAR (100),
`password` CHAR (32),
`email` VARCHAR (50),
`phone` VARCHAR (50),
`sex` ENUM('S_MALE','S_FEMALE','S_BM'),
`status` ENUM('S_OFF','S_NORMAL'),
`avatar` VARCHAR (100),
`remarks` VARCHAR (200),
`add_at` BIGINT,
`update_at` BIGINT,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
這里表名和字段與上一篇文章相比修改了一些,因為看了《阿里巴巴 Java開發手冊》中寫道:
表名、字段名必須使用小寫字母或數字,禁止出現數字開頭,禁止兩個下劃線中間只出現數字。數據庫字段名的修改代價很大,因為無法進行預發布,所以字段名稱需要慎重考慮。 說明:MYSQL在Windows下不區分大小寫,但在Linux上默認區分大小寫。因此,數據庫名、表名、字段名都不允許出現任何大寫字母,避免節外生枝。
4.4 實體類
建立一個MUser的實體類
MUser.class
public class MUser {
private String id;
private String userName;
private String nickName;
private String password;
private String email;
private String phone;
private String sex;
private String status;
private String avatar;
private String remarks;
private Long addAt;
public MUser(){}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public Long getAddAt() {
return addAt;
}
public void setAddAt(Long addAt) {
this.addAt = addAt;
}
}
4.5 Controller
4.5.1 BaseController
public class BaseController {
private static final long serialVersionUID = 6357869213649815390L;
/**
* @param fastJson
*/
protected JSONObject json = new JSONObject();
/**
* fastjson JSONArray
*/
protected JSONArray jsonArray = new JSONArray();
/**
* fastjson用法
* 對象轉json字符串 String json = json.toJSONString(對象);
* 字符串轉json對象 json =json.parseObject(jsonStr);
* 字符串轉java對象 Object object = JSON.parseObject(jsonStr, Object.class);
* 字符串轉list List<Object> list = JSON.parseArray(jsonStr, Object.class);
*/
}
在這里抽出了一個BaseController的父類,可放置多個Controller都會用到的一些對象或方法,這個父類被子類Controller繼承。目前此項目中的BaseController只放置了fastjson的兩個對象,正常項目中肯定會有不少共有的對象或方法都可放置這里面。
4.5.2 UserController
@Controller
@RequestMapping("/user")
public class UserController extends BaseController {
@Resource(name = "userService")
private UserService userService;
/**
* 添加用戶
*
* @param mUserJson
* @return
* @throws Exception
*/
@RequestMapping(value = "", method = RequestMethod.POST)
@ResponseBody
public String addUser(@RequestBody String mUserJson) throws Exception {
String resultInfo = "";
try {
resultInfo = userService.addUser(mUserJson);
} catch (Exception e) {
e.printStackTrace();
}
return resultInfo;
}
/**
* 通過用戶名稱獲取用戶
*
* @param userName
* @return
* @throws Exception
*/
@RequestMapping(value = "/{userName}", method = RequestMethod.GET)
@ResponseBody
public String getUserByName(@PathVariable String userName) throws Exception {
String resultInfo = "";
try {
resultInfo = userService.getUserByName(userName);
} catch (Exception e) {
e.printStackTrace();
}
return resultInfo;
}
/**
* 修改用戶
*
* @param mUserJson
* @return
* @throws Exception
*/
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
@ResponseBody
public String updateUser(@PathVariable("id") String id, @RequestBody String mUserJson) throws Exception {
String resultInfo = "";
try {
resultInfo = userService.updateUser(id, mUserJson);
} catch (Exception e) {
e.printStackTrace();
}
return resultInfo;
}
/**
* 刪除用戶
*
* @param id
* @return
* @throws Exception
*/
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseBody
public String deleteUser(@PathVariable("id") String id) throws Exception {
String resultInfo = "";
try {
resultInfo = userService.deleteUser(id);
} catch (Exception e) {
e.printStackTrace();
}
return resultInfo;
}
}
這里使用springmvc 相關注解,集成restful風格的接口,具體注解和含義、及restful風格的理解可翻上一篇文章。
與上一篇略有不同的本項目使用的是@Resource注解注入bean。
關于@Resource和@Autowired:
- 兩者都可以寫在字段和setter方法上。兩者如果都寫在字段上,那么就不需要再寫setter方法。
- @Autowired默認按類型裝配(這個注解屬于spring的),默認情況下必須要求依賴對象必須存在,如果要允許null值,可以設置它的required屬性為false,如:@Autowired(required=false)
- @Resource默認安裝名稱進行裝配(這個注解屬于J2EE的),名稱可以通過name屬性進行指定,如果沒有指定name屬性,當注解寫在字段上時,默認取字段名進行安裝名稱查找。
- 在我個人推薦用@Resource,因為這個注解是屬于J2EE的,減少了與spring的耦合,并且代碼看起更優雅。若有高見,歡迎指教。
這個示例代碼實現了增刪改查四個基礎功能,前后端完全以JSON字符串進行交互。(這里前后端以JSON字符串交互的方式有待商榷,以前認知是用JSON字符串便于統一風格;不過最近一年以來的學習和工作,現在會直接使用實體類進行接收對象,免去JSON轉對象的步驟。)
4.6 Service
4.6.1 BaseService
public class BaseService {
private static final long serialVersionUID = 6357869213649815390L;
/**
* 得到32位的uuid
*
* @return
*/
public String get32UUID() {
String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
return uuid;
}
/**
* @param fastJson
*/
protected JSONObject json = new JSONObject();
/**
* fastjson JSONArray
*/
protected JSONArray jsonArray = new JSONArray();
/**
* fastjson用法
* 對象轉json字符串 String json = json.toJSONString(對象);
* 字符串轉json對象 json =json.parseObject(jsonStr);
* 字符串轉java對象 Object object = JSON.parseObject(jsonStr, Object.class);
* 字符串轉list List<Object> list = JSON.parseArray(jsonStr, Object.class);
*/
}
也是抽出了一個父類BaseService,放置共用的對象或方法。這里雖然與BashController內容相似,不過沒有與BaseController共用,因為想到如果項目復雜的話,Controller與Service層共用的東西會有較大差別。
4.6.2 UserService
@Service("userService")
public class UserService extends BaseService {
@Resource(name = "userDaoImpl")
private IUserDao iUserDao;
/**
* 添加用戶
*
* @param mUserJson
* @return
*/
public String addUser(String mUserJson) {
BgyResult br = new BgyResult();
MUser mUser = json.parseObject(mUserJson, MUser.class);
int count = iUserDao.countUserName(mUser);
if (count > 0) {
br.setCode("400");
br.setMsg("用戶名已存在");
return json.toJSONString(br);
}
mUser.setId(get32UUID());
boolean result = iUserDao.addUser(mUser);
if (result) {
br.setCode("200");
br.setMsg("注冊成功");
br.setData(mUser);
} else {
br.setCode("400");
br.setMsg("注冊失敗");
}
return json.toJSONString(br);
}
/**
* 通過用戶名獲取用戶
*
* @param userName
* @return
*/
public String getUserByName(String userName) {
BgyResult br = new BgyResult();
MUser mUser = iUserDao.getUserByName(userName);
br.setCode("200");
br.setMsg("Ok");
br.setData(mUser);
return json.toJSONString(br);
}
/**
* 編輯用戶
*
* @param mUserJson
* @return
*/
public String updateUser(String id, String mUserJson) {
BgyResult br = new BgyResult();
MUser mUser = json.parseObject(mUserJson, MUser.class);
MUser myMUser = iUserDao.getUserById(id);
if (myMUser == null) {
br.setCode("400");
br.setMsg("用戶不存在");
return json.toJSONString(br);
}
boolean result = iUserDao.updateUser(mUser);
if (result) {
br.setCode("200");
br.setMsg("修改成功");
} else {
br.setCode("400");
br.setMsg("修改失敗");
}
return json.toJSONString(br);
}
/**
* 刪除用戶
*
* @param id
* @return
*/
public String deleteUser(String id) {
BgyResult br = new BgyResult();
MUser myMUser = iUserDao.getUserById(id);
if (myMUser == null) {
br.setCode("400");
br.setMsg("用戶不存在");
return json.toJSONString(br);
}
boolean result = iUserDao.deleteUser(id);
if (result) {
br.setCode("200");
br.setMsg("刪除成功");
} else {
br.setCode("400");
br.setMsg("刪除失敗");
}
return json.toJSONString(br);
}
}
這一層主要就是處理業務邏輯了,沒什么特別的地方,也是使用@Resource注入Bean。
這里用到了BgyResult類作為返回類。
4.7 BgyResult
public class BgyResult implements Serializable {
private static final long serialVersionUID = 4832771715671880043L;
private String code;
private String msg;
private Object data;
public BgyResult(){
this.code = "200";
this.msg = "SUCCESS";
this.data = null;
}
public BgyResult(String msg) {
this.code = "400";
this.msg = msg;
this.data = null;
}
public BgyResult(String code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return this.data;
}
public void setData(Object data) {
this.data = data;
}
}
為了統一與前端的交互,定義了BgyResult類進行標準返回,統一返回格式code、msg、data的json字符串。
4.8 Dao
4.8.1 IUserDao
public interface IUserDao {
int countUserName(MUser mUser);
boolean addUser(MUser mUser);
MUser getUserByName(String userName);
MUser getUserById(String id);
boolean updateUser(MUser mUser);
boolean deleteUser(String id);
}
這里就是dao的接口層,用于訪問數據庫,實現數據的持久化。這里提一下,《阿里巴巴Java開發手冊》中寫道:
接口類中的方法和屬性不要加任何修飾符號(public也不要加),保持代碼的簡潔性。
4.8.2 UserDaoImpl
@Repository("userDaoImpl")
public class UserDaoImpl implements IUserDao {
@Resource(name = "dbSqlSessionTemplate")
private SqlSessionTemplate sqlSessionTemplate;
@Override
public int countUserName(MUser mUser) {
return sqlSessionTemplate.selectOne("UserMapper.countUserName", mUser);
}
@Override
public boolean addUser(MUser mUser) {
int num = sqlSessionTemplate.insert("UserMapper.addUser", mUser);
boolean result = false;
if (num > 0) {
result = true;
}
return result;
}
@Override
public MUser getUserByName(String userName) {
MUser mUser = sqlSessionTemplate.selectOne("UserMapper.getUserByName", userName);
return mUser;
}
@Override
public MUser getUserById(String id) {
MUser mUser = sqlSessionTemplate.selectOne("UserMapper.getUserById", id);
return mUser;
}
@Override
public boolean updateUser(MUser mUser) {
int num = sqlSessionTemplate.update("UserMapper.updateUser", mUser);
boolean result = false;
if (num > 0) {
result = true;
}
return result;
}
@Override
public boolean deleteUser(String id){
int num = sqlSessionTemplate.update("UserMapper.deleteUser", id);
boolean result = false;
if (num > 0) {
result = true;
}
return result;
}
}
這個類就是dao接口的具體實現類了,沒什么特別的。使用的是前面配置的SqlSessionTemplate模板化工具,與mapper.xml結合實現操作數據庫。不過這里把所有返回int的操作做了一下boolean轉換,便于service層處理。
4.9 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="UserMapper">
<resultMap id="userMap" type="MUser">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
<result column="nick_name" property="nickName"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phone" property="phone"/>
<result column="sex" property="sex"/>
<result column="status" property="status"/>
<result column="avatar" property="avatar"/>
<result column="remarks" property="remarks"/>
<result column="add_at" property="addAt"/>
</resultMap>
<select id="countUserName" parameterType="MUser" resultType="int">
SELECT COUNT(1) FROM `user` WHERE user_name = #{userName}
</select>
<insert id="addUser" parameterType="MUser">
INSERT INTO `user` (id,user_name,nick_name,password,email,phone,sex,status,avatar,remarks,add_at)
VALUES (#{id},#{userName},#{nickName},#{password},#{email},#{phone},#{sex},#{status},#{avatar},#{remarks},unix_timestamp(now()),unix_timestamp(now()))
</insert>
<select id="getUserByName" resultMap="userMap">
SELECT * FROM `user` WHERE user_name = #{userName}
</select>
<select id="getUserById" resultMap="userMap">
SELECT * FROM `user` WHERE id = #{id}
</select>
<update id="updateUser" parameterType="MUser">
UPDATE
`user`
SET
<if test="nickName != null and nickName != ''">
nick_name = #{nickName},
</if>
<if test="password != null and password != ''">
password = #{password},
</if>
<if test="email != null and email != ''">
email = #{email},
</if>
<if test="phone != null and phone != ''">
phone = #{phone},
</if>
<if test="sex != null and sex != ''">
sex = #{sex},
</if>
<if test="status != null and status != ''">
status = #{status},
</if>
<if test="avatar != null and avatar != ''">
avatar = #{avatar},
</if>
<if test="remarks != null and remarks != ''">
remarks = #{remarks},
</if>
update_at = unix_timestamp(now())
WHERE id = #{id}
</update>
<delete id="deleteUser" parameterType="string">
DELETE FROM `user` WHERE
<if test="_parameter!= null">
id = #{id} AND
</if>
1=1
</delete>
</mapper>
這個是mybatis中sql的映射文件。命名空間即是sqlSessionTemplate.insert("UserMapper.addUser", mUser)中的UserMapper。
上面還提到了使用typeAliases標簽元素來對類型進行別名控制,也就是給具體的實體類一個別名,不用寫完整路徑。在這里的type或者parameterType里寫的MUser就是我們的實體類,如果不使用typeAliases,這里則應寫完整路徑,即
com.bgy.springboot.model.MUser
到此,整個項目的代碼已經編寫完成。實現了最基礎的增刪改查四個功能。
運行項目,測試一下試試。由于springboot內置了tomcat,所以不用單獨放在tomcat中部署。直接運行SpringbootApplication類,即可運行項目。看見這個即表示運行成功:
run.png
下面以postman測試接口
添加用戶
post.png
編輯用戶
put.png
查詢用戶
get.png
刪除用戶
delete.png
至此,基于springboot+springmvc+mybatis框架的項目已經完全整合與測試通過。這個項目結合上一個項目的一些東西,當然也改進了一些東西。項目中涉及到的技術都沒有難點,就算對于新手也很容易搞懂,也有完整的代碼,已測試編譯通過。
編者水平有限,若有錯誤或者更優的建議歡迎指出。
目前全部文章列表:
idea整合restful風格的ssm框架(一)
idea整合restful風格的ssm框架(二)
idea整合spring boot+spring mvc+mybatis框架
idea整合springboot+redis
JVM學習之—Java內存區域
JVM學習之—垃圾回收與內存分配策略
專題整理之—不可變對象與String的不可變
專題整理之—String的字符串常量池