Java持久化数据的方式——JDBC&ORM&JPA
JDBC
什么是JDBC?
有了JDBC之后的好处
JDBC完成用户的CURD
jdbc.properties:配置连接数据库的四大基本参数。
className=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root
User实体类
import lombok.Data;
@Data
public class User {
private Integer uid;
private String uname;
private String pwd;
private Integer sex;
private Integer age;
}
sql建表语句
CREATE TABLE `users` (
`uid` int(10) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`uname` varchar(255) DEFAULT NULL COMMENT '用户姓名',
`pwd` varchar(255) DEFAULT NULL COMMENT '用户密码',
`sex` int(1) DEFAULT NULL COMMENT '用户性别,1:男,0:女',
`age` int(3) DEFAULT NULL COMMENT '用户年龄',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
CURD代码
package cn.xxxq.jdbc.statement;
import cn.xxxq.jdbc.domain.User;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* 使用Statement对象执行增删改查SQL语句,有SQL注入的风险。
*/
public class JDBC_CURD_Statement {
private static String className;
private static String url;
private static String username;
private static String password;
/*
使用静态代码块在类加载的时候读取外部属性文件
*/
static {
InputStream in = JDBC_CURD_Statement.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
try {
properties.load(in);
className = properties.getProperty("className");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in!=null)
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
selectAllUser();
// insert();
// update();
// delete();
}
/**
* 查询所有用户
*/
public static void selectAllUser(){
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//注册驱动
Class.forName(className);
//获取连接对象
connection = DriverManager.getConnection(url, username, password);
//获取SQL执行对象
statement = connection.createStatement();
/*执行SQL语句*/
String sql = "select * from users";
resultSet = statement.executeQuery(sql);
while (resultSet.next()){
int uid = resultSet.getInt("uid");
int sex = resultSet.getInt("sex");
int age = resultSet.getInt("age");
String uname = resultSet.getString("uname");
String pwd = resultSet.getString("pwd");
User user = new User();
user.setUid(uid);
user.setUname(uname);
user.setPwd(pwd);
user.setSex(sex);
user.setAge(age);
System.out.println(user);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (resultSet!=null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
/**
* 删除用户
*/
public static void delete(){
Connection connection = null;
Statement statement = null;
try {
Class.forName(className);
connection = DriverManager.getConnection(url, username, password);
statement = connection.createStatement();
String sql = "delete from users where uid = 7";
int i = statement.executeUpdate(sql);
System.out.println(i==1?"删除成功!":"删除失败!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
/**
* 修改用户
*/
public static void update(){
Connection connection = null;
Statement statement = null;
try {
Class.forName(className);
connection = DriverManager.getConnection(url, username, password);
statement = connection.createStatement();
String sql = "update users set uname = '小二',age=28 where uid = 7";
int i = statement.executeUpdate(sql);
System.out.println(i==1?"修改成功!":"修改失败!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
/**
* 保存用户
*/
public static void insert(){
Connection connection = null;
Statement statement = null;
try {
Class.forName(className);
connection = DriverManager.getConnection(url, username, password);
statement = connection.createStatement();
String sql = "insert into users values(default,'老九','lj','1','39')";
int i = statement.executeUpdate(sql);
System.out.println(i==1?"保存成功!":"保存失败!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
}
ORM
什么是ORM?
对象关系映射(Object Relational Mapping,简称ORM),是建立实体类和数据库表之间的关系,
从而达到操作实体类就相当于操作数据库表的目的。
ORM思想
操作实体类就是操作数据库表
建立两个映射关系:
实体类与数据库表的映射
实体类属性与数据库表字段的映射
实现ORM思想的框架:
Hibernate,MyBatis(半ORM思想)
JPA规范
Java持久化API(Java Persistence API)。就是将数据持久化(保存在数据库中)的一套规范。
使用JPA规范完成数据库的操作,底层需要Hibernate作为其实现类来完成数据持久化工作。
JPA完成客户的CURD
创建Maven工程导入依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!--测试环境有效-->
<scope>test</scope>
</dependency>
<!--hibernate对JPA规范的实现包-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.7.Final</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.0.7.Final</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
sql建表语句
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_address` varchar(128) DEFAULT NULL COMMENT '客户联系地址',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '客户联系电话',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Customer实体类
常用注解说明:
@Data:Lombok插件中的注解,自动生成getter、setter、toString等方法。
@Entity:声明当前类是实体类。
@Table:配置实体类与数据库表的映射关系。
name(@Table注解的参数):
:配置数据库表名称。
@Id:声明该字段是主键。
@GeneratedValue:指定主键的生成方式。
strategy(@GeneratedValue注解的参数):
GennerationType.IDENTITY:主键自增。
@Column:配置实体类属性和表字段的映射关系。
name(@Column注解的参数):
表字段名称。
@Data
@Entity
@Table(name = "cst_customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)//主键自增
@Column(name = "cust_id")
private Long custId; //客户的主键
@Column(name = "cust_name")
private String custName;//客户名称
@Column(name = "cust_source")
private String custSource;//客户来源
@Column(name = "cust_level")
private String custLevel;//客户级别
@Column(name = "cust_industry")
private String custIndustry;//客户所属行业
@Column(name = "cust_phone")
private String custPhone;//客户的联系方式
@Column(name = "cust_address")
private String custAddress;//客户地址
}
JPA的核心配置文件
配置persistent-unit节点:持久化单元
name:持久化单元名称。
transaction-type:事务类型。
RESOURCE_LOCAL:本地事务管理(多个表存在一个数据库中)
JTA:分布式事务管理(不同的表分散在不同数据库)
<persistence-unit name="myJPA" transaction-type="RESOURCE_LOCAL"></persistence-unit>
jpa的实现方式: Hibernate
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
数据库连接参数
<properties>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
</properties>
Hibernate额外的配置(可选)
hibernate.show.sql: 是否显示sql,false(不显示),true(显示)
hibernate.hbm2ddl.auto: 是否创建数据库表
create:程序运行时创建数据库表(如果有表,先删除表再创建)
update:程序运行时不会创建表(如果有表,不会创建表)
none:不会创建表
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
完整的核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="myJPA" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
CURD代码
public class CURD_Test {
/**
* 保存客户
*/
@Test
public void save(){
//1.加载配置文件创建工厂对象(实体管理器工厂)
EntityManagerFactory myJPA = Persistence.createEntityManagerFactory("myJPA");
//2.通过实体管理器工厂获取实体管理器
EntityManager entityManager = myJPA.createEntityManager();
//3.获取事务对象并开启事务
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//4.保存操作
Customer customer = new Customer();
customer.setCustName("张三");
customer.setCustAddress("广东省广州市");
entityManager.persist(customer);
//5.提交事务
transaction.commit();
//6.关闭资源
entityManager.close();
myJPA.close();
}
}
JPA API
Persistence
Persistence对象主要作用是用于获取EntityManagerFactory对象的。
通过调用该类的createEntityManagerFactory静态方法,根据配置文件中持久化单元名称创建EntityManagerFactory。
EntityManagerFactory
EntityManagerFactory接口主要用来创建EntityManager对象。
EntityManagerFactory是一个线程安全的对象。多个线程访问同一个EntityManagerFactory对象不会有线程安全问题。
EntityManager
EntityManager是完成持久化操作的核心对象。
实体类作为普通java对象,只有在调用 EntityManager将其持久化后才会变成持久化对象。
通过调用EntityManager的方法完成获取事务,以及持久化数据库的操作。
getTransaction : 获取事务对象
persist : 保存操作
merge : 更新操作
remove : 删除操作
find/getReference : 根据id查询
EntityTransaction
EntityTransaction是完成事务操作的核心对象。
begin:开启事务
commit:提交事务
rollback:回滚事务