前言
首先从事了Java开发已经10年有余,做过大小项目众多,曾经用过2年的Hibernate,直径也快有10年没有再次使用了,主要是后来的项目对性能有要求多采用iBatis后来升级MyBatis。
准备
开始代码前先准备jar包,之所以没有maven是因为maven是因为需要分析项目所需的jar包真正的用途。
准备jar包
- antlr-2.7.6.jar (生成sql语句)
- cglib-2.1_3.jar (动态代理)
- commons-collections-3.2.jar (集合处理)
- commons-logging-1.1.1.jar (日志组件)
- dom4j-1.6.1.jar (xml的dom操作)
- hibernate-3.2.6.ga.jarjta-1.1.jar(不解释)
- junit-4.10.jar (单元测试)
- log4j-1.2.14.jar (家喻户晓的日志)
- mysql-connector-java-5.1.6.jar (用的mysql连接jdbc驱动)
准备数据库Mysql
这里用的mysql5,创建一个库test就可以了,注意是utf-8字符集就可以了很简单(后面的表hibernate会自动生成)。
代码
Hiberante配置文件
<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/test?Unicode=true&characterEncoding=GBK?Unicode=true&characterEncoding=UTF-8</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>-->
<!-- Echo all executed SQL to stdout
<property name="show_sql">true</property>-->
<!-- update|create|create-dorp update自动生成表 update包含create-->
<property name="hbm2ddl.auto">update</property>
<mapping resource="hibernate/curd/Emp.hbm.xml"/>
</session-factory>
</hibernate-configuration>
实体配置文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hibernate.curd">
<class name="Emp" table="Emp">
<!-- id标识主键,generator标识主键生成策略后续详细讲解-->
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name"/>
<property name="sex" type="string" column="sex"/>
<property name="phone" type="string" column="phone"/>
<property name="mail" type="string" column="mail"/>
</class>
</hibernate-mapping>
pojo对象
package hibernate.curd;
import java.io.Serializable;
/**
* 员工对象
*/
public class Emp implements Serializable{
private int id;
private String name;
private String phone;
private String sex;
private String mail;
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
log4j配置文件
log4j.rootLogger=ERROR,CONSOLE
log4j.addivity.org.apache=true
# 应用于控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
# 打印Hibernate sql 参数
log4j.category.org.hibernate.SQL=trace
log4j.category.org.hibernate.type=trace
Junit4测试
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.hibernate.transform.Transformers;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import java.util.Map;
/**
* 将近10年没有用Hibernate了,最近接收项目操作Hibernate,正好回顾一下.
*/
public class TestCurd {
private Configuration cfg;
private SessionFactory cf;
@Before
public void init() {
cfg = new Configuration();
cf = cfg.configure().buildSessionFactory();
}
@Test
/**
* 保存对象
*/
public void save() {
Emp emp = new Emp();
emp.setName("张三");
emp.setMail("zhangsan@123.com");
emp.setPhone("13897654231");
emp.setSex("F");
Session session = cf.openSession();
session.beginTransaction();
session.save(emp);
session.getTransaction().commit();
session.close();
cf.close();
}
/**
* 保存对象
*/
@Test
public void load() {
Session session = cf.openSession();
session.beginTransaction();
Emp emp = (Emp)session.load(Emp.class, 1);
System.out.println("=="+emp.getName());
emp.setName("张三变名字了"); //即使是查询,只要在事物前做过对象操作都将触发update
session.getTransaction().commit();
emp.setName("张三更改不了"); //在事物后处理将不会改变,如果在事物之前非要用对象操作也可以采用session.evict(emp);
session.close();
cf.close();
}
/**
* merge修改数据
* 先根据ID查询数据库是否有数据,如果有数据将进行修改数据,如果没有将进行创建数据
* 注意:如果是更新数据会存在一个问题,如果该对象没有设置某个参数是会被设置null
*/
@Test
public void merge(){
Session session = cf.openSession();
session.beginTransaction();
Emp emp = new Emp();
emp.setId(10);
emp.setName("李四2");
emp.setSex("M");
emp.setMail("lisi@123.com");
session.merge(emp);
session.getTransaction().commit();
session.close();
cf.close();
}
/**
* update更新数据
* 和merge不同的是,如果id不存在会抛出异常
*/
@Test
public void update(){
Session session = cf.openSession();
session.beginTransaction();
Emp emp = new Emp();
emp.setId(20);
emp.setName("李四2");
emp.setSex("M");
emp.setMail("lisi@123.com");
session.update(emp);
session.getTransaction().commit();
session.close();
cf.close();
}
/**
* delete删除某条记录
*/
@Test
public void delete(){
Session session = cf.openSession();
session.beginTransaction();
Emp emp = new Emp();
emp.setId(6);
session.delete(emp);
session.getTransaction().commit();
session.close();
cf.close();
}
/**
* 查询列表
*/
@Test
public void query(){
Session session = cf.openSession();
session.beginTransaction();
Emp empQuery = new Emp();
empQuery.setName("张三");
Query query = session.createQuery("from Emp where name=:name");
query.setProperties(empQuery);
List<Emp> list = query.list();
for(Emp emp : list){
System.out.println(emp.getName());
}
session.getTransaction().commit();
session.close();
cf.close();
}
/**
* 查询列表
*/
@Test
public void query2(){
Session session = cf.openSession();
session.beginTransaction();
Query query = session.createQuery("from Emp where name like ?");
query.setString(0, "%张三%");
List<Emp> list = query.list();
for(Emp emp : list){
System.out.println(emp.getName());
}
session.getTransaction().commit();
session.close();
cf.close();
}
/**
* 查询列表
* 该方法主要用于,没有配置hbm文件或者处理复杂sql需要
*/
@Test
public void querySQL1(){
Session session = cf.openSession();
session.beginTransaction();
SQLQuery query = session.createSQLQuery("select * from emp where name like ?");
// query.setParameter(0, "%张三%"); //设置预处理参数
query.setString(0, "%张三%");
//*** 关键的一步把对象转换成Map
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List<Map> list = query.list();
System.out.println(list);
for(Map emp : list){
System.out.println(emp.toString());
}
session.getTransaction().commit();
session.close();
cf.close();
}
/**
* 查询列表
*/
@Test
public void querySQL(){
Session session = cf.openSession();
session.beginTransaction();
SQLQuery query = session.createSQLQuery("select * from emp where name like ?");
query.setParameter(0, "%张三%");
//*** 主要方法绑定对象
query.addEntity(Emp.class);
List<Emp> list = query.list();
System.out.println(list);
for(Emp emp : list){
System.out.println(emp.getName());
}
session.getTransaction().commit();
session.close();
cf.close();
}
}
由于好久没有使用Hibernate了,后面还会整理 n-n关联关系处理、一级缓存二级缓存查询缓存、主键生成策略、悲观锁和乐观锁、JPA方式等。