您的位置:首页 > 编程语言 > Java开发

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 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 ;

                          }

             
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: