前言:谈起操作数据库,大致可以分为几个阶段:首先是JDBC阶段,初学JDBC可能会使用原生的JDBC的API,再然后可能会使用数据库连接池,比如:C3P0,DBCP,还有一些第三方工具,比如dbutils等,楼主认为JDBC是贯穿始终的,即使到了框架部分,也会对JDBC进行整合,此阶段还是自己手写SQL语句;下一个阶段就是休眠,大家体会到了操作数据库可以不用自己手动编写SQL,调用Hibernate提供的API即可。今天给大家介绍的是操作数据库的另一个模块JPA,即Java持久层的API,JPA如果与SpringData结合起来,会发出不一样的“化学反应”,大家拭目以待〜

官方网站对 SpringData JPA的特点描述:(SpringData JPA)

springboot 操作数据库时锁定表 springboot如何操作数据库_JPA


一,JPA概述


1. Java持久性API(Java持久层API):用于对象持久化的API



2.作用:使得应用程序以统一的方式访问持久层



3。前言中提到了Hibernate,那么JPA与Hibernate的关系是什么关系呢:



1)JPA是Hibernate的一个抽象,就像JDBC和JDBC驱动的关系



2)JPA是一种ORM规范,是Hibernate功能的一个子集(既然JPA是规范,Hibernate对JPA进行了扩展,那么说JPA是Hibernate的一个子集不为过)



3)Hibernate是JPA的一个实现



4。JPA包括三个方面的技术:



1)ORM映射元数据,支持XML和JDK注解两种元数据的形式



2)JPA的API



3)查询语言:JPQL



二、项目框架搭建

1.新建springboot项目

springboot 操作数据库时锁定表 springboot如何操作数据库_JPA_02

二,代码管理

springboot 操作数据库时锁定表 springboot如何操作数据库_spring_03

1.创建Userinfo实体类

package cn.liumce.springbootjpa.entity;


import javax.persistence。*;

/ **
 * @Entity:代表这个类是一个实体类
 * @Table(name =“userinfos):这个注解代表对应表的名称,userinfos就是利用jpa要生成的表名称
 * @id:表示此属性是主键
 * @GeneratedValue:表示的是主键生成策略,默认主键是自增长的,当然你也可以用uuid
 * @Column:表明此属性在数据库中对应的字段,如果实体中的属性与数据库的字段一样,可以省略不写。
 * /
@实体
@Table(name =“userinfos”)
公共类Userinfo {

    @ID
    @GeneratedValue
    @Column(name =“id”)
    private Integer id; //主键

    @Column(name =“user_name”)
    私有String用户名; //用户名

    @Column(name =“user_pass”)
    private String userpass; //密码

    public Integer getId(){
        返回id;
    }

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

    public String getUsername(){
        返回用户名;
    }

    public void setUsername(String username){
        this.username = username;
    }

    public String getUserpass(){
        return userpass;
    }

    public void setUserpass(String userpass){
        this.userpass = userpass;
    }
}

2.控制器在包中创建³³ 的的IndexController类

package cn.liumce.springbootjpa.web.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//此注解默认返回JSON数据
@RestController
//返回页面
// @控制器
公共类IndexController {

    @RequestMapping( “索引”)
    public String index(){
       回归“你好世界”;
       //返回“index”;
    }
}

3.在库包中创建UserinfoRepository类

package cn.liumce.springbootjpa.repository;

import cn.liumce.springbootjpa.entity.Userinfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

/ *
    实现增删改查
    @Transactional开启事务
    @Modifying修改方法专用注解
    @Query(“”)书写JPAsql语句,其中Userinfo是实体类名,
                   为userpass和ID是实体类的属性名,
                   ?1代表是第一个参数?2是第二个参数。
 * /
public interface UserinfoRepository扩展了JpaRepository <Userinfo,Integer> {
    @Transactional
    @Modifying
    @Query(“apdate Userinfo u set u.userpass =?1其中u.id =?2”)
    int updateById(String userpass,int id);

}

4.我的application.properties是这样的:

#服务器端口
server.port = 8080
spring.datasource.url = JDBC:MySQL的://127.0.0.1:3306 /分贝了useUnicode =真的characterEncoding = UTF-8
spring.datasource.username =根
spring.datasource.password = 1
spring.datasource.driver类名= com.mysql.jdbc.Driver

################################################## ######
### Java Persistence Api  -  Spring jpa的配置信息
#其实这个hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构,有四个值
#create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的模型类再重新来生成新表,哪怕两次没有任何改变也要这样执行,
#这就是导致数据库表数据丢失的一个重要原因。
#create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
#UPDATE:最常用的属性,第一次加载休眠时根据模型类会自动建立起表的结构(前提是先建立好数据库),
#以后加载hibernate时根据model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。
#要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
#validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
#dialect主要是指定生成表名的存储引擎为InneoDB
#show-sql是否打印出自动生产的SQL,方便调试的时候查看
################################################## ######
spring.jpa.properties.hibernate.hbm2dd1.auto =更新
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-SQL =真

#页面默认前缀目录
spring.mvc.view.prefix = / WEB-INF /视图/
#页面默认后缀目录
spring.mvc.view.suffix = .JSP

5.pom.xml文件

