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:回滚事务

注解

注解内部结构解析

在这里插入图片描述

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