先講些廢話###
- 距離發表上一篇SpringBoot的文章已經時隔一年多了,在那之后再也沒在實際項目中用到過SpringBoot,基本上在公司里面用的都是普通的SSM,在這之間也換了幾家公司,第二家真的是呆了兩個月就呆不下去了(Spring+xwork+Hibernate以及 JSP+ExtJS 這么老的東西真的受不了)這些都是題外話,反正就是想說基本接觸不到SpringBoot。現在回頭看我一年前寫的那篇文章真的是亂七八糟的23333,不知道那么多看了的人是什么想法,被誤導了不少吧哈哈哈哈。
- 好了,現在開始重新寫一篇簡單的SpringBoot+MyBatis整合當然基于Maven來管理項目。重新開始寫這篇文章的原因是我想自己做一套屬于自己的賬單管理系統,思來想去如果在業余時間用普通的SSM來開發比較費時,而且部署的時候也比較麻煩。何不用輕量化的SpringBoot呢,這樣一來業余時間也能學到不少新知識,畢竟
大部分公司不太喜歡用這種新技術。廢話那么多,下面開始正題。 - 本文盡量精簡,保證能運行且功能都有。后續新增也有可能的喲
SpringBoot+MyBatis整合篇##
1. 首先是pom文件配置,引入必須的jar依賴-應該是最簡化了:###
<?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">
<parent>
<artifactId>billing</artifactId>
<groupId>com.tony.billing</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<properties>
<!-- 這里配置啟動類和版本號 -->
<start.class>com.tony.billing.Application</start.class>
<service.version>1.0-SNAPSHOT</service.version>
<!-- 防止打包之后因為編碼問題變亂碼 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 這里指定SpringBoot和MyBatis相關的版本,這兩個會自動引入相關的Spring,SpringMVC,MyBatis等依賴 -->
<spring-boot.version>1.5.3.RELEASE</spring-boot.version>
<mybatis-spring-boot.version>1.3.0</mybatis-spring-boot.version>
<!-- 引入mysql-jdbc -->
<mysql-connector.version>6.0.6</mysql-connector.version>
<!-- 后面可以再引入一些工具類什么的,這里省略 需要說明的是springboot好像是自帶logback和slf4j依賴的,版本沒要求的話可以不用再顯示引入-->
</properties>
<artifactId>web</artifactId>
<dependencies>
<!-- springboot可以只導入這兩個依賴便能啟動,很方便 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 這個插件是springboot針對maven打包的,和上面${start.class}配套 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 這個是maven編譯的配置不多廢話,可以自己查閱相關內容 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. 然后是application.yml配置[這個YAML配置還不是特別熟悉,只是做做基本的介紹]詳細的可以再查閱其他資料
# Server settings
server:
port: 8080
address: localhost
tomcat:
uri-encoding: utf-8
# SPRING PROFILES
spring:
# HTTP ENCODING
http:
encoding.charset: UTF-8
encoding.force: true
encoding.enabled: true
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
# 需要說明的是mysql-jdbc 6.0+需要添加serverTimezone=UTC不然會因為時區問題報錯,這里用了CTT中國臺灣時區避免產生8小時時差
url: jdbc:mysql://localhost:3306/my_2017_cost?serverTimezone=CTT&characterEncoding=utf8&useUnicode=true&useSSL=false
username: root
password: password
# MyBatis
mybatis:
#指定實體類地址
typeAliasesPackage: com.tony.billing.entity
#指定SqlMap映射文件位置
mapperLocations: classpath:/sqlMapper/*SqlMap.xml
#指定mysql-config配置文件
configLocation: classpath:/mybatis-config.xml
3. mybatis-config.xml 沒啥特別的 依舊照搬老的
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>
<property name="dialect" value="mysql" />
</properties>
<settings>
<!-- 這個配置使全局的映射器啟用或禁用緩存。系統默認值是true,設置只是為了展示出來 -->
<setting name="cacheEnabled" value="true" />
<!-- 全局啟用或禁用延遲加載。當禁用時,所有關聯對象都會即時加載。 系統默認值是true,設置只是為了展示出來 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 允許或不允許多種結果集從一個單獨的語句中返回(需要適合的驅動)。 系統默認值是true,設置只是為了展示出來 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!--使用列標簽代替列名。不同的驅動在這方便表現不同。參考驅動文檔或充分測試兩種方法來決定所使用的驅動。 系統默認值是true,設置只是為了展示出來 -->
<setting name="useColumnLabel" value="true" />
<!--允許 JDBC 支持生成的鍵。需要適合的驅動。如果設置為 true 則這個設置強制生成的鍵被使用,盡管一些驅動拒絕兼容但仍然有效(比如
Derby)。 系統默認值是false,設置只是為了展示出來 -->
<setting name="useGeneratedKeys" value="false" />
<!--配置默認的執行器。SIMPLE 執行器沒有什么特別之處。REUSE 執行器重用預處理語句。BATCH 執行器重用語句和批量更新 系統默認值是SIMPLE,設置只是為了展示出來 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!--設置超時時間,它決定驅動等待一個數據庫響應的時間。 系統默認值是null,設置只是為了展示出來 -->
<setting name="defaultStatementTimeout" value="25000" />
</settings>
</configuration>
- 這里不再用自動代碼生成了,為了方便維護還是老老實實的自己寫比較好哦,當然也可以偷懶自己寫一個代碼生成工具這里不再詳述。
4. Logback.xml配置 目前來看logback是替代log4j的存在,很多方面比后者好。
- 具體配置也是基本照搬網上的,為了盡量精簡也沒有對不同類別的內容進行區分。深入的內容依舊是不再詳述,請自行查閱資料 【傲嬌臉】
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<logger name="org.springframework.web" level="INFO" />
<!--定義日志文件的存儲地址 勿在 LogBack 的配置中使用相對路徑-->
<property name="LOG_PATH" value="/home/billing/logs/" />
<!-- 控制臺輸出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日志消息,%n是換行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件輸出的文件名-->
<FileNamePattern>${LOG_PATH}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天數-->
<maxHistory>15</maxHistory>
<totalSizeCap>30MB</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 異步記錄文件 -->
<appender name="asyncFileAppender" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>500</queueSize>
<appender-ref ref="FILE" />
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="asyncFileAppender" />
</root>
<!-- 這個配置比較關鍵,對dao配置成DEBUG打印sql語句,方便調試查錯 -->
<logger name="com.tony.billing.dao" level="DEBUG">
</logger>
</configuration>
后面自上而下說明Java代碼
5. Application.java 主方法
@SpringBootApplication // 注釋為SpringBoot啟動類
@ComponentScan // 自動掃描
@MapperScan("com.tony.billing.dao.mapper") // 自動隱射sqlMap到com.tony.billing.dao.mapper下面,不用再寫更多的代碼配置mybatis很方便
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// 這個方法還是比較實用的,就是在@ResponseBody轉換json的時候不打印null的內容
@Bean
public ObjectMapper jsonMapper() {
ObjectMapper objectMapper = new ObjectMapper();
// null 不輸出
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return objectMapper;
}
}
6. HelloWorldController.java 實現最基本的登陸功能
- 調用AdminService
@RestController // 這個是@ResponseBody和@Controller的合并,不用再在每個方法上面重復寫@ResponseBody
public class HelloWorldController extends BaseController {
@Resource
private AdminService adminService;
@RequestMapping(value = "/user/login", method = RequestMethod.POST)
public BaseResponse login(@ModelAttribute("request") AdminLoginRequest request, HttpServletResponse httpServletResponse) {
BaseResponse response = new BaseResponse();
try {
Admin loginAdmin = new Admin();
loginAdmin.setUserName(request.getUserName());
loginAdmin.setPassword(Md5Util.md5(request.getPassword()));
Admin admin = adminService.login(loginAdmin);
if (admin != null) {
ResponseUtil.success(response);
} else {
ResponseUtil.error(response);
}
} catch (Exception e) {
logger.error("/user/login error", e);
ResponseUtil.sysError(response);
}
return response;
}
@RequestMapping(value = "/hello/world", method = RequestMethod.GET)
public BaseResponse helloWorld() {
BaseResponse response = new BaseResponse();
response.setMsg("HelloWorld");
response.setCode("1024");
return response;
}
}
7. AdminServiceImpl.java 實現最基本的登陸功能,AdminService接口內容就不貼了一眼就能看出來是啥
- 調用AdminDao
@Service
public class AdminServiceImpl implements AdminService {
@Resource
private AdminDao adminDao;
@Override
public Admin login(Admin admin) {
// 正常來說,這里應該是控制在一個事務里面的需要注意
Admin checkUser = adminDao.preLogin(admin);
if (checkUser != null) {
if (adminDao.doLogin(checkUser) > 0) {
return checkUser;
}
}
return null;
}
}
8. AdminDaoImpl內容 實現登陸校驗和執行登陸操作
@Service("adminDao")
public class AdminDaoImpl implements AdminDao {
@Resource
private AdminMapper adminMapper;
@Override
public Long doLogin(Admin admin) {
return adminMapper.doLogin(admin);
}
@Override
public Admin preLogin(Admin admin) {
admin.setLastLogin(new Date());
return adminMapper.preLogin(admin);
}
}
9. AdminMapper的話就是個接口 對應到SqlMap.xml文件
@Repository // 需要加上注釋,其實就是組件
public interface AdminMapper {
Long doLogin(Admin admin);
Admin preLogin(Admin admin);
}
10. AdminSqlMap.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" >
<!-- 這里namespace需要對應到Mapper不然無法正常運行,下面的id也是要和Mapper定義的方法名一一對應,詳細內容都是可以去網上查到的 -->
<mapper namespace="com.tony.billing.dao.mapper.AdminMapper">
<sql id="all">
id id,
tokenId tokenId,
tokenVerify tokenVerify,
code code,
userName userName,
password password,
lastLogin lastLogin,
createTime createTime,
modifyTime modifyTime,
version version,
isDeleted isDeleted
</sql>
<update id="doLogin" parameterType="com.tony.billing.entity.Admin">
UPDATE t_admin
SET lastLogin = #{lastLogin,jdbcType=TIMESTAMP},
WHERE
userName = #{userName,jdbcType=VARCHAR}
AND password = #{password,jdbcType=VARCHAR}
AND isDeleted = 0
</update>
<select id="preLogin" parameterType="com.tony.billing.entity.Admin" resultType="com.tony.billing.entity.Admin">
SELECT
<include refid="all"/>
FROM t_admin
WHERE userName = #{userName,jdbcType=VARCHAR}
AND password = #{password,jdbcType=VARCHAR}
AND isDeleted = 0
</select>
</mapper>
至此,基本的配置和代碼都已經完成。
在ide中運行或者maven打包后 java -jar運行
然后可以訪問http://localhost:8080/hello/world,得到喜聞樂見的內容:
{"msg":"HelloWorld","code":"1024"}
也可以用post方法試試登陸,當然需要自己在數據庫建表并里面插入相應一條能登陸的數據【太過簡單內容丟失了~】
致辭
- 感謝各位讀者不嫌棄我一年前寫的那篇亂七八糟的文章,鞠躬~
- 雖然過了一年多,我依舊還是個初學者,本文如有錯誤歡迎指正。
- 更多源碼詳見GitHub:https://github.com/TonyJiangWJ/BillingServer 尚處于開發狀態!
- ...