sql數據庫JDBCTemplate和JPA使用

《SpringBoot實戰派》一書第八章用ORM操作SQL數據庫,具體操作過程和踩坑實錄。
第一,由於本臺計算機上沒有安裝mysql,在練習書中代碼的時候,誤以爲本機不需要數據庫便可以運行代碼,導致卡了好久。
第二,把當時學習Mysql重拾起來,算是學以致用。
第三,遇到問題就一步一步解決問題,有挫敗感正常,學會越挫越勇,轉移挫敗感逐漸找回信心直到正反饋的出現。任何人學習代碼都是這個過程。

0.認識JDBC Template

JDBC(Java DataBase Connectivity)是Java用於連接數據庫的規範,也就是用於執行數據庫SQL語句的Java API。它是由一組用Java語言編寫的類和接口組成,爲大部分關係型數據庫提供訪問接口。

JDBC需要每次進行數據庫連接,然後處理SQL語句、傳值、關閉數據庫。如果都由開發人員編寫代碼,則很容易出錯,可能會出現使用完成之後,數據庫連接忘記關閉的情況。這容易導致連接被佔用而降低性能,爲了減少這種可能的錯誤,減少開發人員的工作量,JDBCTemplate被設計出來。

JDBCTemplate
JDBCTemplate=JDBC+Template,是對JDBC的封裝。它更便於程序實現,替我們完成所有的JDBC底層工作。因此,對於數據庫的操作,再不需要每次都進行連接、打開、關閉了。

JDBC和JDBCTemplate就像倉庫管理員,負責從倉庫中存取物品。而後者不需要每次進入都開門,取完關門,因爲有電動門自動控制。

1.使用JDBCTemplate實現數據的增加、刪除、修改和查詢

項目結構
在這裏插入圖片描述
添加依賴
要使用JDBCTemplate,則需要添加其Starter依賴。因爲要操作數據庫,所有也需要配置數據庫(以mysql爲例)的連接依賴

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
			<version>8.0.20</version>
		</dependency>

添加完依賴之後,還需要配置數據庫的連接信息。這樣JDBC才能正常連接到數據庫。在application.properties配置文件中配置數據庫的地址和用戶信息

//配置ip地址,編碼,時區和SSL
spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
//用戶名
spring.datasource.username=root
//密碼
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

User.java
新建一個測試實體類User,實現RowMapper類,重寫mapRow方法,以便實現字段和數據表字段映射。映射是指把Java中設置的實體字段和mysql數據庫的字段對應起來,因爲實體id可以對應數據庫字段的u_id,也可以對應id、那麼等。如果不重寫,則程序不知道如何對應。

package com.example.demo.model;

import lombok.Data;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;

@Data
public class User implements RowMapper<User> {
    private int id;
    private String username;
    private String password;
    //必須重寫mapRow方法
    @Override

    public User mapRow(ResultSet resultSet,int i) throws SQLException{
        User user=new User();
        user.setId(resultSet.getInt("id"));
        user.setUsername(resultSet.getString("username"));
        user.setPassword(resultSet.getString("password"));
        return  user;
    }
}

JDBCTemplate提供了以下操作數據的3個方法

方法 含義
execute 表示執行,用於直接執行sql語句
update 表示更新,包括新增、修改、刪除操作
query 表示查詢

1)創建數據表
在使用JDBCTemplate之前,需要在控制器中注入JDBCTemplate,然後可以通過execute方法執行sql語句

2)添加數據
通過update方法

3)查詢修改刪除數據
執行sql字符串裏面的SQL語句,通過query,update方法

UserController.java

package com.example.demo.controller;

import com.example.demo.model.User;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)

/**
 * @author longzhonghua
 * @data 2/24/2019 9:51 AM
 */