<?xml version =“1.0”encoding =“UTF-8”?>
<project xmlns =“http://maven.apache.org/POM/4.0.0”xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”
	xsi:schemaLocation =“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
	<modelVersion> 4.0.0 </ modelVersion>

	<的groupId> cn.liumce </的groupId>
	<artifactId的> springboot-JPA </ artifactId的>
	<版本> 0.0.1-SNAPSHOT </版本>
	<包装>罐</包装>

	<名称> springboot-JPA </名称>
	<description> Spring Boot的演示项目</ description>

	<母体>
		<的groupId> org.springframework.boot </的groupId>
		<artifactId的>弹簧引导起动父</ artifactId的>
		<版本> 1.5.14.RELEASE </版本>
		<relativePath /> <! - 从存储库查找父级 - >
	</父>

	<性能>
		<project.build.sourceEncoding> UTF-8 </project.build.sourceEncoding>
		<project.reporting.outputEncoding> UTF-8 </project.reporting.outputEncoding>
		<java.version> 1.8 </java.version>
	</属性>

	<依赖性>
		<依赖性>
			<的groupId> org.springframework.boot </的groupId>
			<artifactId的>弹簧引导起动数据JPA </ artifactId的>
		</依赖性>
		<依赖性>
			<的groupId> org.springframework.boot </的groupId>
			<artifactId的>弹簧引导起动的Web </ artifactId的>
		</依赖性>

		<依赖性>
			<的groupId>的MySQL </的groupId>
			<artifactId的> MySQL的连接器的Java </ artifactId的>
			<范围>运行时</范围>
		</依赖性>
		<依赖性>
			<的groupId> org.springframework.boot </的groupId>
			<artifactId的>弹簧引导起动测试</ artifactId的>
			<范围>测试</范围>
		</依赖性>
		<! -  servlet依赖包 - >
		<依赖性>
			<的groupId>的javax.servlet </的groupId>
			<artifactId的>的javax.servlet-API </ artifactId的>
			<范围>提供</范围>
		</依赖性>
		<! -  JSTL(JSP标准标签库)JSP标准标签库 - >
		<依赖性>
			<的groupId>的javax.servlet </的groupId>
			<artifactId的> JSTL </ artifactId的>
		</依赖性>
		<! -  Tomcat的支持 - >
		<依赖性>
			<的groupId> org.springframework.boot </的groupId>
			<artifactId的>弹簧引导起动的Tomcat </ artifactId的>
		</依赖性>
		<依赖性>
			<的groupId> org.apache.tomcat.embed </的groupId>
			<artifactId的> Tomcat的嵌入-碧玉</ artifactId的>
		</依赖性>
	</依赖>

	<建立>
		<插件>
			<插件>
				<的groupId> org.springframework.boot </的groupId>
				<artifactId的>弹簧引导行家-插件</ artifactId的>
			</插件>
		</插件>
	</建造>


</项目>

6.如果你返回的是页面,那么在模块里添加网络服务器,更改路径后在WEB-INF /观点下创建的jsp界面。再到控制器类中修改,将注解@RestController改为@Controller。

注:这里@RestController与@Controller的区别:

@RestController是一个结合@ResponseBody和@Controller的构造型注释。
意思是:
@RestController注解相当于@ResponseBody + @Controller合在一起的作用。

1)如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,配置的视图解析器InternalResourceViewResolver不起作用,返回的内容就是返回里的内容。
例如:本来应该到的success.jsp页面的,则其显示成功。

2)如果需要返回到指定页面,则需要用@Controller配合视图解析器InternalResourceViewResolver才行。
3)如果需要返回JSON,XML或自定义mediaType的内容到页面,则需要在对应的方法上加上@ResponseBody注解。

三,测试

1.找到UserinfoRepository类,如图操作

springboot 操作数据库时锁定表 springboot如何操作数据库_spring_04

2.在测试包生成的UserinfoRepositoryTest测试类中,做对数据库的增删改查测试。

package cn.liumce.springbootjpa.repository;

import cn.liumce.springbootjpa.entity.Userinfo;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

import static org.junit.Assert。*;

@RunWith(SpringRunner.class)
//例如你的主方法的应用程序是xxxApplication.java,classes就要等于xxxApplication.class
@SpringBootTest(classes = SpringBootApplication.class)
公共类UserinfoRepositoryTest {

    / **
     *添加@Autowired
     *自动注入UserinfpRespository
     * /
    @Autowired
    private UserinfoRepository userinfoRepository;


    / **
     *向数据库中增加一条数据
     * @Test代表这是一个测试方法
     * /
    @测试
    public void save(){
        //创建对象并实例化
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername( “管理员”);
        userinfo.setUserpass( “123456”);

        //调用JPA中的保存方法,向数据库中增加一条数据,返回一个对象
        Userinfo us = userinfoRepository.save(userinfo);

        //断言
        Assert.assertEquals(us.getUsername(), “管理员”);
    }


    / **
     *删除数据库的一条数据
     * /
    @测试
    public void delete(){
        //调用删除方法,根据ID删除
        userinfoRepository.delete(1);
    }

    / **
     *更新数据库指定id数据
     * /
    @测试
    public void update(){
        userinfoRepository.updateById( “为admin123”,5);
    }

    @测试
    public void select(){

        //第一种查询返回List集合
        List <Userinfo> lists = userinfoRepository.findAll();
        for(Userinfo us:lists){
            的System.out.println( “>>>>>>>>>>>>>>>>>>第一种,用户名是:” + us.getUsername());

        }
        //第二种查询根据id查询返回实体
        Userinfo uinfo = userinfoRepository.findOne(5);
        的System.out.println( “>>>>>>>>>>>>>>>>>>第二种,用户名是:” + uinfo.getUsername());

    }
}


3.运行判断测试是否成功,可在数据表中查看是否创建表,增加数据,控制台中查看是否更新数据,可查看数据。