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");