1、介紹java
1.springboot是spring項目的總結+整合mysql
當咱們搭smm,ssh,ssjdbc等組合框架時,各類配置不勝其煩,不只是配置問題,在添加各類依賴時也是讓人頭疼,關鍵有些jar包之間還會出現衝突,讓你的項目出現難以解決的問題。基於這種狀況,springboot橫空出世,在考慮到Struts控制層框架有漏洞,springboot放棄(大多數企業一樣如此)了Struts,轉而代之是springMVC,不過,springboot是自動集成springMVC的,不須要任何配置,不須要任何依賴,直接使用各類控制層註解。springboot是springcloud的基礎,是開啓微服務時代的鑰匙。web
2、新建springboot工程spring
1. 使用idea2019新建project,選擇spring Initializr,nextsql
2. 填寫座標信息,next數據庫
3. web選擇Spring Web Starter,SQL選擇MyBatis Framework、MySQL Driver,nextapi
4. 填寫項目名已經存放位置,finishspringboot
3、使用mybatis generator構建項目restful
1. 數據庫mybatis
建立數據庫
create database ssdj;
建立phone表
CREATE TABLE `phone` ( `id` int(11) NOT NULL AUTO_INCREMENT, `brand` varchar(255) DEFAULT NULL, `user_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `FK_8t3jhwmmlxpq3qcwcy1a3alts` (`user_id`), CONSTRAINT `FK_8t3jhwmmlxpq3qcwcy1a3alts` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
建立user表
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `password` varchar(255) DEFAULT NULL, `username` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
插入數據
user phone
實現了一個用戶擁有多部手機的業務
2. pom.xml
在建立springboot工程建立時勾選的Dependencies會在pom中添加,因此pom.xml基本不須要本身添加依賴
爲pom.xml添加generator插件,其它不用動
<!-- mybatis-generator --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <configuration> <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> </plugin>
springboot方便之處就是「自覺得是」的爲工程添加默認中間件,而且不須要本身添加依賴,不須要寫額外配置,如數據庫鏈接池用的是HirikaCP,其它的中間件用的都是市場上評價最好最穩定的
3. application.properties
在src/main/resource下找到application.properties文件
由於properties文件可讀性差,將其改名爲application.yml,並在其中添加
spring:
profiles:
active: dev
4. application-dev.yml
在resource下建立application-dev.yml文件,並在其中添加
server: port: 8080 spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/ssdj?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*Mapper.xml type-aliases-package: club.xcreeper.ssm_generator_restful.entity
#showSql
logging:
level:
club:
xcreeper:
ssm_generator_restful:
dao:
debug
5. generatorConfig.xml
在resource目錄下建立generatorConfig.xml文件,在其中添加
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 數據庫驅動:換成你本地的驅動包位置--> <classPathEntry location="D:/java/generator/mysql-connector-java-5.1.47.jar"/> <context id="DB2Tables" targetRuntime="MyBatis3"> <commentGenerator> <property name="suppressDate" value="true"/> <!-- 是否去除自動生成的註釋 true:是 : false:否 --> <property name="suppressAllComments" value="true"/> </commentGenerator> <!--數據庫連接URL,用戶名、密碼 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/ssdj?useSSL=false" userId="root" password="root"> </jdbcConnection> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!-- 生成模型的包名和位置--> <javaModelGenerator targetPackage="club.xcreeper.ssm_generator_restful.entity" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成映射文件的包名和位置-->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 生成DAO的包名和位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="club.xcreeper.ssm_generator_restful.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 要生成的表 tableName是數據庫中的表名或視圖名 domainObjectName是實體類名-->
<table tableName="%" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
</context>
</generatorConfiguration>
6. logback-spring.xml
在resource目錄下建立logback-spring.xml文件,在其中添加
<?xml version="1.0" encoding="UTF-8"?> <!-- 日誌級別從低到高分爲TRACE < DEBUG < INFO < WARN < ERROR < FATAL,若是設置爲WARN,則低於WARN的信息都不會輸出 --> <!-- scan:當此屬性設置爲true時,配置文件若是發生改變,將會被從新加載,默認值爲true --> <!-- scanPeriod:設置監測配置文件是否有修改的時間間隔,若是沒有給出時間單位,默認單位是毫秒。當scan爲true時,此屬性生效。默認的時間間隔爲1分鐘。 --> <!-- debug:當此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態。默認值爲false。 --> <configuration scan="true" scanPeriod="10 seconds"> <!--<include resource="org/springframework/boot/logging/logback/base.xml" />--> <contextName>logback</contextName> <!-- name的值是變量的名稱,value的值時變量定義的值。經過定義的值會被插入到logger上下文中。定義變量後,可使「${}」來使用變量。 --> <property name="log.path" value="D:/nmyslog/nmys" /> <!-- 彩色日誌 --> <!-- 彩色日誌依賴的渲染類 --> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> <!-- 彩色日誌格式 --> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <!--輸出到控制檯--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--此日誌appender是爲開發使用,只配置最底級別,控制檯輸出的日誌級別是大於或等於此級別的日誌信息--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>info</level> </filter> <encoder> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> <!-- 設置字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!--輸出到文件--> <!-- 時間滾動輸出 level爲 DEBUG 日誌 --> <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌文件的路徑及文件名 --> <file>${log.path}/log_debug.log</file> <!--日誌文件輸出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 設置字符集 --> </encoder> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 日誌歸檔 --> <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌文件保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日誌文件只記錄debug級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>debug</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 時間滾動輸出 level爲 INFO 日誌 --> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌文件的路徑及文件名 --> <file>${log.path}/log_info.log</file> <!--日誌文件輸出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 天天日誌歸檔路徑以及格式 --> <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌文件保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日誌文件只記錄info級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>info</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 時間滾動輸出 level爲 WARN 日誌 --> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌文件的路徑及文件名 --> <file>${log.path}/log_warn.log</file> <!--日誌文件輸出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 此處設置字符集 --> </encoder> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌文件保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日誌文件只記錄warn級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>warn</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 時間滾動輸出 level爲 ERROR 日誌 --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌文件的路徑及文件名 --> <file>${log.path}/log_error.log</file> <!--日誌文件輸出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 此處設置字符集 --> </encoder> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌文件保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日誌文件只記錄ERROR級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- <logger>用來設置某一個包或者具體的某一個類的日誌打印級別、 以及指定<appender>。<logger>僅有一個name屬性, 一個可選的level和一個可選的addtivity屬性。 name:用來指定受此logger約束的某一個包或者具體的某一個類。 level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 還有一個特俗值INHERITED或者同義詞NULL,表明強制執行上級的級別。 若是未設置此屬性,那麼當前logger將會繼承上級的級別。 addtivity:是否向上級logger傳遞打印信息。默認是true。 --> <!--<logger name="org.springframework.web" level="info"/>--> <!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>--> <!-- 使用mybatis的時候,sql語句是debug下才會打印,而這裏咱們只配置了info,因此想要查看sql語句的話,有如下兩種操做: 第一種把<root level="info">改爲<root level="DEBUG">這樣就會打印sql,不過這樣日誌那邊會出現不少其餘消息 第二種就是單獨給dao下目錄配置debug模式,代碼以下,這樣配置sql語句會打印,其餘仍是正常info級別: --> <!-- root節點是必選節點,用來指定最基礎的日誌輸出級別,只有一個level屬性 level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 不能設置爲INHERITED或者同義詞NULL。默認是DEBUG 能夠包含零個或多個元素,標識這個appender將會添加到這個logger。 --> <!--開發環境:打印控制檯--> <springProfile name="dev"> <logger name="com.xiaog.music4j.dao" level="debug"/> </springProfile> <root level="info"> <appender-ref ref="CONSOLE" /> <appender-ref ref="DEBUG_FILE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="WARN_FILE" /> <appender-ref ref="ERROR_FILE" /> </root> <!--生產環境:輸出到文件--> <!--<springProfile name="pro">--> <!--<root level="info">--> <!--<appender-ref ref="CONSOLE" />--> <!--<appender-ref ref="DEBUG_FILE" />--> <!--<appender-ref ref="INFO_FILE" />--> <!--<appender-ref ref="ERROR_FILE" />--> <!--<appender-ref ref="WARN_FILE" />--> <!--</root>--> <!--</springProfile>--> </configuration>
7. 運行generatorConfig.xml文件,自動生成代碼
在idea工具的頂部 Run - Edit Configurations
在其左上角「+」號裏添加Maven
在Command line中填寫 mybatis-generator:generate -e,ok
在idea頂部 Run - Run 'xxx [mybatis-generator:generate -e]'
ok,再去查看代碼是否生成
若運行generatorConfig.xml報錯,不用驚慌,是你直接複製generatorConfig.xml時出現的空格,只須要將文件全部空格刪除,變成一行,
再從新格式化就行了。
8. 設置實體關係
由於一個用戶擁有多部手機,因此在User實體類中加入private List<Phone> phones; 和 getter、setter
而且去掉Phone實體類中的user_id屬性和其getter、setter
在UserMapper.xml文件中改造ResultMap映射關係
<resultMap id="BaseResultMap" type="club.xcreeper.ssm_generator_restful.entity.User"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="password" jdbcType="VARCHAR" property="password" /> <result column="username" jdbcType="VARCHAR" property="username" /> <collection property="phones" ofType="club.xcreeper.ssm_generator_restful.entity.Phone" column="user_id"> <result column="bid" property="id"/> <result column="brand" property="brand"/> </collection> </resultMap>
而且改造selectByPrimaryKey查詢語句
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select user.*,phone.id as bid,phone.brand from user,phone where user.id = phone.user_id and user.id = #{id,jdbcType=INTEGER} </select>
9. 再編寫service層和controller層便可,可經過postman測試接口
(1)service及其實現
package club.xcreeper.ssm_generator_restful.service; import club.xcreeper.ssm_generator_restful.entity.User;
public interface UserService { User getUser(int id); }
package club.xcreeper.ssm_generator_restful.service.impl;
import club.xcreeper.ssm_generator_restful.dao.UserMapper;
import club.xcreeper.ssm_generator_restful.entity.User;
import club.xcreeper.ssm_generator_restful.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User getUser(int id) {
return userMapper.selectByPrimaryKey(id);
}
}
(2) controller
使用Restful api 風格
package club.xcreeper.ssm_generator_restful.controller; import club.xcreeper.ssm_generator_restful.entity.User; import club.xcreeper.ssm_generator_restful.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping(value = "/getOne/{id}") public User getUser(@PathVariable int id){ return userService.getUser(id); } }
10. 經過postman進行接口測試