Hibernate5的入門配置
一、我們喜歡Hibernate的哪些東西
- 它封裝了JDBC對象,讓人不用寫sql,還是開源的ORM的框架
(ORM框架有哪些?HIbernate、Ibatis、Mybatis、EclipseLink、JFinal) - 將數據庫表和實體類對應起來,對數據進行持久化操作(數據持久化(PO)就是將內存中的數據模型轉換爲存儲模型,以及將存儲模型轉換爲內存中的數據模型的統稱.數據模型可以是任何數據結構或對象模型,存儲模型可以是關係模型、XML、二進制流等。cmp和Hibernate只是對象模型到關係模型之間轉換的不同實現)
- 配置對象關係映射可自由選擇,一種是基於xml的方式,另一種是基於annotation的註解方式,個人偏愛JPA註解開發,可以提高開發效率。
二、怎麼使用JPA開發
1、我們選擇使用maven,新建一個項目
2、接着需要在pom.xml配置我們需要的Hibernate和 Druid,使用註解開發需要hibernate5.3.7.jar,hibernate-annotations- 3.3.0.jar,hibernate-commons-annotations.jar 和ejb3-persistence.jar ,不過我們通過maven可以輕鬆的獲取到,不用太擔心。<?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>com.XXX</groupId> <artifactId>hibernate-web</artifactId> <packaging>pom</packaging> <version>1.0.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit.version>4.11</junit.version> <common.jdbc.version>1.0.0</common.jdbc.version> <commons.lang3.version>3.1</commons.lang3.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- 使用註解開發你得有hibernate5.3.7.jar, hibernate-annotations- 3.3.0.jar, hibernate-commons-annotations.jar 和ejb3-persistence.jar 四個jar包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.3.7.Final</version> </dependency> <dependency> <groupId>org.hibernate.common</groupId> <artifactId>hibernate-commons-annotations</artifactId> <version>5.0.4.Final</version> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency> </dependencies> <distributionManagement> <repository> <id>releases</id> <name>Team Nexus Repository</name> <url>http://中央倉庫或者私服地址/repositories/releases/</url> <layout>default</layout> </repository> </distributionManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <configuration> <skip>true</skip> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.0.1</version> <configuration> <attach>true</attach> </configuration> <executions> <execution> <phase>compile</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
3、給Hibernate配置hibernate.cfg.xml,這個文件用於配置數據庫連接和Hibernate運行時所需的各種屬性。每個 Hibernate 配置文件對應一個 Configuration 對象
這個鏈接裏面有各個屬性的解釋,但是注意我們用的Drui替換掉了C3P0:http://www.yiidian.com/hibernate/hibernate-cfg-xml.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 表明以下的配置是針對session-factory配置的,SessionFactory是Hibernate中的一個類,這個類主要負責保存HIbernate的配置信息,以及對Session的操作 -->
<session-factory>
<!--數據源信息 for Druid-->
<!-- 1.連接數據庫參數 -->
<property name="driverClassName">com.mysql.jdbc.Driver</property>
<property name="url">jdbc:mysql://127.0.0.0/3306/test?useSSL=false</property>
<property name="username">XXXXX</property>
<property name="password">XXXXX</property>
<!-- 2.詳細配置 -->
<!-- 配置druid連接池 -->
<property name="connection.provider_class">
com.alibaba.druid.support.hibernate.DruidConnectionProvider
</property>
<property name="filter">stat</property>
<property name="initialSize">5</property>
<property name="maxActive">100</property>
<!-- 配置獲取連接超時等待時間 -->
<property name="maxWait">60000</property>
<!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis">60000</property>
<!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
<property name="minEvictableIdleTimeMillis">300000</property>
<property name="validationQuery">SELECT 1</property>
<property name="testWhileIdle">true</property>
<property name="testOnBorrow">false</property>
<property name="testOnReturn">false</property>
<!-- 打開PSCache,並且指定每個連接上PSCache的大小 -->
<property name="poolPreparedStatements">false</property>
<property name="maxPoolPreparedStatementPerConnectionSize">200</property>
<!--end-->
<!-- 3.hibernate擴展參數 -->
<!-- hibernate方言 -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="jdbc.fetch_size">50 </property>
<!-- 讓session被TheadLocal管理 -->
<property name="hibernate.current_session_context_class">
thread
</property>
<!-- Hibernate映射數據庫的實體類 -->
<mapping class="entity.Company"/>
</session-factory>
</hibernate-configuration>
4、讓我們使用Idea這強大的工具幫助我們自動生成POJO,我們再根據自己的需要去做事情。
4、根據自己的需要對實體類進行註解
各個註解的表達含義如下:
- @Entity —> 如果我們當前這個bean要設置成實體對象,就需要加上Entity這個註解
- @Table(name=“company”) ----> 設置數據庫的表名
- @Column(name = “companyAddr”) —> Column中的name屬性對應了數據庫的該字段名字,裏面還有其他屬性,例如length,nullable等等
- @Id —> 定義爲數據庫的主鍵ID (建議不要在屬性上引入註解,因爲屬性是private的,如果引入註解會破壞其封裝特性,所以建議在getter方法上加入註解)一般我們寫javaBean,成員變量通常定義爲private,目的就是不讓別人來直接訪問的私有屬性,而我們把註解放在私有成員的變量上,就是默認hibernate可以直接訪問我們的私有的成員變量,hibernate是採用java的反射機制完全可以訪問私有成員變量!所以應該放在get方法上。
- @GeneratedValue ----> ID的生成策略爲自動生成
- @OneToMany(mappedBy=“room”) —> OneToMany指定了一對多的關係,mappedBy="room"指定了由多的那一方來維護關聯關係,mappedBy指的是多的一方對1的這一方的依賴的屬性,(注意:如果沒有指定由誰來維護關聯關係,則系統會給我們創建一張中間表)
- @LazyCollection(LazyCollectionOption.EXTRA) —> LazyCollection屬性設置成EXTRA指定了當如果查詢數據的個數時候,只會發出一條 count(*)的語句,提高性能
- @ManyToOne(fetch=FetchType.LAZY) —> ManyToOne指定了多對一的關係,fetch=FetchType.LAZY屬性表示在多的那一方通過延遲加載的方式加載對象(默認不是延遲加載)
- @JoinColumn(name=“rid”) —> 通過 JoinColumn 的name屬性指定了外鍵的名稱 rid (注意:如果我們不通過JoinColum來指定外鍵的名稱,系統會給我們聲明一個名稱)
- @OneToOne(mappedBy=“person”) —> 指定了OneToOne的關聯關係,mappedBy同樣指定由對方來進行維護關聯關係
- @OneToOne —> OnetoOne指定了一對一的關聯關係,一對一中隨便指定一方來維護映射關係,這裏選擇IDCard來進行維護
- @JoinColumn(name=“pid”) —> 指定外鍵的名字 pid
注意:在判斷到底是誰維護關聯關係時,可以通過查看外鍵,哪個實體類定義了外鍵,哪個類就負責維護關聯關係。 - @ManyToMany(mappedBy=“teachers”) —> 表示由Course那一方來進行維護
- @ManyToMany —> ManyToMany指定多對多的關聯關係
- @JoinTable(name=“t_teacher_course”, joinColumns={ - @JoinColumn(name=“cid”)},
inverseJoinColumns={ @JoinColumn(name = “tid”) }) —> 因爲多對多之間會通過一張中間表來維護兩表直接的關係,所以通過 JoinTable 這個註解來聲明,name就是指定了中間表的名字,JoinColumns是一個 @JoinColumn類型的數組,表示的是我這方在對方中的外鍵名稱,我方是Course,所以在對方外鍵的名稱就是 rid,inverseJoinColumns也是一個 @JoinColumn類型的數組,表示的是對方在我這方中的外鍵名稱,對方是Teacher,所以在我方外鍵的名稱就是 tid 這裏涉及多個表和相互之間的關係 - 小技巧:通過hibernate來進行插入操作的時候,不管是一對多、一對一還是多對多,都只需要記住一點,在哪個實體類聲明瞭外鍵,就由哪個類來維護關係,在保存數據時,總是先保存的是沒有維護關聯關係的那一方的數據,後保存維護了關聯關係的那一方的數據
package entity;
import javax.persistence.*;
/**
* @author Grance
*/
@Entity
@Table(name = "company")
public class Company {
private Double id;
private String companyName;
private String companyAddr;
private String name;
private String mobile;
@Column(name = "id")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Double getId() {
return id;
}
public void setId(Double id) {
this.id = id;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
@Basic
@Column(name = "companyAddr")
public String getCompanyAddr() {
return companyAddr;
}
public void setCompanyAddr(String companyAddr) {
this.companyAddr = companyAddr;
}
@Basic
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Basic
@Column(name = "mobile")
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
* @author Grance
*/
public class TestHibernate {
//Configuration類負責管理Hibernate的配置信息,是Hibernate特有的哦
private static Configuration cfg = null;
/**
* SessionFactory是生成Session對象的工廠類,
* 一個SessionFactory實例對應一個數據庫,應用從該對象中獲得Session實例
*應該在應用啓動時初始化該實例
*/
private static SessionFactory factory = null;
//只需要執行1次
static{
cfg = new Configuration();
cfg.configure();
factory = cfg.buildSessionFactory();
}
/**
* 讓外部獲取Session對象
*/
public static Session getSession(){
return factory.openSession();
}
@Test
public void test01(){
//對持久化對象進行操作
Company company = new Company();
company.setName("Test測試公司");
company.setCompanyAddr("深圳市寶安區益田假日盒馬超市第一旺鋪");
company.setMobile("123456789");
company.setQq("123456789");
/**
* Hibernate的寶貝,被稱爲持久化管理器(想到官網說他是一個短命的對象)
* 雖然是一個非線程安全的單線程對象遊走在應用程序與數據庫之間
* 聯手持久化類將數據保存在數據庫(持久化操作),
* 在顯式執行 flush 之前,會將所有的持久化操作的數據都裝(緩存)在自己家倉庫中(session的一級緩存)
*/
Session session = getSession();
//在session開始工作的時候總是要是開啓事物,就像是它的百寶箱
Transaction transaction = session.beginTransaction();
transaction.begin();
session.save(company);
transaction.commit();
}
}
PS:
通過JSch來連接ssh的mysql
JSch jsch = new JSch();
com.jcraft.jsch.Session session = jsch.getSession("linGrNE", "xxxx.xxx.xxx", 22);
session.setPassword("lingRNC");
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
System.out.println(session.getServerVersion());//這裏打印SSH服務器版本信息
//ssh -L 正向代理 //端口映射 轉發
int assinged_port = session.setPortForwardingL(3306, "xxx.xxx.x", 3306);
Connection conn = DriverManager.getConnection("jdbc:mysql://xxxxxxxxx:3306/test&autoReconnect=true&failOverReadOnly=false", "linGrNCE", "LINGENCE");
// 獲取所有表名
Statement statement = conn.createStatement();
ResultSet resultSet = statement
.executeQuery("select COUNT(*) from company");
System.out.println(resultSet.getInt(1));
// File file = new File("hibernte.cfg.xml");