@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    //創建數據表
    @GetMapping("createUserTable")
    public void createUserTable() throws Exception {
        String sql = "CREATE TABLE `user` (\n" +
                "  `id` int(10) NOT NULL AUTO_INCREMENT,\n" +
                "  `username` varchar(100) DEFAULT NULL,\n" +
                "  `password` varchar(100) DEFAULT NULL,\n" +
                "  PRIMARY KEY (`id`)\n" +
                ") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;\n" +
                "\n";

        jdbcTemplate.execute(sql);

    }

    @Test
    //saveUserTest
    //添加一個測試數據
    @GetMapping("saveUserTest")
    public void saveUserTest()throws Exception  {
        String sql = "INSERT INTO user (USERNAME,PASSWORD) VALUES ('longzhiran','123456')";
        int rows = jdbcTemplate.update(sql);
       System.out.println(rows);
    }


    @Test
    //updateUserPassword?id=1&passWord=12345678
    @GetMapping("updateUserPassword")
    public void updateUserPassword() throws Exception {
        Integer id=1;
        String passWord="999888";
        String sql = "UPDATE user SET PASSWORD = ? WHERE ID = ?";
        int rows = jdbcTemplate.update(sql, passWord, id);
        System.out.println(rows);
    }

    @Test
    //deleteUserById?id=1
    @GetMapping("deleteUserById")
    public void deleteUserById() throws Exception {
        String sql = "DELETE FROM  user  WHERE ID = ?";
        int rows = jdbcTemplate.update(sql, 1);
        System.out.println(rows);
    }


    @Test
    //getUserByName?userName=longzhiran
    @GetMapping("getUserByName")
    public void getUserByName()throws Exception {
        String name="longzhonghua";
        String sql = "SELECT * FROM user WHERE USERNAME = ?";
        List<User> list = jdbcTemplate.query(sql, new User(), new Object[]{name});
       for(User user:list){
           System.out.println(user);
       }
    }



    @Test
    //getAll
    @GetMapping("list")
    public void list() throws Exception {
        String sql = "SELECT * FROM user limit 1000";

        List<User> userList = jdbcTemplate.query(sql,
                new BeanPropertyRowMapper(User.class));
        for(User userLists:userList){
            System.out.println(userLists);
        }
    }

}

運行項目
然後運行test創建數據表
在這裏插入圖片描述
打開book數據庫,發現多了一張名爲user的表
在這裏插入圖片描述

運行測試
在這裏插入圖片描述
在mysql中查看,發現多了一個用戶
在這裏插入圖片描述
運行測試
在這裏插入圖片描述

在mysql中查看,密碼已經修改
在這裏插入圖片描述

運行測試
在這裏插入圖片描述

在mysql中查看
id=1的用戶信息已經刪除
在這裏插入圖片描述

2.用JPA構建mysql實體數據表

第一步:安裝mysql,這裏筆者安裝的是mysql 8.0.20
安裝請移步筆者的另一篇博客:Mysql8.0.20下載和安裝

第二步:創建數據庫book
在這裏插入圖片描述

第三步就是IDEA中的操作

0.添加依賴
需要注意的是:注意mysql的版本需要設置正確

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.20</version>
			<scope>runtime</scope>
		</dependency>

1.配置文件

這裏的數據庫用戶名和密碼是自己的,一般爲root和root



spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true

spring.thymeleaf.cache=false
server.port=8080

當時報錯:

org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

學習《Spring Boot實戰派》時由於沒有本臺電腦上沒有安裝mysql,所以自然連不上,需要先安裝mysql 然後創建數據庫book。

後面踩過的坑
遇到問題

o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: S1009
o.h.engine.jdbc.spi.SqlExceptionHelper   : Unable to load authentication plugin 'caching_sha2_password'.

解決方法:更改mysql依賴的版本

然後接着報錯

o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 08001
o.h.engine.jdbc.spi.SqlExceptionHelper   : Public Key Retrieval is not allowed

解決方案:cmd中登錄mysql數據庫 mysql -u root -p 輸入密碼

又遇到錯誤

o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1049, SQLState: 42000
o.h.engine.jdbc.spi.SqlExceptionHelper   : Unknown database 'book'

新建數據庫book,使得本機存在book數據庫

Article.java

package com.example.demo.entity;

import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

@Entity
@Data
public class Article implements Serializable{
    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(nullable = false,unique = true)
    @NotEmpty(message = "標題不能爲空")
    private String title;

    @Column(columnDefinition = "enum('圖','圖文','文')")
    private String type;

    private Boolean available=Boolean.FALSE;
    @Size(min=0,max=20)
    private String keyword;

    @Size(max=255)
    private String description;
    @Column(nullable = false)
    private String body;

    @Transient
    private List keywordlists;
    public List getKeywordlists(){
        return Arrays.asList(this.keyword.trim().split("|"));
    }

    public void setKeywordlists(List keywordlists){
        this.keywordlists=keywordlists;
    }
}

運行項目之後會生成數據表如下圖
在這裏插入圖片描述

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