拓展阅读
The jdbc pool for java.(java 手写 jdbc 数据库连接池实现)
The simple mybatis.(手写简易版 mybatis)
Hibernate
Hibernate ORM 允许开发者更轻松地编写那些数据在应用程序进程结束后仍然存在的应用程序。
作为一个对象关系映射(ORM)框架,Hibernate 关注的是与关系数据库(通过 JDBC)相关的数据持久化。
hibernate
Hello world
- Event.java
/*** Created by houbinbin on 16/5/18.*/
public class Event {private Long id;private String title;private Date date;//
}
- HibernateUtil.java
public class HibernateUtil {private static SessionFactory sessionFactory;private HibernateUtil() {}public static SessionFactory getSessionFactory() {if(sessionFactory == null) {sessionFactory = new Configuration().configure().buildSessionFactory();}return sessionFactory;}
}
- EventService.java
public class HibernateUtil {private static SessionFactory sessionFactory;private HibernateUtil() {}public static SessionFactory getSessionFactory() {if(sessionFactory == null) {sessionFactory = new Configuration().configure().buildSessionFactory();}return sessionFactory;}
}
- EventTest.java is today’s lead.
public class EventTest extends TestCase {private EventService eventService;@Beforepublic void setUp() {eventService = new EventService();}@Testpublic void testCreate() {eventService.createAndStoreEvent("create Event", new Date());}@Testpublic void testQuery() {List<Event> events = eventService.listEvents();for (Event event : events) {System.out.println(event);}}@Afterpublic void tearDown() {HibernateUtil.getSessionFactory().close();}
}
run testCreate()
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Hibernate: insert into EVENT (EVENT_DATE, title) values (?, ?)
run testQuery()
Hibernate: select event0_.EVENT_ID as EVENT_ID1_0_, event0_.EVENT_DATE as EVENT_DA2_0_, event0_.title as title3_0_ from EVENT event0_
五月 20, 2016 12:05:45 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost/hibernate]
Event{id=1, title='My Event', date=2016-05-19 21:48:56.0}
Event{id=2, title='Test Event', date=2016-05-19 22:58:43.0}
Event{id=3, title='create Event', date=2016-05-19 23:32:49.0}
Event{id=4, title='create Event', date=2016-05-20 00:04:40.0}Process finished with exit code 0
Annotation
Now, let’s use annotation way to achieve code above.
- Student.java
/*** Created by houbinbin on 16/5/20.*/
@Entity
public class Student {private Long id;private String name;private int score;//getter and setter...//default constructor and with members' constructor//toString()}
- StudentService.java
public class StudentService extends BaseService<Student> {public String getEntityName() {return "Student";}
}
- BaseService.java
/*** Created by houbinbin on 16/5/20.*/
public abstract class BaseService<T> {/*** get current entity's name;* @return*/public abstract String getEntityName();/*** save the entity.* @param entity* @return*/public Serializable save(T entity) {Session session = HibernateUtil.getSessionFactory().getCurrentSession();session.beginTransaction();Serializable result = session.save(entity);session.getTransaction().commit();return result;}/*** list all data of entity;* @return*/public List<T> list() {Session session = HibernateUtil.getSessionFactory().getCurrentSession();session.beginTransaction();List<T> result = session.createQuery("FROM " + getEntityName()).list();session.getTransaction().commit();return result;}/*** show the list* - you need write the correct toString() of entity;*/public void show() {List<T> result = list();for(T entity : result) {System.out.println(entity);}}
}
- StudentTest.java
public class StudentTest extends TestCase {private StudentService studentService;@Beforepublic void setUp() {studentService = new StudentService();}@Testpublic void testCreate() {Student student = new Student("xiaoming", 70);studentService.save(student);}@Testpublic void testShow() {studentService.show();}@Afterpublic void tearDown() {HibernateUtil.getSessionFactory().close();}
}
Mapping
- @Table
The identifier uniquely identifies each row in that table. By default the name of the table is assumed to be the
same as the name of the entity. To explicitly give the name of the table or to specify other information about the table,
we would use the javax.persistence.Table annotation.
@Entity
@Table(name="t_simple")
public class Simple {private int id;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}
}
the created table named t_simple.
- @Basic
Strictly speaking, a basic type is denoted with the javax.persistence.Basic annotation.
Generally speaking the @Basic annotation can be ignored. Both of the following examples are ultimately the same.
so, the code above is the same as…
@Entity
@Table(name="t_simple")
public class Simple {private int id;@Id@GeneratedValue@Basicpublic int getId() {return id;}public void setId(int id) {this.id = id;}
}
- @Column
For basic type attributes, the implicit naming rule is that the column name is the same as the attribute name.
If that implicit naming rule does not meet your requirements, you can explicitly tell Hibernate (and other providers) the column name to use.
@Entity
public class Simple {private int id;@Id@GeneratedValue@Column(name="t_id")public int getId() {return id;}public void setId(int id) {this.id = id;}
}
the created table column will be “t_id”.
- @Enumerated
ORDINAL - stored according to the enum value’s ordinal position within the enum class, as indicated by java.lang.Enum#ordinal
STRING - stored according to the enum value’s name, as indicated by java.lang.Enum#name
@Entity
public class Simple {private int id;private Gender gender;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}@Enumerated(STRING)public Gender getGender() {return gender;}public void setGender(Gender gender) {this.gender = gender;}public static enum Gender {MALE, FEMALE}
}
result is MALE;
change into
@Enumerated
public Gender getGender() {return gender;
}
result is 0;
Spring
When hibernate meets spring, things will be interesting…What I want to say, is hibernate’s model define.
- hbm.xml
<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"><property name="mappingResources"><list><value>user.hbm.xml</value></list></property>
</bean>
- class
<property name="annotatedClasses"><list><value>com.ryo.model.User</value></list>
</property>
- auto scan
<property name="packagesToScan"><list><value>com.ryo.model.*</value></list>
</property>
packagesToScan specify packages to search for autodetection of your entity classes in the classpath.
So, the * in com.ryo.model.*
is stand for package name. If your model classes are like this…
/com/ryo/model/- User.java
You need write com.ryo.*
Or, you can write like this…
<list><value>com.ryo.model</value>
</list>