Operación JPA de almacenamiento persistente de datos

JDBC

     La especificación técnica más inferior (en relación con JPA)
     define: la especificación del lenguaje java para conectar una base de datos relacional para la operación de SQL, y cada fabricante de la base de datos implementa la especificación (controlador JDBC) .


MyBatis

     Definición: marco de mapeo SQL basado en Java,
     encapsulando operaciones JDBC.
     La finalización es del método SQL y la implementación es semiautomática .
     Fácil de entender


Hibernar

     Definición: El marco ORM (Object Relational Mapping) basado en Java ,
                  encapsula las operaciones JDBC.
      Tabla de mapeo directo de clase, la implementación es automatizada y altamente encapsulada.

      Persistencia del modelo de dominio para bases de datos relacionales Persistencia del modelo de
       dominio (objetos comerciales) en bases de datos relacionales


JPA

 

   La especificación de Java Persistence API (JPA)
     hibernate es una implementación de referencia de JPA.
    Una implementación de JPA: Hibernate, TopLink,
    
    JPA es una especificación técnica, una definición abstracta. Tales como: bebidas gaseosas, cerveza.
    Hibernate es una implementación. Como Coca-Cola, Sprite.


La conexión entre los tres

   JDBC es una especificación técnica, implementación: mysql, db2, oracle, postgreSQL,
    solo usa la API en JDBC, no puede ver la sombra del fabricante, el trabajo real lo realiza el controlador del fabricante.

    MyBatis: mapeo SQL, en algún punto intermedio.

    Spring Data JDBC

    JPA es una especificación técnica, implementación: hiberbnate, topLink
    Spring Data JPA usa hibernate de forma predeterminada, cambia a la implementación de enlace superior , la codificación solo usa JPA API,
    no puede ver la sombra de hibernate.
 

 


La diferencia entre JDBC y JPA

   JDBC y JPA son especificaciones técnicas definidas en el lenguaje Java. JDBC se conecta a una base de datos relacional y ejecuta el lenguaje SQL.
    JPA está construido sobre JDBC y encapsula las operaciones de los métodos JDBC y JPA. La capa inferior es JDBC.

 La conexión predeterminada de MySQL es 150


Código de demostración

Primero cree un directorio de proyecto, seleccione las dependencias requeridas del proyecto


El directorio del proyecto se muestra en la figura: 

 


 City.java

package com.newer.jpa;

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

/**
 * POJO/Domain Object/使用JPA的注解进行ORM
 * 
 * 实体类映射到表,类的属性映射到表的列,不写 SQL,自动化
 * @author Admin
 *
 */
@Entity
//对应表名
@Table(name = "city")
public class City {
	
	//驼峰式命名法
	//+-------------+----------+------+-----+---------+----------------+
	//| Field       | Type     | Null | Key | Default | Extra          |
	//+-------------+----------+------+-----+---------+----------------+
	//| ID          | int      | NO   | PRI | NULL    | auto_increment |
	//| Name        | char(35) | NO   |     |         |                |
	//| CountryCode | char(3)  | NO   | MUL |         |                |
	//| District    | char(20) | NO   |     |         |                |
	//| Population  | int      | NO   |     | 0       |                |



//	             主键
		@Id
//		自增长
		@GeneratedValue
		Long id;
		
		@Column(name = "name", nullable = true)
		String name;
//		
		String countryCode;
		
//		类中属性名与表中列名一致时,可以不写注解
		String district;
		
		int population;
		
		
		public City() {
			
		}


		public Long getId() {
			return id;
		}


		public void setId(Long id) {
			this.id = id;
		}


		public String getName() {
			return name;
		}


		public void setName(String name) {
			this.name = name;
		}


		public String getCountryCode() {
			return countryCode;
		}


		public void setCountryCode(String countryCode) {
			this.countryCode = countryCode;
		}


		public String getDistrict() {
			return district;
		}


		public void setDistrict(String district) {
			this.district = district;
		}


		public int getPopulation() {
			return population;
		}


		public void setPopulation(int population) {
			this.population = population;
		}


		@Override
		public String toString() {
			return "City [id=" + id + ", name=" + name + ", countryCode=" + countryCode + ", district=" + district
					+ ", population=" + population + "]";
		}

		

		
	

}

CityRepository.java

package com.newer.jpa;

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;

/**
 * 数据持久化 操作
 * @author Admin
 *
 */
@Repository
public interface CityRepository extends PagingAndSortingRepository<City, Long>{

//	CRUD 基本操作 框架已经实现了,不需要你写了
	
//	排序,分页也实现了,不需要你写
	
//	TODO 额外的一些操作,需要自己实现
	
	
}

CityController.java

package com.newer.jpa;



import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Restful API定义实现
 * @author Admin
 *
 */
@RestController
//请求映射
@RequestMapping("/api/city")
public class CityController {

//	依赖service
//	也可以直接注入repository
	@Autowired
	CityRepository cityRepository;
	
