Springboot 第三講 對數據庫的操作

這裏講解三種方式

JDBC操作
整合mybatis操作
使用JPA操作
注意:Demo只寫Service層代碼,操作數據庫爲test,表爲Person
注意:新建的boot項目記得選spring web的起步依賴~

方式一 使用JDBC

1.導入springboot整合JDBC的起步依賴
    <!--導入springboot整合JDBC的起步依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--導入具體的數據庫驅動類  mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

2.編輯application.yml

配置數據源

#配置springboot整合數據庫基於jdbc
spring:
  datasource:
    url: jdbc:mysql:///test?serverTimezone=GMT%2B8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver

3.編寫Service層代碼
package com.demo.service.impl;

import com.demo.bean.Person;
import com.demo.service.PersonService;
import io.swagger.annotations.ApiImplicitParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class PersonServiceImpl implements PersonService {
    //再springboot引入 spring-boot-starter 起步依賴後,就可以採用springboot提供的JDBCTemlate來進行數據庫操作
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //增加
    @Override
    public void add(Person person) {
        jdbcTemplate.update("insert into person(name,age) value (?,?)",person.getName(),person.getAge());

    }

    //修改
    @Override
    public void update(Long id,Person person) {
        jdbcTemplate.update("update person set name=?,age=? where id=?",person.getName(),person.getAge(),id);

    }

    //根據id查找
    @Override
    public Person findOne(Long id) {
        return jdbcTemplate.queryForObject("select * from person where id=?",new BeanPropertyRowMapper<>(Person.class),id);
    }

    //查找全部
    @Override
    public List<Person> findAll() {
        return jdbcTemplate.query("select * from person",new BeanPropertyRowMapper<>(Person.class));
    }

    //根據id刪除
    @Override
    public void Delete(Long id) {
        jdbcTemplate.update("delete from person where id = ?",id);

    }
}

4.在啓動類加個註解

@SpringBootApplication //加載配置文件用的

方式二:使用mybatis

mybatis的操作分爲兩種,使用映射文件,使用註解
1.映射文件的方式
1.引入springboot整合mybatis的起步依賴包

      <!--導入具體的數據庫驅動類  mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
      <!--導入mybatis整合依賴包-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

2.使用逆向工程生成映射文件以及mapper接口還有bean
目錄結構
在這裏插入圖片描述
注意:映射文件指向的位置要一致
在這裏插入圖片描述

3.配置application.yml文件

#配置springboot整合數據庫基於jdbc
spring:
  datasource:
    url: jdbc:mysql:///test?serverTimezone=GMT%2B8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
	
