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:回滾事務

註解

註解內部結構解析

在這裏插入圖片描述

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