一、JPA介绍

JPA (Java Persistence API)Java持久化API,是一套Sun公司Java官方制定的ORM 规范(sun公司并没有实现)。
ORM(Object Relational Mapping)为对象关系映射,是一个实现使用对象操作数据库的设计思想。
其作用是在操作数据库之前,先把数据表与实体类关联起来,然后通过实体类的对象操作(增删改查)数据库表。
因此JPA的作用就是通过对象来操作数据库(不用编写sql语句)。其好处在于:不同的数据库的SQL语法是有差异,如果不需要编写SQL语句,就可以屏蔽各种数据库SQL的差异。那么,编写的代码就可以一套代码兼容多种数据库

既然JPA是一套规范,也就意味着它只是一套实现ORM理论的接口,并没有实现的代码

那么我们必须要有具体的实现者。
市场上的主流的**JPA框架(实现者)**有:
Hibernate (性能最好)、EclipseTop、OpenJPA

JPA实现流程:
首先是 ORM 映射,通过注解或 XML 描述对象和表直接的映射关系。
然后就是对数据库进行 CRUD (增删改查)操作,由于已经配置了对象和表的映射关系,所以可以自动生成对应的 SQL 语句,然后执行语句即可。

二、Spring Boot+ JPA 开发一个完整实例

第一步:创建项目,并新建好包,并在新建一个数据库shop

java jpa createQuery 怎么解决sql注入 jpa写sql_spring

第二步:引入依赖

<!-- jpa -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<scope>test</scope>
		</dependency>

第三步:添加配置

# 配置数据库驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 配置数据库url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
# 配置数据库用户名
spring.datasource.username=
# 配置数据库密码
spring.datasource.password=

# 启动时更新表结构,保留数据(JPA 会在项目启动时自动建立表结构,因此数据库可以不用建表)
spring.jpa.hibernate.ddl-auto=update

第四步:在entity 包下新建GoodsDo类 ,并通过注解实现类结构与数据表结构的映射。

package com.example.demo.entity;


import javax.persistence.*;

/**
 * 商品类
 */
@Entity // 表示这是一个数据对象类
@Table(name = "goods") // 对应数据库中的goods表
public class GoodsDo {
    /**
     * 商品id
     */
    @Id// 该字段对应数据库中的列为主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键自增长
    @Column(name = "id") // 对应goods表中的id列
    private Long id;
    /**
     * 商品名称
     */
    @Column(name = "name") // 对应goods表中的name列
    private String name;
    /**
     * 商品价格
     */
    @Column(name = "price") // 对应goods表中的price列
    private String price;
    /**
     * 商品图片
     */
    @Column(name = "pic") // 对应goods表中的pic列
    private String pic;

    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 getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }
}

第五步:在dao包下新建IGoodsDao 接口,通过继承 CrudRepository 实现 CRUD 操作,此时已经可以通过 IGoodsDao 对数据库中的表进行增删改查操作了

package com.example.demo.dao;

import com.example.demo.entity.GoodsDo;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;


//通过继承 CrudRepository 实现 CRUD 操作。泛型参数分别为实体类及主键的数据类型。
//注意此时已经可以通过 IGoodsDao 对数据库 goods 表进行增删改查操作了。
@Repository
public interface IGoodsDao extends CrudRepository<GoodsDo,Long> {
}

第六步:在service包下新建GoodsService 类

package com.example.demo.service;

import com.example.demo.dao.IGoodsDao;
import com.example.demo.entity.GoodsDo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * 商品服务类
 */
@Service
public class GoodsService {
    @Autowired
    private IGoodsDao goodsDao;

    /**
     * 新增商品
     */
    public void add(GoodsDo goods) {
        goodsDao.save(goods);
    }

    /**
     * 删除商品
     */
    public void remove(Long id) {
        goodsDao.deleteById(id);
    }

    /**
     * 编辑商品信息
     */
    public void edit(GoodsDo goods) {
        goodsDao.save(goods);
    }

    /**
     * 按id获取商品信息(Optional是一个包装类,它的内容是空或者包含的对象,所以可以避免空指针问题)
     */
    public Optional<GoodsDo> getById(Long id) {
        return goodsDao.findById(id);
    }

    /**
     * 获取商品信息列表
     */
    public Iterable<GoodsDo> getList() {
        return goodsDao.findAll();
    }
}

第七步:control包下新建GoodsController类

/**
 * 商品控制器类
 */
@RestController
public class GoodsController {
	@Autowired
	private GoodsService goodsService;
	/**
	 * 按id获取商品信息
	 */
	@GetMapping("/goods/{id}")
	public Optional<GoodsDo> getOne(@PathVariable("id") long id) {
		return goodsService.getById(id);
	}
	/**
	 * 获取商品列表
	 */
	@GetMapping("/goods")
	public Iterable<GoodsDo> getList() {
		return goodsService.getList();
	}
	/**
	 * 新增商品
	 */
	@PostMapping("/goods")
	public void add(@RequestBody GoodsDo goods) {
		goodsService.add(goods);
	}
	/**
	 * 编辑商品
	 */
	@PutMapping("/goods/{id}")
	public void update(@PathVariable("id") long id, @RequestBody GoodsDo goods) {
		// 修改指定id的博客信息
		goods.setId(id);
		goodsService.edit(goods);
	}
	/**
	 * 移除商品
	 */
	@DeleteMapping("/goods/{id}")
	public void delete(@PathVariable("id") long id) {
		goodsService.remove(id);
	}
}

第八步:测试

package com.example.demo;

import com.example.demo.dao.IGoodsDao;
import com.example.demo.entity.GoodsDo;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
class DemoJpaApplicationTests {
	@Autowired
	private IGoodsDao goodsDao;
	@Test
	void contextLoads() {
	}
	/**
	 * 新增测试
	 */
	@Test
	public void testAdd() {
		GoodsDo goods = new GoodsDo();
		goods.setName("梨张");
		goods.setPic("梨图片");
		goods.setPrice("2.0");
		GoodsDo result = goodsDao.save(goods);
		System.out.println("新增商品id:" + result.getId());
		assertNotNull(result);
	}

	private void assertNotNull(GoodsDo result) {
	}
}

运行测试类,查看控制台输出,并查看数据库,可以看出已经自动构建表结构和添加数据。

java jpa createQuery 怎么解决sql注入 jpa写sql_spring boot_02