SpringData簡介
對於數據訪問層,無論是SQL還是NoSQL,在SpringBoot 底層都是採用SpringData來進行封裝的。
官網地址:https://spring.io/projects/spring-data
使用IDEA構建項目時,我們可以勾選SpringData相關依賴。
如上圖界面所示,Spring提供了很多工具供我們使用,它封裝了大量的模板,在Template Engines
選項中可以勾選需要的模板引擎依賴,IDEA會自動幫我們導入。
JDBC我們選擇了Spring Data JDBC,對應的依賴爲spring-boot-start-data-jdbc
,它本質上和spring-boot-start-jdbc
依賴是一樣的,點擊依賴,我們發現它的底層使用的還是spring-boot-start-jdbc
依賴。
與此同時,可以發現SpringBoot2.x默認的數據源是HikariCP
,其maven依賴如下:
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.2</version>
<scope>compile</scope>
</dependency>
我們還導入了MySQL驅動,需要注意的是MySQL驅動如果不指定版本號,默認使用8.0版本,其maven依賴如下:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
如果不想使用默認版本,加上version即可。
集成JDBC
導入數據庫
1、創建springboot數據庫。
CREATE DATABASE /*!32312 IF NOT EXISTS*/`springboot`
/*!40100 DEFAULT CHARACTER SET utf8 */;
2、創建員工表,插入若干數據。
CREATE TABLE `employee` (
`id` INT(5) NOT NULL AUTO_INCREMENT COMMENT '僱員id',
`last_name` VARCHAR(100) NOT NULL COMMENT '名字',
`email` VARCHAR(100) NOT NULL COMMENT '郵箱',
`gender` INT(2) NOT NULL COMMENT '性別1 男, 0 女',
`department` INT(3) NOT NULL COMMENT '部門id',
`birth` DATETIME NOT NULL COMMENT '生日',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1006 DEFAULT CHARSET=utf8;
3、創建部門表,插入若干數據。
CREATE TABLE `department` (
`id` INT(3) NOT NULL AUTO_INCREMENT COMMENT '部門id',
`department_name` VARCHAR(20) NOT NULL COMMENT '部門名字',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8;
創建項目
1、導入JDBC配置和MySQL驅動。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2、編寫配置文件,注意MySQL8.0以上需要配置時區。
spring:
datasource:
username: root
password: 123456
#注意MySQL8.0以上需要配置時區
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
小技巧:如果記不清楚url,可以在IDEA的Database窗口中測試連接一下,測試成功後下方會顯示完整的數據庫連接地址。
3、測試連接。
@SpringBootTest
class SpringBootDataDemoApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
//查看默認數據源 class com.zaxxer.hikari.HikariDataSource
System.out.println(dataSource.getClass());
Connection connection=dataSource.getConnection();
//connection代表數據源 HikariProxyConnection@64068997 wrapping com.mysql.cj.jdbc.ConnectionImpl@2ae62bb6
System.out.println(connection);
//真實開發更多會去使用數據源
connection.close();
}
}
自動配置核心類
DataSourceConfiguration
:自動配置的數據源DataSourceAutoConfiguration
:自動配置類DataSourceProperties
:配置文件綁定
HikariDataSource
號稱當前Java Web環境中速度最快的數據源,和Druid相比,它的效率會更高一點。
不同的數據源擁有不同的配置,詳細配置可以查看對應數據源的DataSource源碼。
4、測試CRUD,直接編寫Controller進行測試。我們可以使用JdbcTemplate來操作數據庫,它會自動幫我們配置需要的環境,並且封裝了很多操作方法,使用起來十分簡單。
@RestController
@RequestMapping("/jdbc")
public class JdbcController {
//Spring的核心思想之一:xxxTemplate
//xxxTemplate會自動幫我們配置完需要的環境,拿來即用
@Autowired
JdbcTemplate jdbcTemplate;
@GetMapping("/userList")
public List<Map<String,Object>> userList(){
String sql="select * from employee";
List<Map<String,Object>> lists=jdbcTemplate.queryForList(sql);
return lists;
}
//JdbcTemplate會自動幫我們處理事務
@GetMapping("/add")
public String addUser(){
String sql="insert into employee(last_name, email, gender, department, birth)" +
"values ('wunian','[email protected]',1,303,'"+new Date().toLocaleString()+"')";
jdbcTemplate.update(sql);
return "ok";
}
@GetMapping("/update/{id}")
public String updateUser(@PathVariable("id")int id){
String sql="update employee set last_name=?,email=? where id="+id;
//數據
Object[] objects=new Object[2];
objects[0]="wunian";
objects[1]="[email protected]";
jdbcTemplate.update(sql,objects);
return "ok";
}
@GetMapping("/delete/{id}")
public String deleteUser(@PathVariable("id")int id){
String sql="delete from employee where id=?";
jdbcTemplate.update(sql,id);
return "ok";
}
}
集成Druid
Druid簡介
Java程序很多時候都是要操作數據庫的,爲了提高操作數據庫的性能,一般會使用連接池。 Druid 是阿里巴巴的開源組件之一,結合了C3P0,DBCP連接池的優點,並且自帶日誌監控功能,Druid 可以天然的監控 SQL和 數據庫連接池的狀況。
配置參數
DruidDataSource配置屬性如下列表所示:
配置 | 缺省值 | 說明 |
---|---|---|
name | 配置這個屬性的意義在於,如果存在多個數據源,監控的時候可以通過名字來區分開來。如果沒有配置,將會生成一個名字,格式是:“DataSource-” + System.identityHashCode(this). 另外配置此屬性至少在1.0.5版本中是不起作用的,強行設置name會出錯。詳情-點此處。 | |
url | 連接數據庫的url,不同數據庫不一樣。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
username | 連接數據庫的用戶名 | |
password | 連接數據庫的密碼。如果你不希望密碼直接寫在配置文件中,可以使用ConfigFilter。詳細看這裏 | |
driverClassName | 根據url自動識別 | 這一項可配可不配,如果不配置druid會根據url自動識別dbType,然後選擇相應的driverClassName |
initialSize | 0 | 初始化時建立物理連接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時 |
maxActive | 8 | 最大連接池數量 |
maxIdle | 8 | 已經不再使用,配置了也沒效果 |
minIdle | 最小連接池數量 | |
maxWait | 獲取連接時最大等待時間,單位毫秒。配置了maxWait之後,缺省啓用公平鎖,併發效率會有所下降,如果需要可以通過配置useUnfairLock屬性爲true使用非公平鎖。 | |
poolPreparedStatements | false | 是否緩存preparedStatement,也就是PSCache。PSCache對支持遊標的數據庫性能提升巨大,比如說oracle。在mysql下建議關閉。 |
maxPoolPreparedStatementPerConnectionSize | -1 | 要啓用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改爲true。在Druid中,不會存在Oracle下PSCache佔用內存過多的問題,可以把這個數值配置大一些,比如說100 |
validationQuery | 用來檢測連接是否有效的sql,要求是一個查詢語句,常用select ‘x’。如果validationQuery爲null,testOnBorrow、testOnReturn、testWhileIdle都不會起作用。 | |
validationQueryTimeout | 單位:秒,檢測連接是否有效的超時時間。底層調用jdbc Statement對象的void setQueryTimeout(int seconds)方法 | |
testOnBorrow | true | 申請連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能。 |
testOnReturn | false | 歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能。 |
testWhileIdle | false | 建議配置爲true,不影響性能,並且保證安全性。申請連接的時候檢測,如果空閒時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測連接是否有效。 |
keepAlive | false (1.0.28) | 連接池中的minIdle數量以內的連接,空閒時間超過minEvictableIdleTimeMillis,則會執行keepAlive操作。 |
timeBetweenEvictionRunsMillis | 1分鐘(1.0.14) | 有兩個含義: 1) Destroy線程會檢測連接的間隔時間,如果連接空閒時間大於等於minEvictableIdleTimeMillis則關閉物理連接。 2) testWhileIdle的判斷依據,詳細看testWhileIdle屬性的說明 |
numTestsPerEvictionRun | 30分鐘(1.0.14) | 不再使用,一個DruidDataSource只支持一個EvictionRun |
minEvictableIdleTimeMillis | 連接保持空閒而不被驅逐的最小時間 | |
connectionInitSqls | 物理連接初始化的時候執行的sql | |
exceptionSorter | 根據dbType自動識別 | 當數據庫拋出一些不可恢復的異常時,拋棄連接 |
filters | 屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有: 監控統計用的filter:stat 日誌用的filter:log4j 防禦sql注入的filter:wall | |
proxyFilters | 類型是List<com.alibaba.druid.filter.Filter>,如果同時配置了filters和proxyFilters,是組合關係,並非替換關係 |
在項目中配置Druid。
spring:
datasource:
username: root
password: 123456
#?serverTimezone=UTC解決時區的報錯
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默認是不注入這些屬性值的,需要自己綁定
#druid 數據源專有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置監控統計攔截的filters,stat:監控統計、log4j:日誌記錄、wall:防禦sql注入
#如果允許時報錯 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#則導入 log4j 依賴即可,Maven 地址:
#https://mvnrepository.com/artifact/log4j/log4j
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
使用第三方數據源
如果項目中要使用第三方數據源,一般操作步驟如下:
1、導入依賴
2、看源碼配置
3、看官方文檔解釋
4、測試使用
測試
1、導入log4j、Druid依賴。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2、配置數據源,和上面配置Druid一樣。
3、配置數據日誌監控。
//自定義DruidConfig
@Configuration
public class DruidConfig {
//綁定配置的bean
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
//註冊後臺監控頁面,SpringBoot如何註冊Servlet
//沒有web.xml的情況配置Servlet的方法 ServletRegistrationBean
//測試訪問 /druid
@Bean
public ServletRegistrationBean statViewServlet(){
//配置後臺監控頁面
ServletRegistrationBean bean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
Map<String,String> map=new HashMap<>();
//後臺登陸的用戶名和密碼
//用戶名密碼可以放到數據庫
map.put("loginUserName","admin");
map.put("loginPassword","123456");
// 訪問權限
//map.put("allow","localhost");//只允許本機訪問
map.put("allow","");//所有人都可以訪問
//拒絕訪問
//map.put("deny","192.168.1.1")//ip會被拒絕訪問
bean.setInitParameters(map);
return bean;
}
//過濾器配置,看看哪些請求需要被過濾
//沒有web.xml的情況配置filter的方法 FilterRegistrationBean
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean=new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
//配置內容
//配置哪些請求可以被過濾
Map<String,String> map=new HashMap<>();
map.put("exclusions",".js,*.css,/druid/*");
bean.setInitParameters(map);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
4、測試,通過http://localhost:8080/druid來訪問Druid後臺監控頁面。
當我們去訪問一個查詢員工列表的請求時,再回到後臺監控頁面的SQL監控
頁下,可以看到多了一條記錄,詳細記錄了查詢員工列表SQL的各項信息。
集成Mybatis
MyBatis如何使用?
1、導入依賴。
2、編寫MyBatis配置文件。
3、編寫接口。
4、編寫接口Mapper配置文件。
5、註冊Mapper配置文件。
6、測試。
MyBatis-Spring
在Spring中需要集成MyBatis-Spring依賴,上面原生的對象被Spring託管了,直接拿來使用即可。
MyBatis Spring Boot Starter
在maven官網中搜索"MyBatis",可以查到很多MyBatis的依賴,這些依賴都可以使用,我們這裏使用的是MyBatis Spring Boot Starter
官方文檔地址:
- MyBatis:https://mybatis.org/mybatis-3/getting-started.html
- MyBatis-Spring:http://mybatis.org/spring/zh/factorybean.html
- MyBatis Spring Boot Starter:http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/
測試
1.導入依賴,依賴要求:mybatis-spring-boot-starter
2.1版本。
<!--mybatis 自己寫的啓動器不是官方的-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
2、編寫配置文件。
spring:
datasource:
username: root
password: 123456
#?serverTimezone=UTC解決時區的報錯
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默認是不注入這些屬性值的,需要自己綁定
#druid 數據源專有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置監控統計攔截的filters,stat:監控統計、log4j:日誌記錄、wall:防禦sql注入
#如果允許時報錯 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#則導入 log4j 依賴即可,Maven 地址:
#https://mvnrepository.com/artifact/log4j/log4j
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
3、啓動項目,測試是否連接成功。
4、編寫實體類。
@Repository //dao層使用
@Mapper //表示這是一個Mybatis的Mapper
public interface EmployeeMapper{
// @Select("sql") 註解版配置
//獲取全部員工信息
List<Employee> getEmployees();
//新增一個員工信息
int save(Employee employee);
//通過id獲取員工信息
Employee get(Integer id);
//通過id刪除員工信息
int delete(Integer id);
}
5、編寫Mapper.xml文件。SQL語句可以直接在IDEA的DataSource窗口中用鼠標點擊數據庫,點擊上方鉛筆圖標打開console窗口進行編寫,在這裏編寫會有智能提示,可以提升寫SQL的效率。
<?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.wunian.mapper.EmployeeMapper">
<!--多表有映射需要使用resultMap-->
<!--結果集映射-->
<resultMap id="EmployeeMap" type="Employee">
<!--id代表主鍵 property代表對象屬性 column代表數據庫表列名-->
<id property="id" column="eid"/>
<result property="lastName" column="last_name"/>
<result property="email" column="email"/>
<result property="gender" column="gender"/>
<result property="birth" column="birth"/>
<!--對象和集合就需要使用多對一盒一對多的知識
association 關聯對象
collection 集合包含
-->
<association property="eDepartment" javaType="Department">
<id property="id" column="did"/>
<result property="departmentName" column="dname"/>
</association>
</resultMap>
<!--綁定接口中的方法-->
<select id="getEmployees" resultMap="EmployeeMap">
select e.id as eid,last_name,email,gender,birth,d.id as did,d.department_name as dname
from employee e,department d where e.department=d.id
</select>
<insert id="save" parameterType="Employee" >
insert into employee(last_name, email, gender, department, birth)
values (#{lastName}, #{email}, #{gender}, #{department}, #{birth})
</insert>
<select id="get" resultType="Employee">
select * from employee where id= #{id}
</select>
<delete id="delete" parameterType="int">
delete from employee where id= #{id}
</delete>
</mapper>
6、編寫Controller進行測試。
public class EmployeeController {
@Autowired
EmployeeMapper mapper;
//獲取全部員工信息
@GetMapping("/getEmployees")
public List<Employee> getEmployees(){
return mapper.getEmployees();
}
//新增一個員工信息
@GetMapping("/save")
public int save(){
Employee employee=new Employee();
employee.setLastName("wunian");
employee.setEmail("[email protected]");
employee.setGender(1);
employee.setBirth(new Date());
employee.setDepartment(101);
return mapper.save(employee);
}
//通過id獲取員工信息
@GetMapping("/get/{id}")
public Employee get(@PathVariable("id") Integer id){
return mapper.get(id);
}
//通過id刪除員工信息
@GetMapping("/delete/{id}")
public int delete(@PathVariable("id") Integer id){
return mapper.delete(id);
}
}
7、配置MyBatis的配置項。
#配置mybatis的配置
#下劃線轉駝峯
mybatis.configuration.map-underscore-to-camel-case=true
#使用表名的包
mybatis.type-aliases-package=com.wunian.pojo
#mapper配置文件地址,自動掃描
mybatis.mapper-locations=classpath:com/wunian/mapper/xml/*.xml
#mybatis核心配置文件地址,集成Spring之後就不需要了
#mybatis.config-location=
8、解決Maven資源過濾問題。由於Maven默認不支持從src/java目錄下獲取除了代碼之外的配置文件,我們需要在pom文件中過濾一下配置。
<!--配置文件導出-->
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
9、測試運行。