利用IDEA环境用Hibernate连接sql server看这里hibernate连接sql server
1 引言
- Hibernate是一个高性能的对象关系型持久化存储和查询的服务,其主要关注:
- java类到数据库表的映射
- java数据类型到SQL数据类型的映射
2 Hibernate ORM 概览
2.1 什么是JDBC
- JDBC: Java Database Connectivity
他提供一组java Api来访问数据库,这些api能使java应用程序去执行SQL语句。
2.2 什么是 ORM?
- ORM:Object-Relational Mapping
其是一种在java等面对对象编程语言和数据库中转换数据的技术。
3 Hibernate 简介
-
Hibernate 将 Java 类映射到数据库表中,从 Java 数据类型中映射到 SQL 数据类型中,并把开发人员从 95% 的公共数据持续性编程工作中解放出来。
4 Hibernate 架构
-
Hibernate 架构是分层的,作为数据访问层,你不必知道底层 API 。Hibernate 利用数据库以及配置数据来为应用程序提供持续性服务(以及持续性对象)。
5 Session 简介
5.1 hibernate执行过程
- 获取配置
//创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.configure().build();
- 获取映射对象且创建会话工厂
sessionFactory = new MetadataSources( serviceRegistry ).buildMetadata().buildSessionFactory();
- 创建会话(session类似jdbc中的connection)
session = sessionFactory.openSession();
- 提交事务
transaction = session.beginTransaction();
- 关闭会话
session.close(); //关闭会话
sessionFactory.close(); //关闭会话工厂
5.2 Session
- 理解为操纵数据库的对象
- session与connection是多对一的关系,每个session都有一个与之对应的connection,一个connection可以供多个session使用。
6 transaction简介
- hibernate对数据的操作都是封装在事务中的,并且默认是非自动提交的方式。所以用session保存对象时,如果不提交事务,对象不会真的保存在数据库中。
- 如果不想使用事务提交的方式,也可以采用下面这种方法。
@Test
public void testSaveStudents() {
//生成学生对象
Students s = new Students(1, "张三丰", "男", new Date(), "武当山");
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
connection.setAutoCommit(true);
}
});
session.save(s); //保存对象进入数据库
session.flush();
}
7 Session详解
7.1 如何获得session对象
- openSession
- getCurrentSession
如果使用getCurrentSession需要在hibernater.cfg.xml文件中添加
<property name="hibernate.current_session_context_class">thread</property>
7.2 两种获取Session方法的区别
- getCurrentSession在事务提交后会自动关闭,而openSession需要手动关闭,若没有手动关闭多次连接会导致连接池溢出。
- openSession每次需要创建一个新的session对象,而getCurrentSession获取的是当前的session对象(单例模式)。
7.3 实例映射表解释
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--name:表示映射的是哪个类,table表示该类映射数据库的那张表-->
<class name="Students" table="students">
<!--id,表示表的主键,name表示实体中的属性,type表示其数据类型,column name则是表中的名称-->
<id name="sid" type="int">
<column name="sid"/>
<!--主键生成策略native为数据库自动增长,assigned为自己分配-->
<generator class="native"/>
</id>
<property name="sname" type="java.lang.String">
<column name="sname"/>
</property>
<property name="gender" type="java.lang.String">
<column name="gender"/>
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday"/>
</property>
<property name="address" type="java.lang.String">
<column name="address"/>
</property>
</class>
</hibernate-mapping>
8 映射类型
-
其对应于映射表中的类型type
- 直接使用hibernate的映射类型或许更好。
8.1 对象类型
- blob:音频,视频图片,二进制数据
- clob:大文本类型
- 下面给出上传图片到数据库以及下载图片到本地的代码
public void testWriteBlob() throws IOException {
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Students s1 = new Students( "张丰", "男", new Date(), "武当山");
File file = new File("D:/IDEA背景/mygirl.jpg");
InputStream inputStream = new FileInputStream(file);
Blob image = Hibernate.getLobCreator(session).createBlob(inputStream,inputStream.available());
s1.setPicture(image);
session.save(s1); //保存对象进入数据库
transaction.commit();
session.close();
sessionFactory.close();
}
public void testGetBlob() throws SQLException, IOException {
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Students s = (Students)session.get(Students.class,1);
Blob image = s.getPicture();
InputStream inputStream = image.getBinaryStream();
File file = new File("D:/IDEA背景/mytest.jpg");
OutputStream outputStream = new FileOutputStream(file);
//创建缓冲区
byte[] buff = new byte[inputStream.available()];
inputStream.read(buff);
outputStream.write(buff);
inputStream.close();
outputStream.close();
}
9 组件属性
- 当实例对象中包含另一个实例的时候
<component name="address" class="Address">
<property name="postCode" column="POSTCODE"></property>
<property name="phone" column="PHONE"></property>
<property name="address" column="ADDRESS"></property>
</component>
- 被包含的实例
public class Address {
private String postCode;
private String phone;
private String address;
public Address() {
}
public Address(String postCode, String phone, String address) {
this.postCode = postCode;
this.phone = phone;
this.address = address;
}
public String getPostCode() {
return postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
- 测试方法如下:
@Test
public void testComponent(){
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Students s1 = new Students( "张丰", "男", new Date());
s1.setAddress(new Address("400065","15340504859","cq"));
session.save(s1);
transaction.commit();
}
-
数据库中结果如下:
10 对单表的增删查改
- 查get
@Test
public void testGet(){
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
//第二个参数为主键
Students students = session.get(Students.class,2);
//输出数据为Students
System.out.print(students.getClass().getName());
transaction.commit();
}
- 查load
@Test
public void testLoad(){
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
//第二个参数为主键
Students students = session.load(Students.class,2);
//输出的数据为Students$HibernateProxy$L7kBGyFY
System.out.print(students.getClass().getName());
transaction.commit();
}
注意,load和get方法的区别在哪里?①get方法在调用之后会立刻向数据库发送SQL语句;load方法只有当对象使用除主键外属性时才会发送sql语句,意思就是说load方法返回的对象开始只是一个代理对象,仅具有主键id。②get在数据库不存在该数据时返回Null,而load则抛出异常
- 增save
@Test
public void testSave(){
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Students s1 = new Students( "张丰", "男", new Date());
s1.setAddress(new Address("400065","15340504859","cq"));
session.save(s1);
transaction.commit();
}
- 改update
@Test
public void testUpdate(){
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
//第二个参数为主键
Students students = session.get(Students.class,1);
students.setGender("女");
session.update(students);
transaction.commit();
}
- 删delete
@Test
public void testDelete(){
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
//第二个参数为主键
Students students = session.get(Students.class,1);
session.delete(students);
transaction.commit();
}
11 类的三种状态
11.1 瞬时态
- 对象里没有id值,对象与session没有关联。
11.2 持久态
- 对象中有id值,且与session有关。
//由session获得的对象显然是持久态
Students students = session.get(Students.class,2);
11.3 托管态
- 对象有id值,对象与session没有关联。