SpringData簡介
對于數(shù)據(jù)訪問層伐弹,無論是SQL還是NoSQL愁溜,在SpringBoot 底層都是采用SpringData來進(jìn)行封裝的。
官網(wǎng)地址:https://spring.io/projects/spring-data
使用IDEA構(gòu)建項目時确丢,我們可以勾選SpringData相關(guān)依賴霎箍。
如上圖界面所示,Spring提供了很多工具供我們使用瞬项,它封裝了大量的模板蔗蹋,在
Template Engines
選項中可以勾選需要的模板引擎依賴,IDEA會自動幫我們導(dǎo)入囱淋。JDBC我們選擇了Spring Data JDBC猪杭,對應(yīng)的依賴為
spring-boot-start-data-jdbc
,它本質(zhì)上和spring-boot-start-jdbc
依賴是一樣的妥衣,點擊依賴皂吮,我們發(fā)現(xiàn)它的底層使用的還是spring-boot-start-jdbc
依賴。與此同時税手,可以發(fā)現(xiàn)SpringBoot2.x默認(rèn)的數(shù)據(jù)源是
HikariCP
,其maven依賴如下:
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.2</version>
<scope>compile</scope>
</dependency>
我們還導(dǎo)入了MySQL驅(qū)動蜂筹,需要注意的是MySQL驅(qū)動如果不指定版本號,默認(rèn)使用8.0版本芦倒,其maven依賴如下:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
如果不想使用默認(rèn)版本艺挪,加上version即可。
集成JDBC
導(dǎo)入數(shù)據(jù)庫
1兵扬、創(chuàng)建springboot數(shù)據(jù)庫麻裳。
CREATE DATABASE /*!32312 IF NOT EXISTS*/`springboot`
/*!40100 DEFAULT CHARACTER SET utf8 */;
2口蝠、創(chuàng)建員工表,插入若干數(shù)據(jù)津坑。
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妙蔗、創(chuàng)建部門表,插入若干數(shù)據(jù)疆瑰。
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;
創(chuàng)建項目
1眉反、導(dǎo)入JDBC配置和MySQL驅(qū)動。
<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以上需要配置時區(qū)。
spring:
datasource:
username: root
password: 123456
#注意MySQL8.0以上需要配置時區(qū)
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
小技巧:如果記不清楚url耿币,可以在IDEA的Database窗口中測試連接一下播歼,測試成功后下方會顯示完整的數(shù)據(jù)庫連接地址。
3掰读、測試連接秘狞。
@SpringBootTest
class SpringBootDataDemoApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
//查看默認(rèn)數(shù)據(jù)源 class com.zaxxer.hikari.HikariDataSource
System.out.println(dataSource.getClass());
Connection connection=dataSource.getConnection();
//connection代表數(shù)據(jù)源 HikariProxyConnection@64068997 wrapping com.mysql.cj.jdbc.ConnectionImpl@2ae62bb6
System.out.println(connection);
//真實開發(fā)更多會去使用數(shù)據(jù)源
connection.close();
}
}
自動配置核心類
-
DataSourceConfiguration
:自動配置的數(shù)據(jù)源 -
DataSourceAutoConfiguration
:自動配置類 -
DataSourceProperties
:配置文件綁定
HikariDataSource
號稱當(dāng)前Java Web環(huán)境中速度最快的數(shù)據(jù)源,和Druid相比蹈集,它的效率會更高一點烁试。
不同的數(shù)據(jù)源擁有不同的配置,詳細(xì)配置可以查看對應(yīng)數(shù)據(jù)源的DataSource源碼拢肆。
4减响、測試CRUD,直接編寫Controller進(jìn)行測試郭怪。我們可以使用JdbcTemplate來操作數(shù)據(jù)庫支示,它會自動幫我們配置需要的環(huán)境,并且封裝了很多操作方法鄙才,使用起來十分簡單颂鸿。
@RestController
@RequestMapping("/jdbc")
public class JdbcController {
//Spring的核心思想之一:xxxTemplate
//xxxTemplate會自動幫我們配置完需要的環(huán)境,拿來即用
@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會自動幫我們處理事務(wù)
@GetMapping("/add")
public String addUser(){
String sql="insert into employee(last_name, email, gender, department, birth)" +
"values ('wunian','1796608443@qq.com',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;
//數(shù)據(jù)
Object[] objects=new Object[2];
objects[0]="wunian";
objects[1]="1233@qq.com";
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程序很多時候都是要操作數(shù)據(jù)庫的攒庵,為了提高操作數(shù)據(jù)庫的性能嘴纺,一般會使用連接池。 Druid 是阿里巴巴的開源組件之一浓冒,結(jié)合了C3P0栽渴,DBCP連接池的優(yōu)點,并且自帶日志監(jiān)控功能稳懒,Druid 可以天然的監(jiān)控 SQL和 數(shù)據(jù)庫連接池的狀況闲擦。
配置參數(shù)
DruidDataSource配置屬性如下列表所示:
配置 | 缺省值 | 說明 |
---|---|---|
name | 配置這個屬性的意義在于,如果存在多個數(shù)據(jù)源,監(jiān)控的時候可以通過名字來區(qū)分開來墅冷。如果沒有配置贮缕,將會生成一個名字,格式是:"DataSource-" + System.identityHashCode(this). 另外配置此屬性至少在1.0.5版本中是不起作用的俺榆,強(qiáng)行設(shè)置name會出錯。詳情-點此處装哆。 | |
url | 連接數(shù)據(jù)庫的url罐脊,不同數(shù)據(jù)庫不一樣。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
username | 連接數(shù)據(jù)庫的用戶名 | |
password | 連接數(shù)據(jù)庫的密碼蜕琴。如果你不希望密碼直接寫在配置文件中萍桌,可以使用ConfigFilter。詳細(xì)看這里 | |
driverClassName | 根據(jù)url自動識別 | 這一項可配可不配凌简,如果不配置druid會根據(jù)url自動識別dbType上炎,然后選擇相應(yīng)的driverClassName |
initialSize | 0 | 初始化時建立物理連接的個數(shù)。初始化發(fā)生在顯示調(diào)用init方法雏搂,或者第一次getConnection時 |
maxActive | 8 | 最大連接池數(shù)量 |
maxIdle | 8 | 已經(jīng)不再使用藕施,配置了也沒效果 |
minIdle | 最小連接池數(shù)量 | |
maxWait | 獲取連接時最大等待時間,單位毫秒凸郑。配置了maxWait之后裳食,缺省啟用公平鎖,并發(fā)效率會有所下降芙沥,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖诲祸。 | |
poolPreparedStatements | false | 是否緩存preparedStatement,也就是PSCache而昨。PSCache對支持游標(biāo)的數(shù)據(jù)庫性能提升巨大救氯,比如說oracle。在mysql下建議關(guān)閉歌憨。 |
maxPoolPreparedStatementPerConnectionSize | -1 | 要啟用PSCache着憨,必須配置大于0,當(dāng)大于0時务嫡,poolPreparedStatements自動觸發(fā)修改為true享扔。在Druid中,不會存在Oracle下PSCache占用內(nèi)存過多的問題植袍,可以把這個數(shù)值配置大一些惧眠,比如說100 |
validationQuery | 用來檢測連接是否有效的sql,要求是一個查詢語句于个,常用select 'x'氛魁。如果validationQuery為null,testOnBorrow、testOnReturn秀存、testWhileIdle都不會起作用捶码。 | |
validationQueryTimeout | 單位:秒,檢測連接是否有效的超時時間或链。底層調(diào)用jdbc Statement對象的void setQueryTimeout(int seconds)方法 | |
testOnBorrow | true | 申請連接時執(zhí)行validationQuery檢測連接是否有效惫恼,做了這個配置會降低性能。 |
testOnReturn | false | 歸還連接時執(zhí)行validationQuery檢測連接是否有效澳盐,做了這個配置會降低性能祈纯。 |
testWhileIdle | false | 建議配置為true,不影響性能叼耙,并且保證安全性腕窥。申請連接的時候檢測,如果空閑時間大于timeBetweenEvictionRunsMillis筛婉,執(zhí)行validationQuery檢測連接是否有效簇爆。 |
keepAlive | false (1.0.28) | 連接池中的minIdle數(shù)量以內(nèi)的連接,空閑時間超過minEvictableIdleTimeMillis爽撒,則會執(zhí)行keepAlive操作入蛆。 |
timeBetweenEvictionRunsMillis | 1分鐘(1.0.14) | 有兩個含義: 1) Destroy線程會檢測連接的間隔時間,如果連接空閑時間大于等于minEvictableIdleTimeMillis則關(guān)閉物理連接硕勿。 2) testWhileIdle的判斷依據(jù)安寺,詳細(xì)看testWhileIdle屬性的說明 |
numTestsPerEvictionRun | 30分鐘(1.0.14) | 不再使用,一個DruidDataSource只支持一個EvictionRun |
minEvictableIdleTimeMillis | 連接保持空閑而不被驅(qū)逐的最小時間 | |
connectionInitSqls | 物理連接初始化的時候執(zhí)行的sql | |
exceptionSorter | 根據(jù)dbType自動識別 | 當(dāng)數(shù)據(jù)庫拋出一些不可恢復(fù)的異常時首尼,拋棄連接 |
filters | 屬性類型是字符串挑庶,通過別名的方式配置擴(kuò)展插件,常用的插件有: 監(jiān)控統(tǒng)計用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall | |
proxyFilters | 類型是List<com.alibaba.druid.filter.Filter>软能,如果同時配置了filters和proxyFilters迎捺,是組合關(guān)系,并非替換關(guān)系 |
在項目中配置Druid查排。
spring:
datasource:
username: root
password: 123456
#?serverTimezone=UTC解決時區(qū)的報錯
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 默認(rèn)是不注入這些屬性值的凳枝,需要自己綁定
#druid 數(shù)據(jù)源專有配置
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
#配置監(jiān)控統(tǒng)計攔截的filters,stat:監(jiān)控統(tǒng)計跋核、log4j:日志記錄岖瑰、wall:防御sql注入
#如果允許時報錯 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#則導(dǎo)入 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
使用第三方數(shù)據(jù)源
如果項目中要使用第三方數(shù)據(jù)源砂代,一般操作步驟如下:
1蹋订、導(dǎo)入依賴
2、看源碼配置
3刻伊、看官方文檔解釋
4露戒、測試使用
測試
1椒功、導(dǎo)入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动漾、配置數(shù)據(jù)源,和上面配置Druid一樣荠锭。
3旱眯、配置數(shù)據(jù)日志監(jiān)控。
//自定義DruidConfig
@Configuration
public class DruidConfig {
//綁定配置的bean
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
//注冊后臺監(jiān)控頁面证九,SpringBoot如何注冊Servlet
//沒有web.xml的情況配置Servlet的方法 ServletRegistrationBean
//測試訪問 /druid
@Bean
public ServletRegistrationBean statViewServlet(){
//配置后臺監(jiān)控頁面
ServletRegistrationBean bean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
Map<String,String> map=new HashMap<>();
//后臺登陸的用戶名和密碼
//用戶名密碼可以放到數(shù)據(jù)庫
map.put("loginUserName","admin");
map.put("loginPassword","123456");
// 訪問權(quán)限
//map.put("allow","localhost");//只允許本機(jī)訪問
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());
//配置內(nèi)容
//配置哪些請求可以被過濾
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后臺監(jiān)控頁面。
當(dāng)我們?nèi)ピL問一個查詢員工列表的請求時看蚜,再回到后臺監(jiān)控頁面的
SQL監(jiān)控
頁下叫搁,可以看到多了一條記錄,詳細(xì)記錄了查詢員工列表SQL的各項信息供炎。集成Mybatis
MyBatis如何使用渴逻?
1、導(dǎo)入依賴音诫。
2惨奕、編寫MyBatis配置文件。
3竭钝、編寫接口梨撞。
4、編寫接口Mapper配置文件香罐。
5卧波、注冊Mapper配置文件。
6庇茫、測試港粱。
MyBatis-Spring
在Spring中需要集成MyBatis-Spring依賴,上面原生的對象被Spring托管了旦签,直接拿來使用即可查坪。
MyBatis Spring Boot Starter
在maven官網(wǎng)中搜索"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.導(dǎo)入依賴,依賴要求: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解決時區(qū)的報錯
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 默認(rèn)是不注入這些屬性值的,需要自己綁定
#druid 數(shù)據(jù)源專有配置
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
#配置監(jiān)控統(tǒng)計攔截的filters炭臭,stat:監(jiān)控統(tǒng)計永脓、log4j:日志記錄、wall:防御sql注入
#如果允許時報錯 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#則導(dǎo)入 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窗口中用鼠標(biāo)點擊數(shù)據(jù)庫,點擊上方鉛筆圖標(biāo)打開console窗口進(jìn)行編寫吸申,在這里編寫會有智能提示梗劫,可以提升寫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-->
<!--結(jié)果集映射-->
<resultMap id="EmployeeMap" type="Employee">
<!--id代表主鍵 property代表對象屬性 column代表數(shù)據(jù)庫表列名-->
<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 關(guān)聯(lián)對象
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進(jìn)行測試梳侨。
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("193939@qq.com");
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的配置
#下劃線轉(zhuǎn)駝峰
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默認(rèn)不支持從src/java目錄下獲取除了代碼之外的配置文件,我們需要在pom文件中過濾一下配置束凑。
<!--配置文件導(dǎo)出-->
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
9彼哼、測試運行。