mybatis:
  #指明pojo所在位置
  type-aliases-package: com.demo.bean
  #指明mybatis映射文件所在目錄
  mapper-locations: classpath:com/demo/mapper/*.xml

4.在啓動類加個註解,指明mapper接口的位置
@MapperScan(basePackages = “com.demo.mapper”)
在這裏插入圖片描述
5.這裏就都配置好啦,service和controller這裏就不寫了
2.註解的方式
1.引入springboot整合mybatis的起步依賴包,同上操作
2.配置application.yml文件
這裏只配置數據源

#配置springboot整合數據庫基於jdbc
spring:
  datasource:
    url: jdbc:mysql:///test?serverTimezone=GMT%2B8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver

3.寫mapper類來操作數據庫
這裏使用了註解
@Mapper
@Insert
@Delete()
@Update()
@Select()

package com.demo.mapper;
import com.demo.bean.Person;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface PersonMapper {
	//這裏演示一個插入操作
    @Insert("insert into person(name,age) values (#{name},#{age})")
    public void add(Person p);
}

補充:配置數據源還可以使用Druid連接池 使用type屬性

1.先加依賴

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>

2.使用type屬性添加

#配置springboot整合數據庫基於jdbc
spring:
  datasource:
    url: jdbc:mysql:///test?serverTimezone=GMT%2B8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
	type: com.alibaba.druid.pool.DruidDataSource  #添加連接池
mybatis:
  #指明pojo所在位置
  type-aliases-package: com.demo.bean
  #指明mybatis映射文件所在目錄
  mapper-locations: classpath:com/demo/mapper/*.xml

3.還可以配置其他的屬性

方式三 使用官方的JPA技術

1.導入相關依賴
     <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
               <!--引入阿里的連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.14</version>
        </dependency>
2.配置application.yml文件
#配置springboot整合數據庫基於jdbc
spring:
  datasource:
    url: jdbc:mysql:///youlexuandb?serverTimezone=GMT%2B8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource   #啓用阿里的druid連接池
  jpa:
    hibernate:
      ddl-auto: update
    #在控制檯輸出執行的語句
    show-sql: true


jpa.hibernate.ddl-auto是hibernate的配置屬性,其主要作用是:自動創建、更新、驗證數據庫表結構。該參數的幾種配置如下:
·create:每次加載hibernate時都會刪除上一次的生成的表,然後根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執行,這就是導致數據庫表數據丟失的一個重要原因。
·create-drop:每次加載hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除。
·update:最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以後加載hibernate時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器後,表結構是不會被馬上建立起來的,是要等應用第一次運行起來後纔會。
·validate:每次加載hibernate時,驗證創建數據庫表結構,只會和數據庫中的表進行比較,不會創建新表,但是會插入新值。
到這就配置好了,然後書寫對數據庫的操作代碼

3.創建一個bean

這裏區別於其它多了幾個註解
@Entity @Table @Id @GeneratedValue @Column

package com.demo.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
//Lombok生成getset方法以及有參無參構造函數
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity  //表示當前java類,對應映射到數據庫一張表
@Table(name = "tb_user") //可以重命名生成表的表明,也可以不寫該註解,默認是類名爲表名
public class User implements Serializable {
    @Id   //表示當前屬性id就是一個主鍵
    @GeneratedValue  //數據庫自增
    private Long id;
    @Column(name="name",length =100,nullable = false)
    private String name;
    @Column(name="age",length =4,nullable = false)
    private int age;

    public User(String name,int age){
        this.name = name;
        this.age = age;
    }
}

其它常用註解說明
@Entity 聲明類爲實體或表
@Table 聲明表名
@Basic 指定非約束明確的各個字段
@Embedded 指定類或它的值是一個可嵌入的類的實例的實體的屬性
@Id 指定的類的屬性,用於識別(一個表中的主鍵)
@GeneratedValue 指定如何標識屬性可以被初始化,例如自動、手動、或從序列表中獲得的值
@Transient 指定的屬性,它是不持久的,即:該值永遠不會存儲在數據庫中
@Column 指定持久屬性欄屬性
@SequenceGenerator 指定在@GeneratedValue註解中指定的屬性的值。它創建了一個序列
@TableGenerator 指定在@GeneratedValue批註指定屬性的值發生器。它創造了的值生成的表
@AccessType 這種類型的註釋用於設置訪問類型。如果設置@AccessType(FIELD),則可以直接訪問變量並且不需要getter和setter,但必須爲public。如果設置@AccessType(PROPERTY),通過getter和setter方法訪問Entity的變量
@JoinColumn 指定一個實體組織或實體的集合。這是用在多對一和一對多關聯
@UniqueConstraint 指定的字段和用於主要或輔助表的唯一約束
@ColumnResult 參考使用select子句的SQL查詢中的列名
@ManyToMany 定義了連接表之間的多對多一對多的關係
@ManyToOne 定義了連接表之間的多對一的關係
@OneToMany 定義了連接表之間存在一個一對多的關係
@OneToOne 定義了連接表之間有一個一對一的關係
@NamedQueries 指定命名查詢的列表
@NamedQuery 指定使用靜態名稱的查詢

4.創建一個dao操作類並實現接口

相當於mybatis的mapper接口

package com.demo.dao;

import com.demo.bean.User;
import org.springframework.data.jpa.repository.JpaRepository;

//注意 泛型第一個是指定的類,第二個是主鍵的類型
//這個接口寫好了所有增刪查改的方法
public interface UserDao extends JpaRepository<User,Long> {
    
}

5.寫一個service實現類
package com.demo.service.impl;

import com.demo.bean.User;
import com.demo.dao.UserDao;
import com.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
	//增加
    @Override
    public void add(User user){
        userDao.save(user);
    }
    //修改
    @Override
    public void update(User user){
        userDao.saveAndFlush(user);
    }
	//根據id查找
    public User findOne(Long id){
        return userDao.findById(id).get();
    }
	//根據id刪除
    public void delete(Long id){
        userDao.deleteById(id);
    }
}

6.controller層略

當你啓動啓動類後會發現,數據庫會自動新增兩張表
在這裏插入圖片描述
第一張表是用來存儲自增的id值的
第二張表就是通過註解來自動生成的表

-----------------------------------------------------

JPA的操作非常的簡單,看看dao層,只是實現了接口,增刪查改等基本操作就都實現了,但是有沒有發現一個問題?複雜的查詢或者其它條件查詢並沒有實現,那對於這個問題怎麼處理呢?下面來安排

按照一定命名規範來自定義方法

舉例:新增一個通過姓名來查詢的方法
只需要在userDao類添加一行代碼
public List findByName(String name);

package com.demo.dao;

import com.demo.bean.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

//注意 泛型第一個是指定的類,第二個是主鍵的類型
//這個接口寫好了所有增刪查改的方法
public interface UserDao extends JpaRepository<User,Long> {

    //自動推導,可以根據用戶編寫方法推導出用戶查詢意圖,自動化實現隊應查詢
    public List<User> findByName(String name);


}

可以發現,根本不需要自己寫sql語句,是直接推導出了用戶的意圖直接實現了該方法,所以方法名必須按照約定去命名,這裏就體現了約定大於配置的理念

其它方法命名規則如下圖

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
那麼問題又來了:我就要自己寫sql語句可以嗎?當然是可以的

JPA使用@Query實現自定義查詢語句

這裏有涉及到一個概念:JPQL語句,不能再像以前那種sql語法去寫
在userDao類添加自定義方法
注意:
1.不能寫表明,寫的是bean類名
2.java8版本以上 傳參前面要用@Param標示一下
3.JPQL語句接收參數用 : 參數名 的形式

//根據姓名的模糊查詢
    @Query("select u from  User u where u.name like %:name%")
    public List<User> queryName(@Param("name") String name);
如果想使用原始sql語句,那註解要這樣寫

注意:
1.要設置nativeQuery = true
2.接收參數還是用 : name 的形式

//根據姓名的模糊查詢
    @Query(nativeQuery = true,value = "select * from tb_user where name = :name")
    public List<User> queryname(String name);

補充知識:使用JPA快速的搭建一個Rest風格的接口

1.創建一個boot項目,啓動依賴選三個
在這裏插入圖片描述
2.在pom.xml添加依賴

<!--JPA來處理rest風格所必須的包 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
 <!--bean類快速生成getset方法-->
   <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
   <!--ali提供的連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.14</version>
        </dependency>

3.修改application.properties爲application.yml並添加以下代碼

#配置springboot整合數據庫基於jdbc
spring:
  datasource:
    url: jdbc:mysql:///test?serverTimezone=GMT%2B8
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource   #啓用阿里的druid連接池
  jpa:
    hibernate:
      ddl-auto: update
    #在控制檯輸出執行的語句
    show-sql: true

注意:driver-class-name: com.mysql.cj.jdbc.Driver這裏可能會報錯
解決方法:加個依賴

 <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

4.寫bean類

package com.demo.springbootjparestdemo.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {
    @Id
    @GeneratedValue
    private int id;
    @Column(length = 100,nullable = false)
    private String name;
    @Column(length = 50)
    private double price;
}

5.實現JPA的操作接口類

package com.demo.springbootjparestdemo.dao;

import com.demo.springbootjparestdemo.bean.Car;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CarDao extends JpaRepository<Car,Long> {
}

到這就寫完了!完全不用寫什麼接口實現類
測試:
直接訪問地址
http://localhost:8080/cars/
會出現
在這裏插入圖片描述
就說明成功了
其它測試地址
在這裏插入圖片描述
刪除
delete http://localhost:8080/cars/6

默認的訪問路徑是cars,當然也可以自定義訪問路徑
在操作接口類添加註解
@RepositoryRestResource(path=“www”)
在這裏插入圖片描述
修改後的訪問路徑是http://localhost:8080/www/

也可以自定義方法

在操作接口類添加方法

 @RestResource(path="findbynames")
    List<Car> findByName(@Param("name") String name);

訪問接口
http://localhost:8080/www/search/findbynames?name=本田
注意:訪問接口前多加了一個search

如果想不暴露這些方法

在操作接口類添加註解,多個參數用,隔開
關閉時
@RepositoryRestResource(exported=false)
開啓時
@RepositoryRestResource(exported=true)

配置跨域

直接在實現了Respository接口的類上增加跨域註解@CrossOrigin即可
例:
@CrossOrigin(“http://localhost/9001”)

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