如果遺漏了哪些東西,告訴我一聲,哈哈。歡迎加羣一起學習:43827511
- 項目創建
IntelliJ IDEA 首先創建一個項目,創建時選擇Spring Initializr,然後Next,如下圖:
填寫項目信息,如下圖:
填寫項目使用到技術,上面的Spring Boot版本建議選擇最新的穩定版,下面勾選上Web就可以了,如下圖:
最後一步,填寫工程名字點擊Finish:
第一次創建時系統會去下載需要的依賴等,耗時稍長
- 啓動項目
Spring Boot通常有一個名爲*Application的入口類,入口類裏有一個main方法,這個main方法其實就是一個標準的Java應用的入口方法。在main方法中使用SpringApplication.run(PlamanagerApplication.class, args),啓動Spring Boot應用項目。
- @SpringBootApplication
@SpringBootApplication是Spring Boot的核心註解它是一個組合註解:
@SpringBootApplication註解主要組合了
@Configuration
@EnableAutoConfiguration(讓Spring Boot根據類路徑中的jar包依賴爲當前項目進行自動配置)
例如,添加了spring-boot-starter-web依賴,會自動添加Tomcat和SpringMVC的依賴,那麼Spring Boot會對Tomcat和SpringMVC進行自動配置。
又如,添加了spring-boot-starter-data-jpa依賴,Spring Boot會自動進行JPA相關的配置。
Spring Boot會自動掃描@SpringBootApplication所在類的同級包以及下級包裏的Bean。建議入口類放置的位置在groupId+arctifactID組合的包名下。
@ComponentScan主要就是定義掃描的路徑從中找出標識了需要裝配的類自動裝配到spring的bean容器中
- springboot熱部署
spring-boot-devtools是一個爲開發者服務的一個模塊,其中最重要的功能就是自動應用代碼更改到最新的App上面去。
原理是在發現代碼有更改之後,重新啓動應用,但是速度比手動停止後再啓動更快。
其深層原理是使用了兩個ClassLoader,一個Classloader加載那些不會改變的類(第三方Jar包),另一個ClassLoader加載會更改的類,稱爲restart ClassLoader
,這樣在有代碼更改的時候,原來的restart ClassLoader被丟棄,重新創建一個restart ClassLoader,由於需要加載的類相比較少,所以實現了較快的重啓時間。
即devtools會監聽classpath下的文件變動,並且會立即重啓應用(發生在保存時機)
開啓idea自動make功能
1.CTRL + SHIFT + A --> 查找 make project automatically --> 選中
2.CTRL + SHIFT + A --> 查找Registry --> 找到並勾選 compiler.automake.allow.when.app.running
- 添加pom依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
- 開啓熱部署
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--該配置必須-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
- 我的pom文件
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.boot</groupId>
<artifactId>plamanager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>plamanager</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--熱部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--該配置必須-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
- Spring Data JPA簡介
JPA中文名Java持久層API,是JDK 5.0註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中。
Spring Data JPA是Spring Data的一個子項目,它通過提供基於JPA的Repository極大地減少了JPA作爲數據訪問方案的代碼量。
- 添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- 修改配置文件
springboot創建時默認給了一個application.properties配置文件,這個properties格式的文件,好像要多寫好多代碼,所以改用yml後綴的文件
application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/hello?useUnicode=true&characterEncoding=utf-8
username: root
password: ******
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
- pom
只需要在pom.xml引入需要的數據庫配置,就會自動訪問此數據庫,如果需要配置其他數據庫,可以在application.yml
默認使用org.apache.tomcat.jdbc.pool.DataSource創建連接池
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.boot</groupId>
<artifactId>plamanager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>plamanager</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--熱部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--省去get set-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--該配置必須-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
項目結構,我建了幾個包,如下:
- 模型對象Type,就是實體類,在pojo包中
package com.boot.plamanager.pojo;
import lombok.Data;
import javax.persistence.*;
@Data
@Entity
@Table(name = "type")
public class Type {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
}
持久層BaseRepository(封裝的父類),在util包中
package com.boot.plamanager.util;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.io.Serializable;
@NoRepositoryBean
public interface BaseRepository<T,I extends Serializable> extends PagingAndSortingRepository<T,I>,JpaSpecificationExecutor<T> {
}
持久層TypeRepository,在mapper包中
package com.boot.plamanager.mapper;
import com.boot.plamanager.pojo.Type;
import com.boot.plamanager.util.BaseRepository;
public interface TypeRepository extends BaseRepository<Type,Long> {
Type findByName(String name);
}
運行項目,會自動的在數據庫中創建表和字段。
- Spring Data JPA提供的接口
Repository:最頂層的接口,是一個空的接口,目的是爲了統一所有Repository的類型,且能讓組件掃描的時候自動識別
CrudRepository :是Repository的子接口,提供CRUD的功能
PagingAndSortingRepository:是CrudRepository的子接口,添加分頁和排序的功能
JpaRepository:是PagingAndSortingRepository的子接口,增加了一些實用的功能,比如:批量操作等
JpaSpecificationExecutor:用來做負責查詢的接口
Specification:是Spring Data JPA提供的一個查詢規範,要做複雜的查詢,只需圍繞這個規範來設置查詢條件即可
- Repository接口查詢規則
關鍵字 | 案例 | 效果 |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
TRUE | findByActiveTrue() | … where x.active = true |
FALSE | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnam noreCase | … where UPPER(x.firstame) = UPPER(?1) |
- SpringBoot配置Druid連接池簡介
Druid是阿里巴巴開源的數據庫連接池,Druid號稱是Java語言中最好的數據庫連接池,並且能夠提供強大的監控和擴展功能。
支持所有JDBC兼容的數據庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
Druid針對Oracle和MySql做了特別優化,比如:
Oracle的PS Cache內存佔用優化
MySql的ping檢測優化
Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,這是一個手寫的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象語法樹很方便。
簡單SQL語句用時10微秒以內,複雜SQL用時30微秒。
通過Druid提供的SQL Parser可以在JDBC層攔截SQL做相應處理,比如說分庫分表、審計等。
Druid防禦SQL注入攻擊的WallFilter,就是通過Druid的SQL Parser分析語義實現的
添加依賴,(我用的1.1.10,版本錯了可能有坑)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
- 配置application.yml 數據源相關信息
spring:
datasource:
druid:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://cdb-39vuh24q.bj.tencentcdb.com:10059/pladb?useUnicode=true&characterEncoding=utf-8
username: root
password: zhengkai123
type: com.alibaba.druid.pool.DruidDataSource
# 初始化大小,最大,最小
initial-size: 1
max-active: 20
min-idle: 1
# 配置獲取連接等待超時的時間
max-wait: 60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一個連接在池中最小生存的時間,單位是毫秒
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 打開PSCache,並且指定每個連接上PSCache的大小
pool-prepared-statements: true
max-open-prepared-statements: 20
filters:
commons-log.connection-logger-name: stat,wall,log4j
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
server:
port: 8090
- 配置Druid的監控統計功能
DruidConfig.java,在util包中
package com.boot.placms.util;
import java.sql.SQLException;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
public class DruidConfig {
private static final Logger logger = LoggerFactory.getLogger(DruidConfig.class);
private static final String DB_PREFIX = "spring.datasource.druid";
@Bean
public ServletRegistrationBean druidServlet() {
logger.info("init Druid Servlet Configuration ");
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
// IP白名單
servletRegistrationBean.addInitParameter("allow", "192.168.2.25,127.0.0.1");
// IP黑名單(共同存在時,deny優先於allow)
servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
//控制檯管理用戶
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "admin");
//是否能夠重置數據 禁用HTML頁面上的“Reset All”功能
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
@ConfigurationProperties(prefix = DB_PREFIX)
class IDataSourceProperties {
private String url;
private String username;
private String password;
private String driverClassName;
private int initialSize;
private int minIdle;
private int maxActive;
private int maxWait;
private int timeBetweenEvictionRunsMillis;
private int minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private String filters;
private String connectionProperties;
@Bean //聲明其爲Bean實例
@Primary //在同樣的DataSource中,首先使用被標註的DataSource
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
System.err.println("druid configuration initialization filter: " + e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
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 String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
public String getConnectionProperties() {
return connectionProperties;
}
public void setConnectionProperties(String connectionProperties) {
this.connectionProperties = connectionProperties;
}
}
}
Druid 數據源屬性
屬性(Parameter) | 默認值(Default) | 描述(Description) |
---|---|---|
initialSize | 3 | 初始化配置 |
minIdle | 3 | 最小連接數 |
maxActive | 15 | 最大連接數 |
maxWait | 5000 | 獲取連接超時時間(單位:ms) |
timeBetweenEvictionRunsMillis | 90000 | 連接有效性檢測時間(單位:ms) |
testOnBorrow | false | 獲取連接檢測 |
testOnReturn | false | 歸還連接檢測 |
minEvictableIdleTimeMillis | 1800000 | 最大空閒時間(單位ms) |
testWhileIdle | true | 在獲取連接後,確定是否要進行連接空間時間的檢查 |
訪問druid頁面,輸入類中配置的賬號密碼登錄:
http://localhost:8090/druid/index.html
- 配置Mybatis
配置之前,先給數據庫中加點數據,隨便加點就行,用於測試
添加依賴
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
修改application.yml文件,添加mybatis配置
spring:
datasource:
druid:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://cdb-39vuh24q.bj.tencentcdb.com:10059/pladb?useUnicode=true&characterEncoding=utf-8
username: root
password: zhengkai123
type: com.alibaba.druid.pool.DruidDataSource
# 初始化大小,最大,最小
initial-size: 1
max-active: 20
min-idle: 1
# 配置獲取連接等待超時的時間
max-wait: 60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一個連接在池中最小生存的時間,單位是毫秒
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 打開PSCache,並且指定每個連接上PSCache的大小
pool-prepared-statements: true
max-open-prepared-statements: 20
filters:
commons-log.connection-logger-name: stat,wall,log4j
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
server:
port: 8090
## 該配置節點爲獨立的節點,若將這個配置放在spring的節點下,會導致配置無法被識別
mybatis:
mapper-locations: classpath:sqlmap/*.xml #注意:一定要對應mapper映射xml文件的所在路徑
type-aliases-package: com.boot.placms.pojo # 注意:對應實體類的路徑
接下來就是一系列的開發流程,新建了一個jpa包,把TypeRepository放在了jpa包下,做好分類而已,在mapper包中新建TypeMapper.java接口
package com.boot.placms.mapper;
import com.boot.placms.pojo.Type;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @ 描 述 :
* @ 作 者 : 一念〃
* @ 時 間 : 22:40 2018/12/28
* @ 備 注 :
*/
@Mapper
public interface TypeMapper {
Type findByName(@Param("name") String name)throws Exception;
}
新建service包,在其中新建service接口,ITypeService.java
package com.boot.placms.service;
import com.boot.placms.pojo.Type;
/**
* @ 描 述 :
* @ 作 者 : 一念〃
* @ 時 間 : 22:34 2018/12/28
* @ 備 注 :
*/
public interface ITypeService {
Type findByName(String name);
}
在service包中新建impl包,用於實現類的存放,TypeServiceImpl.java
package com.boot.placms.service.impl;
import com.boot.placms.mapper.TypeMapper;
import com.boot.placms.pojo.Type;
import com.boot.placms.service.ITypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @ 描 述 :
* @ 作 者 : 一念〃
* @ 時 間 : 22:35 2018/12/28
* @ 備 注 :
*/
@Service
public class TypeServiceImpl implements ITypeService {
@Autowired
private TypeMapper typeMapper;
/**
* 根據名字查詢返回對象
* @param name
* @return
*/
@Override
public Type findByName(String name) {
Type byName = null;
try {
byName = typeMapper.findByName(name);
} catch (Exception e) {
e.printStackTrace();
}
return byName;
}
}
新建controller包,控制器的存放,TypeController.java
package com.boot.placms.controller;
import com.boot.placms.pojo.Type;
import com.boot.placms.service.ITypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @ 描 述 :
* @ 作 者 : 一念〃
* @ 時 間 : 22:36 2018/12/28
* @ 備 注 :
*/
@Controller
@RequestMapping("/test")
public class TypeController {
@Autowired
private ITypeService typeService;
@RequestMapping("/name")
public Type name(@RequestParam(required=false, value="name") String name){
return typeService.findByName(name);
}
}
在resources文件夾下新建sqlmap包,存放mabatis的xml文件,TypeMapper.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.boot.placms.mapper.TypeMapper">
<resultMap id = "result" type = "com.boot.placms.pojo.Type">
<result property = "id" column = "id"/>
<result property = "name" column = "name"/>
</resultMap>
<select id = "findByName" resultMap="result" parameterType="java.lang.String">
SELECT * FROM type where name = #{name}
</select>
</mapper>
看一下目錄結構:
接下來是測試mybatis,在controller中打個斷點,然後debug模式啓動,訪問controller
http://127.0.0.1:8090/test/name?name=趙山河
訪問後進入斷點:
使用調試工具,New Watch查看對應的值,輸入typeService.findByName(name)後回車,查看所返回的對象
可以看到id是1,name是趙山河,與我們數據庫的數據一致,mybatis配置成功
需要注意的是:
上邊我的mabatis的xml文件存放在resources中的sqlmap文件夾下,就這麼寫就行了:
如果想放在java包下的mapper包下,和mapper接口放在一起,則需要改成:
mybatis:
mapper-locations: classpath:com/boot/placms/mapper/*.xml #注意:一定要對應mapper映射xml文件的所在路徑
type-aliases-package: com.boot.placms.pojo # 注意:對應實體類的路徑
而後在啓動類中添加mapper掃描,如果放在resources下則不需要這樣:
@MapperScan("com.boot.placms.mapper")
// 如果要掃描多個,用下面這種寫法
//@MapperScan(basePackages={"com.boot.placms.mapper", "com.boot.placms.dao"})
還有可能出現的一個錯誤就是:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):com.boot.placms.mapper.TypeMapper.findByName
引起的原因:
就是mybatis報錯,哪裏沒有配置好,需要檢查的地方:
- 檢查mabatis的xml文件,裏面的namespace,resultType,resultMap,parameterType等是否配置正確。
- xml文件與Mapper接口文件的名字一致
- Mapper中的方法名是否與XML文件中的id一致
如果還不行,看一下target文件夾下,xml文件有沒有編譯:
我的是放在resources下的,會被編譯的,放在java包下的我沒試過,如果沒有被編譯,手動在pom文件中的build節點下添加:
<!-- 添加資源標籤,路徑自己看下,這是從網上搜的,沒試過 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
總之,是自己引起的錯誤,與idea編輯器和mybatis無關,自己沒整明白而已。
截止到此,項目已經可以開始擼代碼了,保存一份,以後拿來直接用。
下載鏈接:
鏈接: https://pan.baidu.com/s/15m-lO7onfN23Jb4oNZa-kQ
提取碼: n7xu