數據庫連接
數據庫大家都不陌生,從名字就能看出來它是「存放數據的倉庫」,那我們怎麼去「倉庫」取東西呢?當然需要鑰匙啦!這就是我們的數據庫用戶名、密碼了,然後我們就可以打開門去任意的存取東西了。這個時候,我們與數據庫之間的連接就是「數據庫連接」。
這個時候問題就來了,當我們僅僅只需要去取一個東西的時候,我們取完東西隨手關上門,然後拔出鑰匙,這完全是再正常不過的流程了,完全沒毛病,但是,我們大部分時間是需要一件件的把倉庫中的東西搬到外面停放的大卡車上,那這時候我們如果取一件東西把門鎖上,然後再打開門取一件再次鎖上,這有沒有毛病?在我看來,這個邏輯完全正確,沒一點毛病,就是這樣必然會影響我們裝貨的效率嘛!正常人肯定會想到我們不鎖門不就行了,等這批貨裝完了,我們再鎖上門。這可以阿,但是,會不會有安全及其他問題?還有這時候你是否允許別人從你打開的門進入倉庫搬東西?
如果,這時候我們招聘了一個「倉庫管理員」幫忙我們管理會怎樣?當然完美啦,他會在你進入倉庫時給你「授權令」進入,然後可能還會在你出來的時候檢查下你搬的貨物是否正確,並做下記錄以及報表分析,然後你完成時把你的「授權令」還給他,另外一個人進入當然也是這樣的,也並不會影響到你的工作,你倆當然可以同時搬東西,倉庫管理員並不會在你結束的時候鎖上門。
數據庫連接池
其實上面的「倉庫管理員」我就認爲是我們程序世界的數據庫連接池。因爲他手裏拿着大把的進入倉庫的令牌,他給你一個你就能進去,出來後你還給他,他再接着可以給下一個人,這個時候我們倉庫門是一直打開的狀態,省去了大把我們開鎖、開門、關門、鎖門的操作,完全交由一個專業人士管理,更神奇的是他還能記錄你的一系列操作。
看概念:
數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重複使用一個現有的數據庫連接,而不是再重新建立一個;釋放空閒時間超過最大空閒時間的數據庫連接來避免因爲沒有釋放數據庫連接而引起的數據庫連接遺漏。這項技術能明顯提高對數據庫操作的性能。摘自百度百科
在大部分 .Net 開發人心目中,好像並沒有數據庫連接池的概念,只有數據庫連接,然後用完要記得close和用using,在 Java 中有太多的開源的數據庫連接池,而且好像一個吹的比一個厲害。我其實告訴你,其實在 .Net 中 ADO.Net 已經幫我們實現了數據庫連接池,我們並不需要什麼配置,用就是了,但 Java 不一樣,需要我們自己選擇合適的數據庫連接池。下面我說說項目中爲什麼選擇了阿里的 Druid 數據庫連接池。
爲監控而生的數據庫連接池
這是它在 GitHub 上的描述,它有四千多的 Star , 這些並不重要,其實他的監控功能做的很不錯,對開發完成後我們代碼優化提供了大量的參考,至少在數據庫連接層面的提升是明顯可見的。我們曾經把一個耗時半分鐘的查詢優化到毫秒級別,當然這並不是全靠優化數據庫查詢,但它對調優有重要幫助。
網上有很多各個比較常用的連接池的對比,如 c3p0 ,Proxool ,Druid ,Tomcat Jdbc Pool 等等這些,你可以搜到詳細的對比,我這裏不再討論,我提供一個 連接池c3p0 ,Proxool ,Druid ,Tomcat Jdbc Pool對比測試,可以參考。
我覺得這篇文章通俗易懂,推薦像我一樣的小白學習https://www.sohu.com/a/228255918_819383
1. 在pom.xml文件中添加pom依賴:mybatis-spring-boot-starter
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
2. 在application.properties添加mybatis配置項:mybatis.*
# mybatis
mybatis.type-aliases-package=com.xxx.xxx.domain //根據自己的包路徑
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.default-fetch-size=100
mybatis.configuration.default-statement-timeout=3000
mybatis.mapperLocations = classpath:com/xxx/xxx/dao/*.xml //根據自己的包路徑
注意:光有mybatis還是不能訪問數據庫,還需要數據源。
3.引入jdbc和druid的依賴
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.5</version>
</dependency>
4. 配置數據源和連接池druid
#druid連接池
spring.datasource.url=jdbc:mysql://192.168.**.**:3306/miaosha?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false //cmd > ipconfig/all > 查看自己的IP地址
spring.datasource.username=root
spring.datasource.password=****** //自己數據庫的密碼
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.filters=stat
spring.datasource.initialSize=100
spring.datasource.minIdle=500
spring.datasource.maxActive=1000
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=30000
spring.datasource.validationQuery=select 'x'
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
5.測試
新建miaosha數據庫
創建測試表user,並寫入兩條數據。
create table user
(
id INT(20) primary key not null auto_increment,
name varchar(16) DEFAULT NULL
);
controller
在controller裏面寫一個請求測試,創建一個UserService,並且注入到controller裏面
@Controller
@RequestMapping("/demo")//注意!!!加了一個路徑
public class DemoController {
@Autowired
UserService userService;
@RequestMapping("/db/get")
@ResponseBody
public Result<User> dbGet() {
User user = userService.getById(1);
return Result.success(user);
}
@RequestMapping("/db/tx")
@ResponseBody
public Result<Boolean> dbTx() {
userService.tx();
return Result.success(true);
}
}
Service
UserService 裏面注入 userDao
@Service
public class UserService {
@Autowired
UserDao userDao;
public User getById(int id) {
return userDao.getById(id);
}
//使用事務
@Transactional
public boolean tx() {
User user=new User();
user.setId(3);
user.setName("ljs");
userDao.insert(user);
User user1=new User();
user1.setId(1);
user1.setName("ljs2");
userDao.insert(user1); //這裏出問題則回滾
return true;
}
}
userDao
直接使用註解,不需要再去配置xml文件。
@Mapper
public interface UserDao {
@Select("select * from t_user where id=#{id}")//@Param("id")進行引用
public User getById(@Param("id")int id);
@Insert("insert into t_user(id,name) values(#{id},#{name})") //id爲自增的,所以可以不用設置id
public void insert(User user);
}
User Bean
@Getter
@Setter
public class User {
private int id;
private String name;
public User() {
}
public User(int id,String name) {
this.id=id;
this.name=name;
}
}