首先看一下传统JDBC开发
JDBC的开发步骤:
- 加载数据库驱动
- 创建并获取数据库链接
- 创建PreparedStatement对象
- 设置sql语句
- 设置sql语句中的参数(使用preparedStatement)
- 通过statement执行sql并获取结果
- 对sql执行结果进行解析处理
- 释放资源(resultSet、preparedstatement、connection)
public class DataSourceUtils {
public static Connection getConnection(){
Connection connection = null;
try {
// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 通过驱动管理类获取数据库链接
connection = (Connection) DriverManager
.getConnection(
"jdbc:mysql://localhost:3306/StudentDB",
"root", "zu3.141592653");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connection;
}
}
StuDao:
public class StuDao {
private static Connection connection = DataSourceUtils.getConnection();
private static PreparedStatement preparedStatement = null;
private static ResultSet resultSet = null;
public void findById(int id) throws Exception{
// 定义sql语句 ?表示占位符
String sql = "select * from stu where stuId = ?";
// 获取预处理statement
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
// 设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setInt(1, id);
// 向数据库发出sql执行查询,查询出结果集
resultSet = (ResultSet) preparedStatement.executeQuery();
// 遍历查询结果集
while (resultSet.next()) {
System.out.println(resultSet.getString("stuId") + " "
+ resultSet.getString("stuName")+" "+resultSet.getString("stuAge")+" "+resultSet.getString("stuAddr"));
}
}
//释放资源
public boolean release(){
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
return true;
}
}
JDBC开发分析
- 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
- Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
- 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
- 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
Hibernate框架概述
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合。
Hibernate优点:
- 开源和轻量级: Hibernate框架是根据LGPL许可证和轻量级的开源工具。
- 快速性能: Hibernate框架的性能很快,因为缓存在Hibernate框架内部使用。 hibernate框架中有两种类型的缓存:一级缓存和二级缓存。一级缓存默认是启用的。
- 数据库独立查询: HQL(Hibernate查询语言)是面向对象的SQL版本。 它生成数据库独立查询。 所以你不需要编写数据库特定的查询语句。 在Hibernate之前,如果项目更改了数据库,我们需要更改SQL查询,从而导致维护变得非常复杂。
- 自动创建表: Hibernate框架提供了自动创建数据库表的功能。 因此,无需手动在数据库中创建表。
- 简化复杂连接: 在hibernate框架中可轻松获取多个表中的数据。
- 提供查询统计和数据库状态: Hibernate支持查询缓存,并提供有关查询和数据库状态的统计信息。
自动创建表这一个功能我想能让我们省时省力了,有一个Student类,使用Hibernate框架,表也建好了,方便快捷。
自动创建表这一功能我们也可以实现哦!欢迎查看:使用反射实现自己的ORM,自动创建表
Hibernate框架入门
下载Hibernate开发包:
http://download.csdn.net/download/qq_25343557/10150037
分析开发包目录结构:
Hibernate程序的流程:
- 创建java项目
- 为hibernate添加jar文件
- 创建持久类
- 创建持久类的映射文件
- 创建配置文件
- 创建检索或存储持久对象的类
- 运行应用程序
创建一个java工程:
导入jar包:
- hibernate3.jar
- required下的所有jar包
- jpa/hibernate-jpa.2.0-api-1.0.0.Final.jar
- 数据库驱动
创建表:
CREATE TABLE `stu` (
`stuId` INT(3) PRIMARY KEY NOT NULL AUTO_INCREMENT,
`stuName` CHAR(20),
`stuAge` INT(2),
`stuAddr` CHAR(30)
);
创建实体类:
public class Student {
Integer stuId;
String stuName;
Integer stuAge;
String stuAddr;
public Integer getStuId() {
return stuId;
}
public void setStuId(Integer stuId) {
this.stuId = stuId;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public Integer getStuAge() {
return stuAge;
}
public void setStuAge(Integer stuAge) {
this.stuAge = stuAge;
}
public String getStuAddr() {
return stuAddr;
}
public void setStuAddr(String stuAddr) {
this.stuAddr = stuAddr;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(Integer stuId, String stuName, Integer stuAge, String stuAddr) {
super();
this.stuId = stuId;
this.stuName = stuName;
this.stuAge = stuAge;
this.stuAddr = stuAddr;
}
@Override
public String toString() {
return "Student [stuId=" + stuId + ", stuName=" + stuName + ", stuAge="
+ stuAge + ", stuAddr=" + stuAddr + "]";
}
}
创建实体类对应的ORM映射文件:
文件名:实体类名.hbm.xml
。
新建Student.hbm.xml文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 现在先依葫芦画瓢,不要想参数的含义 -->
<!-- 建立类与表的映射 -->
<!-- class标签:用于映射类与表的关系 name:类的全路径 table:表的名称 -->
<class name="cn.xpu.hcp.bean.Student" table="stu">
<!-- 建立类的属性和表中的字段映射 -->
<!-- 1、使用id标签配置唯一属性,name:类中属性名称,column:表中字段名称 -->
<id name="stuId" column="stuId">
<!-- 配置逐渐生成策略 -->
<generator class="native"/>
</id>
<!-- 2、配置普通属性 -->
<!-- property标签:映射类中的普通属性 -->
<property name="stuName" column="stuName" type="string"/>
<property name="stuAge" column="stuAge" type="java.lang.Integer"/>
<property name="stuAddr" column="stuAddr" type="string"></property>
</class>
</hibernate-mapping>
创建一个Hibernate的核心配置文件:
文件名为hibernate.cfg.xml
,必须放在包外部。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 必须配置的信息---begin -->
<!-- 配置数据库连接的信息 -->
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql:///hibernateDB
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">zu3.141592653</property>
<!-- Hibernate方言 -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- 必须配置的信息---end -->
<!-- 可选配置的信息---begin -->
<!-- 执行CRUD等操作时是否显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL(使显示更美观) -->
<property name="hibernate.format_sql">true</property>
<!-- 可选配置的信息---end -->
<!-- 选择加载哪个实体类的映射文件 -->
<mapping resource="cn/xpu/hcp/bean/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
创建测试类实现插入一条数据操作:
//向数据库中插入数据
@Test
public void test() {
//1、获取核心配置文件
Configuration configure = new Configuration().configure();
//2、创建一个SessionFactory
SessionFactory sessionFactory = configure.buildSessionFactory();
//3、获取session对象
Session session = sessionFactory.openSession();
//4、默认情况下事务是不会自动提交的
Transaction tx = session.beginTransaction();
//5、执行业务
Student stu = new Student(null,"张三",22,"上海市");
session.save(stu);
tx.commit();//提交事务
//释放资源
session.close();
sessionFactory.close();
}
测试结果:
如果出现如下图所示情况:
这是由于Hibernate使用了日志系统,所以需要有log4j.properties文件:
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=info, stdout
在src下新建一个log4j.properties就行了。