SpringBoot操作數據庫

SpringData簡介

對於數據訪問層,無論是SQL還是NoSQL,在SpringBoot 底層都是採用SpringData來進行封裝的。
官網地址:https://spring.io/projects/spring-data
官網

使用IDEA構建項目時,我們可以勾選SpringData相關依賴。
勾選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後臺監控頁面。
Druid後臺監控頁面
當我們去訪問一個查詢員工列表的請求時,再回到後臺監控頁面的SQL監控頁下,可以看到多了一條記錄,詳細記錄了查詢員工列表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依賴
官方文檔地址:

  • 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-starter2.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、測試運行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章