java Dao层对数据库操作总结
2016-06-12 10:51
330 查看
一、获取数据库连接
Connection con = null;
try{
con =this.getSessionFactory.getCurrentSession().connection();
con.setAutoCommit(false);
Statementst = con.createStatement();
for (int i = 0; i < ids.length; i++){
st.addBatch("delete from test_user where id ="+ids[i]);
}
st.executeBatch();
con.commit();
}catch(SQLException e){
// TODOAuto-generated catch block
}finally{
if(con != null){
try{
con.close();
}
catch (SQLExceptione) {
// TODO Auto-generated catchblock
}
}
}
二、使用Session.createSQLQuery()
对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。
public String getComment(Long id){
注:[b]append( )是类StringBuffer的一个方法。作用是在已有字符串后面添加一个字符串,主要用于sql语句拼接及字符串连接。[/b]
三、使用Session.createQuery(string hql)
小结:session.createQuery(hql) 与session.createSQLQuery(sql)区别
createQuery:执行时传入的参数为HQL语句,以hibernate生成的Bean为对象装入list返回
createSQLQuery:执行时传入的参数为SQL语句,返回的结果根据查询的字段数进行区分,如果查询一个字段,则返回该字段类型的集合,如果查询的为多个字段,则将这些字段组合成一个对象数组,返回该对象数组的集合。
所以使用createSQLQuery有时候也想以hibernate生成的Bean为对象装入list返回,就不是很方便,突然发现createSQLQuery有这样一个方法可以直接转换对象
Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class);
XXXXXXX 代表以hibernate生成的Bean的对象,也就是数据表映射出的Bean。
还有另外一个相关的小细节应注意:
比如有这样一个po
PO: User.class
properties: userId,userName
DDL: create table tuser (userid varchar(10),username varchar(20));
当执行:
session.createQuery("from User u").list()时生成的SQL:select userid,username from tuser;
当执行:
session.createQuery("from User u").iterator()时生成的SQL:select userid from tuser;
可以看出
list()一次将数据从数据库中读出直接填充到List中
iterator()将数据的主键从数据库中读出,当循环这个Iterator时才添加执行:select userid,username from user where userid=?;把数据读出。
在不同的应用范围使用不同的方法,具体在hibernate应用中应当注意。
4.使用 this. getHibernateTemplate()
HibernateTemplate提供非常多的常用方法来完成基本的操作,比如通常的增加、删除、修改、查询等操作,Spring2.0更增加对命名SQL查询的支持,也增加对分页的支持。大部分情况下,使用Hibernate的常规用法,就可完成大多数DAO对象的CRUD操作。下面是HibernateTemplate的常用方法简介:
q void delete(Object entity):删除指定持久化实例
q deleteAll(Collection entities):删除集合内全部持久化类实例
q find(String queryString):根据HQL查询字符串来返回实例集合
q findAll():返回实例集合
q findByNamedQuery(String queryName):根据命名查询返回实例集合
q get(Class entityClass, Serializable id):根据主键加载特定持久化类的实例
q save(Object entity):保存新的实例
q saveOrUpdate(Object entity):根据实例状态,选择保存或者更新
q update(Object entity):更新实例的状态,要求entity是持久状态
q setMaxResults(int maxResults):设置分页的大小
public Object findUnique(String hql, Object... values) {
return this.createQuery(hql, values).uniqueResult();
}
***************************************************************
附上 Hibernate Query 对象简述
可以透过org.hibernate.Query介面的实例来进行查询,透过Query介面,您可以先设定查询参数,之后透过setXXX()等方法,将指定的参数值填入,而不用每次都撰写完整的HQL,直接来看个例子:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.name from User asuser where user.age > ?");
query.setInteger(0, 25);
List names = query.list();
Iterator iterator = names.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
session.close();
在设定参数值时,必须依照 ? 所设定的顺序,并使用对应型态的setXXX()方法
你可以使用命名参数(NamedParameter)来取代这个方法,这可以不用依照特定的顺序来设定参数值,并拥有较好的可读性,直接来看个例子:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.name from User asuser where user.age > :minAge");
query.setInteger("minAge", 25);
List names = query.list();
Iterator iterator = names.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
session.close();
设定命名参数时,在建立Query时先使用:后跟着参数名,之后就可以在setXXX()方法直接指定参数名来设定参数值,而不用依照特定的顺序。
*********************************************
getSession() 和getHibernateTemplate()方法区别
1.使用getSession()方法你只要继承sessionFactory,而使用getHibernateTemplate()方法必须继承HibernateDaoSupport当然包括sessionFactory,这点区别都不是特别重要的,下面这些区别就很重要了
2.getSession()方法是没有经过spring包装的,spring会把最原始的session给你,在使用完之后必须自己调用相应的close方法,而且也不会对声明式事务进行相应的管理,一旦没有及时关闭连接,就会导致数据库连接池的连接数溢出,getHibernateTemplate()方法是经过spring封装的,例如添加相应的声明式事务管理,由spring管理相应的连接。
在实际的使用过程中发现的确getHibernateTemplate()比getSession()方法要好很多,但是有些方法在getHibernateTemplate()并没有提供,这时我们用HibernateCallback回调的方法管理数据库.
例如如下代码:
public List getListForPage ( final String hql , final int offset ,final int length ) {
List list = getHibernateTemplate().executeFind ( newHibernateCallback ( ) {
public Object doInHibernate ( Session session ) throwsHibernateException, SQLException {
Queryquery = session.createQuery ( hql ) ;
query.setFirstResult( offset ) ;
query.setMaxResults( length ) ;
Listlist = query.list ( ) ;
returnlist ;
}
Connection con = null;
try{
con =this.getSessionFactory.getCurrentSession().connection();
con.setAutoCommit(false);
Statementst = con.createStatement();
for (int i = 0; i < ids.length; i++){
st.addBatch("delete from test_user where id ="+ids[i]);
}
st.executeBatch();
con.commit();
}catch(SQLException e){
// TODOAuto-generated catch block
}finally{
if(con != null){
try{
con.close();
}
catch (SQLExceptione) {
// TODO Auto-generated catchblock
}
}
}
二、使用Session.createSQLQuery()
对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。
public List<Map<String, Object>> findUserByClassId(Long classId, Long gradeId) { String sql = "select * from student t where t.class_id=? and t.grade_id=? and t.deleted!=1"; SQLQuery query = this.createSQLQuery(sql, classId, gradeId); return query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list(); }
public List<Map<String, Object>> findUserByClassId(Long classId, Long gradeId) { StringBuffer sql = new StringBuffer(); sql.append("select * from student t") .append(" where t.class_id=:classId and t.grade_id=:gradeId and t.deleted!=1 "); SQLQuery q = this.getSession().createSQLQuery(sql.toString()); q.setLong("classId", classId); q.setLong("gradeId",gradeId); return q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list(); }//查询原生的object对象 然后再去遍历转换为我们需要的类型
public List<Map<String, String>> findAllStudent(){ StringBuffer sql = new StringBuffer(); sql.append("select distinct stu_no as value ,stu_name as name from student order by stu_no "); SQLQuery query = createSQLQuery(sql.toString()); List<Object[]> list = query.list(); List<Map<String, String>> mapList = new ArrayList<Map<String, String>>(); if (list.size() > 0) { for (Object[] obj : list) { Map<String, String> detailMap = new HashMap<String, String>(); detailMap.put("value", obj[0].toString()); detailMap.put("name", obj[1].toString()); mapList.add(detailMap); } } if (mapList.size() > 0) { return mapList; } return null; }
//返回List<Object[]> public List<Object[]> findById(Long classId, Long gradeId) { String sql = " select * from (select rownum rn,b.* from (select * from student t " + " order by t.id,t.no,t.t.name) b where where t.class_id=? and t.grade_id=? )"; SQLQuery q = this.createSQLQuery(sql, classId, gradeId); List<Object[]> list = q.list(); return list; }
//返回值为:List<String>public List<String> findUserNameByClassId(Long classId, Long gradeId){
StringBuffer sql = new StringBuffer(); sql.append("SELECT stu_name FROM student "); sql.append("WHERE class_id = '"+classId+"' and grade_id='"+gradeId+"' "); List<String> list=this.getSession().createSQLQuery(sql.toString()).list(); return list; }
//一个返回值: public int countStudent(Long classId, Long gradeId,String sex) { StringBuffer sqlStr = new StringBuffer(" select count(*) from student t where where t.class_id=:classId and t.grade_id=:gradeId and t.deleted!=1 "); if(sex!=null){ sqlStr.append(" AND t.sex = :sex "); } SQLQuery q = getSession().createSQLQuery(sqlStr.toString()); q.setLong("classId", classId); q.setLong("gradeId", gradeId); if(sex!=null){ q.setString("sex", sex); } //int countNumber = Integer.parseInt(q.uniqueResult().toString()); int countNumber = Integer.parseInt(q.list().get(0).toString());//Integer.valueOf(q.list().get(0).toString()).intValue(); return countNumber; }
public String getComment(Long id){
StringBuffer sql = new StringBuffer(); sql.append("select stu_name FROM student t") .append(" where stu_id=?"); SQLQuery query = this.getSession().createSQLQuery(sql.toString(),id); return query.list().get(0) == null ? "" : query.list().get(0).toString(); } //不带返回值:如insert,delete,update
public void insertStudent(Long classId, Long gradeId){ StringBuffer sql = new StringBuffer(); sql.append("insert into student(id,name) values('001','Jane') where class_id=:classId and grade_id = :gradeId"); SQLQuery sqlQuery = this.getSession().createSQLQuery(sql.toString()); sqlQuery.setLong("classId", classId); sqlQuery.setLong("gradeId", gradeId); sqlQuery.executeUpdate(); }
public void createStudentHis(String classId,String gradeId) {
String sql = "insert into STUDENT_HIS(id,name,sex,class_id,grade_id) " + "select STUDENT_HIS_SEQ.nextval,name,sex,?,? from STUDENT "; this.executeSQL(sql, classId,gradeId); }
public List<Map<String, Object>> getStudentList(Long classId, Long gradeId, int page, int rows) { StringBuffer sql = new StringBuffer(); sql.append("SELECT * FROM student "); sql.append("WHERE class_id=:classId AND grade_id = :gradeId "); sql.append(" ORDER BY stu_no "); SQLQuery sqlQuery = this.getSession().createSQLQuery(sql.toString()); sqlQuery.setLong("classId", classId); sqlQuery.setLong("gradeId", gradeId); return sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).setFirstResult((page - 1) * rows).setMaxResults(rows).list(); }
注:[b]append( )是类StringBuffer的一个方法。作用是在已有字符串后面添加一个字符串,主要用于sql语句拼接及字符串连接。[/b]
增加,删除,修改或查询的sql语句,在多种可变的条件下,
在写sql语句时会用到StringBuffer.append()进行条件连接,但是如果里面添加了字符串连接符,那么这个StringBuffer对象的地址就变了,append里面不能用+连接符(???????)
public List<Object[]> findStudentList(String name, String address) { StringBuffer sql = new StringBuffer(); sql.append("select * from student as t where 1=1"); if (name != null || !"".equals(name)) { //此处不建议使用 sql.append(" and t.name ='" + name + "'"); sql.append(" and t.name =?"); } if (address != null || !"".equals(address)) { sql.append(" and t.address =?"); } SQLQuery query = this.getSession().createSQLQuery(sql.toString()); return query.list(); }以上就是拼接sql语句,也就是说select * from student as t where 1=1一定会执行,而后面两个会根据参数选择执行
String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 三者的区别:http://blog.csdn.net/rmn190/article/details/1492013
三、使用Session.createQuery(string hql)
public void insertStudent(String stuId) { String hql = "delete from Student where id ='"+stuId+"'"; this.getSession().createQuery(hql).executeUpdate(); }
小结:session.createQuery(hql) 与session.createSQLQuery(sql)区别
createQuery:执行时传入的参数为HQL语句,以hibernate生成的Bean为对象装入list返回
createSQLQuery:执行时传入的参数为SQL语句,返回的结果根据查询的字段数进行区分,如果查询一个字段,则返回该字段类型的集合,如果查询的为多个字段,则将这些字段组合成一个对象数组,返回该对象数组的集合。
所以使用createSQLQuery有时候也想以hibernate生成的Bean为对象装入list返回,就不是很方便,突然发现createSQLQuery有这样一个方法可以直接转换对象
Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class);
XXXXXXX 代表以hibernate生成的Bean的对象,也就是数据表映射出的Bean。
public List<Student> findStudent(Long classId, Long gradeId) { //尽量避免适用"*" String sql = "select * from student t where t.class_id=? and t.grade_id=? and t.deleted!=1"; SQLQuery query = this.createSQLQuery(sql, classId, gradeId); query.addEntity(Student.class); List<Student> retList = query.list(); }
还有另外一个相关的小细节应注意:
比如有这样一个po
PO: User.class
properties: userId,userName
DDL: create table tuser (userid varchar(10),username varchar(20));
当执行:
session.createQuery("from User u").list()时生成的SQL:select userid,username from tuser;
当执行:
session.createQuery("from User u").iterator()时生成的SQL:select userid from tuser;
可以看出
list()一次将数据从数据库中读出直接填充到List中
iterator()将数据的主键从数据库中读出,当循环这个Iterator时才添加执行:select userid,username from user where userid=?;把数据读出。
在不同的应用范围使用不同的方法,具体在hibernate应用中应当注意。
4.使用 this. getHibernateTemplate()
HibernateTemplate提供非常多的常用方法来完成基本的操作,比如通常的增加、删除、修改、查询等操作,Spring2.0更增加对命名SQL查询的支持,也增加对分页的支持。大部分情况下,使用Hibernate的常规用法,就可完成大多数DAO对象的CRUD操作。下面是HibernateTemplate的常用方法简介:
q void delete(Object entity):删除指定持久化实例
public void deleteStudent(Long id) {
this.projectADao.delete(id); }
q deleteAll(Collection entities):删除集合内全部持久化类实例
q find(String queryString):根据HQL查询字符串来返回实例集合
public List<Student> findUserByClassId(Long classId, String gradeId) { return find("from Student where classId = ? and gradeId = ?", classId, gradeId); }
q findAll():返回实例集合
public String findAllStudent() { List<Student> studentList = this.stuDao.findAll(); String studentListJson = BaseUtils.fetchCollectionToJson(studentList, "id", "stuNo"); return "["+studentListJson+"]"; }
q findByNamedQuery(String queryName):根据命名查询返回实例集合
q get(Class entityClass, Serializable id):根据主键加载特定持久化类的实例
public Student findStudentDetail(Long id) { return this.stuDao.get(id); }
q save(Object entity):保存新的实例
public void deleteStudent(Long id) {//删除标示 0:未删除 1:删除 Student stu= this.stuDao.get(id); stu.setLastUpdated(new Date()); stu.setDeleted(1); this.stuDao.save(stu); }
q saveOrUpdate(Object entity):根据实例状态,选择保存或者更新
String version="00"; hql = "from TmsTsReference where tmsTmProjectId=? and targetLevel=0"; List<TmsTsReference> referenceList = this.find(hql, tmsTmProjectId); for (TmsTsReference tmsTsReference : referenceList) { TmsHisTsReference tmsHisTsReference = new TmsHisTsReference(); ReflectionUtils.getInstance(tmsHisTsReference, tmsTsReference); tmsHisTsReference.setVersion(version); this.getSession().saveOrUpdate(tmsHisTsReference); }
q update(Object entity):更新实例的状态,要求entity是持久状态
q setMaxResults(int maxResults):设置分页的大小
public Object findUnique(String hql, Object... values) {
return this.createQuery(hql, values).uniqueResult();
}
public Student findStudentBySex(String sex) { String hql = "from Student t where t.sex = ?"; Student stu = (Student) this.findUnique(hql, sex); return stu; }
***************************************************************
附上 Hibernate Query 对象简述
可以透过org.hibernate.Query介面的实例来进行查询,透过Query介面,您可以先设定查询参数,之后透过setXXX()等方法,将指定的参数值填入,而不用每次都撰写完整的HQL,直接来看个例子:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.name from User asuser where user.age > ?");
query.setInteger(0, 25);
List names = query.list();
Iterator iterator = names.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
session.close();
在设定参数值时,必须依照 ? 所设定的顺序,并使用对应型态的setXXX()方法
你可以使用命名参数(NamedParameter)来取代这个方法,这可以不用依照特定的顺序来设定参数值,并拥有较好的可读性,直接来看个例子:
Session session = sessionFactory.openSession();
Query query = session.createQuery("select user.name from User asuser where user.age > :minAge");
query.setInteger("minAge", 25);
List names = query.list();
Iterator iterator = names.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
session.close();
设定命名参数时,在建立Query时先使用:后跟着参数名,之后就可以在setXXX()方法直接指定参数名来设定参数值,而不用依照特定的顺序。
*********************************************
getSession() 和getHibernateTemplate()方法区别
1.使用getSession()方法你只要继承sessionFactory,而使用getHibernateTemplate()方法必须继承HibernateDaoSupport当然包括sessionFactory,这点区别都不是特别重要的,下面这些区别就很重要了
2.getSession()方法是没有经过spring包装的,spring会把最原始的session给你,在使用完之后必须自己调用相应的close方法,而且也不会对声明式事务进行相应的管理,一旦没有及时关闭连接,就会导致数据库连接池的连接数溢出,getHibernateTemplate()方法是经过spring封装的,例如添加相应的声明式事务管理,由spring管理相应的连接。
在实际的使用过程中发现的确getHibernateTemplate()比getSession()方法要好很多,但是有些方法在getHibernateTemplate()并没有提供,这时我们用HibernateCallback回调的方法管理数据库.
例如如下代码:
public List getListForPage ( final String hql , final int offset ,final int length ) {
List list = getHibernateTemplate().executeFind ( newHibernateCallback ( ) {
public Object doInHibernate ( Session session ) throwsHibernateException, SQLException {
Queryquery = session.createQuery ( hql ) ;
query.setFirstResult( offset ) ;
query.setMaxResults( length ) ;
Listlist = query.list ( ) ;
returnlist ;
}
相关文章推荐
- Spring 中配置sessionFactory及用法
- 对java数组的理解
- java基础语法练习--输入年月日确定星期几
- Struts2学习笔记(1)-入门教程
- 更改eclipse(myeclipse) author的默认名字(注释的作者)
- JAVA并发-3种典型的死锁
- [置顶] java支付宝无密退款
- java ——解析json遇到的问题
- 打开eclipse报错:发现了以元素 ‘d:skin’ 开头的无效内容。此处不应含有子元素
- JAVA基础知识回顾-----File类-----实用
- springmvc+mybatis+spring 整合
- Eclipse转战Android Studio心酸史
- java开发经典书籍
- [Java] super,this 的区别及构造方法的使用
- [Java] 获取随机数的3种方法
- GC的介绍
- java代码调用使用cxf搭建的webService服务传递对象
- JAVA 中IO总结 之前篇阻塞、非阻塞
- 学习练习 java练习小题题目:判断一个整数能被几个9整除
- jsp与JavaBean