Hibernate(十三)命名查询-批量处理和调用存储过程
一、命名查询
HQL语句混杂在代码之间将破坏代码的可读性
Hibernate允许在映射配置文件中定义字符串形式的查询语句,这种查询方式称为命名查询
二、建立数据表和持久化类
建立数据表
create table login ( username varchar2(32) primary key, password varchar2(32) not null , age number(3) ); insert into login select '张三','123456',21 from dual union select 'Tom','123123',34 from dual union select 'Jack','12345678',34 from dual union select '李四','qwerty',23 from dual; commit;
建立持久化类和配置文件
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> <property name="dialect"> org.hibernate.dialect.Oracle9Dialect </property> <property name="connection.url"> jdbc:oracle:thin:@localhost:1521:orcl </property> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.driver_class"> oracle.jdbc.OracleDriver </property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="entity/Login.hbm.xml" /> </session-factory> </hibernate-configuration>
持久化类和配置文件
package entity; public class Login implements java.io.Serializable { // Fields /** * */ private static final long serialVersionUID = 1L; private String username; private String password; private int age; // Constructors /** default constructor */ public Login() { } /** minimal constructor */ public Login(String username, String password) { this.username = username; this.password = password; } /** full constructor */ public Login(String username, String password, int age) { this.username = username; this.password = password; this.age = age; } // Property accessors public String getUsername() { return this.username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } }
配置文件Login.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="entity.Login" table="LOGIN" schema="ROOT"> <id name="username" type="java.lang.String"> <column name="USERNAME" length="32" /> <generator class="assigned" /> </id> <property name="password" type="java.lang.String"> <column name="PASSWORD" length="32" not-null="true" /> </property> <property name="age" type="java.lang.Integer"> <column name="AGE" precision="3" scale="0" /> </property> </class> <query name="loginUser"> <!--HQL查询语句 --> <![CDATA[ from Login login where login.username=:username and login.password=:password ]]> </query> </hibernate-mapping>
测试类:
package demo; import java.util.Iterator; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import entity.Login; public class Demo5 { /** * Criteria无查询条件查询所有 */ public static void main(String[] args) { //声明一个集合用来接收结果 List<Login> result=null; //声明SessionFactory SessionFactory factory=null; //声明Session Session session=null; // //初始化以上对象 //创建一个用户对象 Login lo=new Login(); lo.setUsername("Tom"); lo.setPassword("123123"); try{ factory=new Configuration().configure().buildSessionFactory(); session=factory.openSession(); //创建Query 参数为配置文件中的name Query query=session.getNamedQuery("loginUser"); //将对象作为参数传为 query.setProperties(lo); //查询使用list方法 result=query.list(); }catch(HibernateException e){ e.printStackTrace(); }finally{ session.close(); factory.close(); } //判断结果是否为空 Iterator<Login> iterator=result.iterator(); //如果有内容,--不为空 if(iterator.hasNext()){ //输出结果 Login login=iterator.next(); System.out.println("用户名:"+login.getUsername()+" 密码:"+login.getPassword()+" 年龄:"+login.getAge()); }else{ System.out.println("没有这个用户"); } } }
二、NativeSQL本地化SQL
2.1、执行本地SQL
package demo; import java.util.Iterator; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import entity.Login; public class Demo6 { /** * Criteria无查询条件查询所有 */ public static void main(String[] args) { //声明一个集合用来接收结果 List<Login> result=null; //声明SessionFactory SessionFactory factory=null; //声明Session Session session=null; String uname="Tom"; //初始化以上对象 try{ factory=new Configuration().configure().buildSessionFactory(); session=factory.openSession(); //声明Criteria对象传入一个持久化类对象类型 String sql="select {l.*} from login l where l.username=? "; //创建SQLQuery对象,传入2个参数,第一个参数为数据库表的别名,第二个为实体类的类 SQLQuery sqlQuery=session.createSQLQuery(sql).addEntity("l", Login.class); sqlQuery.setParameter(0, uname); //查询使用list方法 result=sqlQuery.list(); }catch(HibernateException e){ e.printStackTrace(); }finally{ session.close(); factory.close(); } System.out.println("=========="); Iterator<Login> iterator=result.iterator(); //输出结果 while(iterator.hasNext()){ Login login=iterator.next(); System.out.println("用户名:"+login.getUsername()+" 密码:"+login.getPassword()+" 年龄:"+login.getAge()); } } }
2.2、执行本地SQL命名查询
首先配置类的配置文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="entity.Login" table="LOGIN" schema="ROOT"> <id name="username" type="java.lang.String"> <column name="USERNAME" length="32" /> <generator class="assigned" /> </id> <property name="password" type="java.lang.String"> <column name="PASSWORD" length="32" not-null="true" /> </property> <property name="age" type="java.lang.Integer"> <column name="AGE" precision="3" scale="0" /> </property> </class> <query name="loginUser"> <!--HQL查询语句 --> <![CDATA[ from Login login where login.username=:username and login.password=:password ]]> </query> <!-- 本地SQL命名查询--> <sql-query name="findUser"> <![CDATA[ select {l.*} from login l where l.username=? ]]> <!--指定与实体类的关联 --> <return alias="l" class="entity.Login" /> </sql-query> </hibernate-mapping>
测试类
package demo; import java.util.Iterator; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import entity.Login; public class Demo7 { /** * Criteria无查询条件查询所有 */ public static void main(String[] args) { //声明一个集合用来接收结果 List<Login> result=null; //声明SessionFactory SessionFactory factory=null; //声明Session Session session=null; String uname="Tom"; //初始化以上对象 try{ factory=new Configuration().configure().buildSessionFactory(); session=factory.openSession(); Query query=session.getNamedQuery("findUser"); query.setParameter(0, uname); //查询使用list方法 result=query.list(); }catch(HibernateException e){ e.printStackTrace(); }finally{ session.close(); factory.close(); } System.out.println("=========="); Iterator<Login> iterator=result.iterator(); //输出结果 while(iterator.hasNext()){ Login login=iterator.next(); System.out.println("用户名:"+login.getUsername()+" 密码:"+login.getPassword()+" 年龄:"+login.getAge()); } } }
三、定制SQL
可以执行自己写的SQL语句来替代Hibernate的SQL,主要有3个保存,插入,删除,时就会执行我们自己写的SQL
- Insert和update语句,中的字段必须与映射文件中声明的相对应,一个都不能少
- Insert和update语句,中的属性出现的顺序必须与映射文件中声明的的顺序一致
- Insert语句,中的主键的顺序永远是在最后出现的
如果插入或者是更新时,不想插入或者更新一些字段只需要在映射文件中相应的字段后面加下insert="false",update="false";
四、指量处理数据
配置:
<?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> <property name="dialect"> org.hibernate.dialect.Oracle9Dialect </property> <property name="connection.url"> jdbc:oracle:thin:@localhost:1521:orcl </property> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.driver_class"> oracle.jdbc.OracleDriver </property> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="myeclipse.connection.profile">orcl</property> <property name="hibernate.jdbc.batch_size">20</property> <property name="hibernate.cache.use_second_level_cache">false</property> <mapping resource="entity/Login.hbm.xml" /> </session-factory> </hibernate-configuration>
测试类
package demo; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import entity.Login; public class Demo8 { /** * 批量插入数据 */ public static void main(String[] args) { //声明一个集合用来接收结果 List<Login> result=null; //声明SessionFactory SessionFactory factory=null; //声明Session Session session=null; //声明事务 Transaction tran=null; //初始化以上对象 try{ factory=new Configuration().configure().buildSessionFactory(); session=factory.openSession(); tran=session.beginTransaction(); for(int i=0;i<100;i++){ Login login=new Login(); login.setUsername(Integer.toString(i+100000)); login.setPassword(Integer.toString(i+100000)); login.setAge(i); session.save(login); //保存 if(i%20==0){ //单次处理的数据为20,与配置文件中设置的JDBC数量一样 session.flush(); //清理缓存 session.clear(); //清空缓存中的Login对象 } } tran.commit(); }catch(HibernateException e){ e.printStackTrace(); }finally{ session.close(); factory.close(); } } }
五、调用存储过程
调用插入
更新
删除
建立带输出参数的存储过程
命名SQL调用
配置文件中添加配置
调用
调用带输出结果集的存储过程