	/**
	 * 分页获得数据:GET "/api/city ?p=0&s=20"
	 * 
	 * @RequestParam:字符串查询参数
	 * @param page 页码数,
	 * @param size 一页的记录数
	 * @return 分页信息:数据,总页数,当前页,当前页是否第一页等
	 */
	@GetMapping
	public Page<City> findAll(
			@RequestParam(name = "p" ,defaultValue = "0") int page,
			@RequestParam(name = "s",defaultValue = "300") int size
			) {
//		API是Spring Data设计
//		排序规则
//		order by name,id,desc
		Sort s1=Sort.by("name").ascending().and(Sort.by("id").descending());
		
//		order by name,id
		Sort s2=Sort.by("name","id");
//		分页信息
//		1.页码数,基于0开始的索引
//		2.记录数,20条记录
//		3.排序规则
//		Pageable pageable=PageRequest.of(0, 20,Sort.by("id"))	;
		
		Pageable pageable=PageRequest.of(page, size,Sort.by("id"))	;
		
		 return cityRepository.findAll(pageable);
	}
}

HomeController.java

package com.newer.jpa;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

	@GetMapping("/")
	public String home() {
		return "index.html";
	}
}

index.html

<!doctype html>
<html lang="en">

<head>
    <title>数据分页</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <!-- axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div class="jumbotron jumbotron-fluid">
        <div class="container">
            <h1 class="display-3">数据分页</h1>
            <p class="lead">Vue & Spring Boot &MyBatis& MySQL</p>

        </div>
    </div>
    <div id="app" class="container">
        <h1>{{totalPages}}</h1>
        <!-- 表格 -->
        <table class="table">
            <thead>
                <tr>
                    <th>编号</th>
                    <th>城市</th>
                    <th>国家</th>
                    <th>所在地区</th>
                    <th>人口</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(city, index) in  cityList" :key="index">
                    <td>{{city.id}}</td>
                    <td>{{city.name}}</td>
                    <td>{{city.countryCode}}</td>
                    <td>{{city.district}}</td>
                    <td>{{city.population}}</td>
                </tr>

            </tbody>
        </table>

        <!-- 分页 -->
        <nav aria-label="Page navigation">
            <ul class="pagination justify-content-center">
                <li class="page-item ">
                    <a class="page-link" href="#" aria-label="Previous">
                        <span @click="page(index--)" aria-hidden="true" :class="{active: index===number}">上一页</span>

                    </a>
                </li>
                <!-- 默认的样式 -->
                <!-- <li class="page-item active"><a class="page-link" href="#">当前</a></li> -->


                <li v-for="(n, index) in  totalPages" :key="index" class="page-item" :class="{active: n-1===number}">

                    <a @click="page(n-1)" class="page-link" href="#">
                        {{n}}
                    </a>
                </li>
                <li class="page-item">
                    <a class="page-link" href="#" aria-label="Next">
                        <span @click="page(index++)" aria-hidden="true" :class="{active: index===number}">下一页</span>

                    </a>
                </li>
            </ul>
        </nav>

    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                cityList: [],
                // 总页数
                totalPages: '',
                // 当前页
                number: '',
                index: 1
            },
            methods: {
                page: function (num) {

                    axios.get('/api/city', {
                        params: {
                            p: num
                        }
                    })
                        .then(res => {
                            // console.log(res);
                            this.cityList = res.data.content;
                            this.totalPages = res.data.totalPages;
                            this.number = res.data.number;
                        })
                },

                next: function (i) {
                    axios.get('/api/city', {
                        params: {
                            p: i
                        }
                    })
                        .then(res => {
                            console.log(res);
                        })
                }
            },
            created() {
                // 本地URL
                let url = '/api/city';
                axios.get(url)
                    .then(res => {
                        console.log(res)
                        this.cityList = res.data.content;
                        this.totalPages = res.data.totalPages;
                        this.number = res.data.number;
                    })
                    .catch(err => {
                        console.error(err);
                    })
            },
        })

    </script>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
        integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
        integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
        crossorigin="anonymous"></script>
</body>

</html>

application.properties

#数据源
spring.datasource.url=jdbc:mysql://阿里云数据库ip:3306/world
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#请求参数
spring.http.log-request-details=true

#Spring MVC
logging.level.web=debug

#数据源默认的数据库连接池信息
logging.level.com.zaxxer=debug

#hibernate(JPA)
logging.level.org.hibernate.sql=debug

#jpa/hibernate 驼峰命名规则的映射
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

Ahora podemos ver el efecto:

Datos obtenidos de la base de datos.


Representación en el front-end: (previamente establecido en 300 registros por página)

 

125 artículos originales publicados · elogiados 279 · más de 20,000 visitas

Supongo que te gusta

Origin blog.csdn.net/weixin_44364444/article/details/105450845
Recomendado
Clasificación