zoukankan      html  css  js  c++  java
  • EJB3之查询

          

        EJB3的实体查询 本文 使用的是JPA规范进行操作  产品实现用的是Hibernate

    主要涉及到增加、删除、更新、对象查询带排序、查询条件中使用构造器、运算符查询、字符串函数、计算函数、聚合函数


    先来看看 提供EJB服务的无状态bean

    package com.undergrowth.bean.impl;
    
    import java.util.List;
    
    import javax.ejb.Remote;
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    
    import com.undergrowth.bean.Person;
    import com.undergrowth.bean.SimplePerson;
    import com.undergrowth.bean.service.IPerson;
    
    @Stateless
    @Remote(IPerson.class)
    public class PersonDao implements IPerson {
    
    	//依赖注入实体管理器
    	@PersistenceContext
    	EntityManager em;
    	
    	@Override
    	public void save(Person person) {
    		// TODO Auto-generated method stub
    		//由新建状态转为托管
    		em.persist(person);
    	}
    
    	@Override
    	public void delete(Integer personId) {
    		// TODO Auto-generated method stub
    		//由托管转为销毁
    		em.remove(getReferencesById(personId));
    	}
    
    	@Override
    	public void update(Person person) {
    		// TODO Auto-generated method stub
    		//由游离转为托管
    		em.merge(person);
    	}
    
    	@Override
    	public Person getById(Integer personId) {
    		// TODO Auto-generated method stub
    		return em.find(Person.class, personId);
    	}
    
    	@Override
    	public Person getReferencesById(Integer personId) {
    		// TODO Auto-generated method stub
    		//使用懒加载 返回代理对象  只有在使用get方法获取数据时  才加载对象
    		return em.getReference(Person.class, personId);
    	}
    
    	/**
    	 * 通过sql来获取对象
    	 * @param sql
    	 * @return
    	 */
    	@SuppressWarnings("unchecked")
    	@Override
    	public List<Person> getBySql(String sql) {
    		// TODO Auto-generated method stub
    		Query query=em.createQuery(sql);
    		return (List<Person>)query.getResultList();
    	}
    
    	/**
    	 * 通过sql来进行删除 添加 修改 数据
    	 * @param sql
    	 * @return
    	 */
    	@Override
    	public int cudBySql(String sql) {
    		// TODO Auto-generated method stub
    		Query query=em.createQuery(sql);
    		int num=query.executeUpdate();
    		return num;
    	}
    	
    	
    	@SuppressWarnings("unchecked")
    	@Override
    	public List<Person> getAllPersons() {
    		// TODO Auto-generated method stub
    		//使用JPQL进行查询结果集
    	return (List<Person>)em.createQuery("select p from Person p").getResultList();
    	}
    
    	/**
    	 * 返回部分对象
    	 */
    	@SuppressWarnings("unchecked")
    	@Override
    	public List<SimplePerson> getSimplePersonThroSql(String sql) {
    		// TODO Auto-generated method stub
    		return (List<SimplePerson>)em.createQuery(sql).getResultList();
    	}
    
    	/**
    	 * 通过查询返回单一的结果集
    	 */
    	@Override
    	public Object getBySqlRetSimple(String sql) {
    		// TODO Auto-generated method stub
    		Query query=em.createQuery(sql);
    		return query.getSingleResult();
    	}
    
    	
    
    }
    



    对应的远程接口

    package com.undergrowth.bean.service;
    
    import java.util.List;
    
    import javax.persistence.Query;
    
    import com.undergrowth.bean.Person;
    import com.undergrowth.bean.SimplePerson;
    
    public interface IPerson {
    	
    	//增删改查
    	public void save(Person person);
    	public void delete(Integer personId);
    	public void update(Person person);
    	/**
    	 * 通过sql来进行删除 添加 修改 数据
    	 * @param sql
    	 * @return
    	 */
    	public int  cudBySql(String sql);
    	public Person getById(Integer personId);
    	public Person getReferencesById(Integer personId);
    	/**
    	 * 通过sql来获取对象
    	 * @param sql
    	 * @return
    	 */
    	public List<Person> getBySql(String sql);
    	public List<Person> getAllPersons();
    	/**
    	 * 获取只有id name age的Person
    	 * @param sql
    	 * @return
    	 */
    	public List<SimplePerson> getSimplePersonThroSql(String sql);
    	public Object getBySqlRetSimple(String sql);
    	
    	
    }
    


    一对一的实体bean

    package com.undergrowth.bean;
    
    import java.io.Serializable;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    
    /*
     * 步骤
     * 1.一对一的相互关联 各自实体中拥有对方
     * 2.设置关系维护端与被维护端 指定级联的关系
     * 3.指明外键
     * 4.添加数据
     */
    
    @Entity
    @Table(name="person_info")
    public class Person implements Serializable{
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	@Id @GeneratedValue 
    	private Integer id;
    	@Column(length=10,nullable=false)
    	private String name;
    	@Column(nullable=false)
    	private Integer age;
    	//all表示当person进行增删改查的时候 级联的增删改查idcard
    	//optional为false表示外键不能为空
    	@OneToOne(cascade=CascadeType.ALL,optional=false)
    	//JoinColumn指明idcard_id作为外键 来维护两个表的关系
    	@JoinColumn(name="idcard_id")
    	private IDCard idCard;
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public Integer getAge() {
    		return age;
    	}
    	public void setAge(Integer age) {
    		this.age = age;
    	}
    	
    	public Person(){} //用于给反射机制使用
    	public IDCard getIdCard() {
    		return idCard;
    	}
    	public void setIdCard(IDCard idCard) {
    		this.idCard = idCard;
    	}
    	public Person(String name, Integer age, IDCard idCard) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.idCard = idCard;
    	}
    	
    	@Override
    	public String toString() {
    		return "Person [id=" + id + ", name=" + name + ", age=" + age
    				+ ", idCard=" + idCard + "]";
    	}
    	
    	
    	
    }
    


    package com.undergrowth.bean;
    
    import java.io.Serializable;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    
    
    @Entity
    @Table(name="idcard_info")
    public class IDCard implements Serializable{
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	@Id @GeneratedValue
    	private Integer id;
    	@Column(length=18,nullable=false)
    	private String cardNum;
    	@Column(length=20,nullable=false)
    	private String issuedBy;
    	//mappedBy指定使用person对象的idCard这个属性来进行维护表间关系 并指明自己是关系的被维护端
    	@OneToOne(mappedBy="idCard")
    	private Person person;
    	
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getCardNum() {
    		return cardNum;
    	}
    	public void setCardNum(String cardNum) {
    		this.cardNum = cardNum;
    	}
    	public String getIssuedBy() {
    		return issuedBy;
    	}
    	public void setIssuedBy(String issuedBy) {
    		this.issuedBy = issuedBy;
    	}
    	public IDCard(){} //用于给反射机制使用
    	public IDCard(String cardNum, String issuedBy) {
    		this.cardNum = cardNum;
    		this.issuedBy = issuedBy;
    	}
    	public Person getPerson() {
    		return person;
    	}
    	public void setPerson(Person person) {
    		this.person = person;
    	}
    	
    	@Override
    	public String toString() {
    		return "IDCard [id=" + id + ", cardNum=" + cardNum + ", issuedBy="
    				+ issuedBy + "]";
    	}
    	
    	
    }
    


    封装部分实体属性的SimplePerson

    package com.undergrowth.bean;
    
    import java.io.Serializable;
    
    public class SimplePerson implements  Serializable{
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	private Integer id;
    	private String name;
    	private Integer age;
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public Integer getAge() {
    		return age;
    	}
    	public void setAge(Integer age) {
    		this.age = age;
    	}
    	@Override
    	public String toString() {
    		return "SimplePerson [id=" + id + ", name=" + name + ", age=" + age
    				+ "]";
    	}
    	public SimplePerson(Integer id, String name, Integer age) {
    		super();
    		this.id = id;
    		this.name = name;
    		this.age = age;
    	}
    	public SimplePerson() {
    		super();
    	}
    	
    	
    }
    

    哦 persistence.xml文件

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
            version="2.0">
        <persistence-unit name="under" transaction-type="JTA">
        <jta-data-source>java:/myDataSource</jta-data-source>
            <properties>
             <property name="hibernate.hbm2ddl.auto" value="update" />
             <property name="hibernate.show_sql" value="true" />
             <property name="hibernate.format_sql" value="true"/>
            </properties>
        </persistence-unit>
    </persistence>

    ant的编译build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- ================================================ -->
    <!-- Sample buildfile for jar components -->
    <!-- -->
    <!-- ================================================ -->
    <project name="EJB3QL"  basedir=".">
        <!-- 定义属性 -->
        <property name="src.dir" value="${basedir}src" />
    	<!--  访问操作系统的环境变量  -->
        <property environment="env"  />
    	<!-- 设置jboss的目录 -->
        <property name="jboss.home" value="${env.JBOSS_HOME}"/>
    	<!-- 设置jboss的服务器名 -->
        <property name="jboss.server.home" value="standalone"  />
        <property name="dep" value="deployments"  />
        <property name="build.dir" value="${basedir}uild"  />
    
    	<!--构建path路径  -->
        <path id="build.classpath">
        	<fileset dir="${basedir}lib">
        		<include name="*.jar" />
        	</fileset>
        	<!--<pathelement location="${build.dir}" /> -->
        </path>
    
    	<!-- - - - - - - - - - - - - - -->
    	<!-- target: init -->
    	<!-- - - - - - - - - - - - - - -->
    	<target name="init">
    		<delete dir="${build.dir}"></delete>
    		<mkdir dir="${build.dir}"></mkdir>
    	</target>
    
    	<!-- ========================= -->
    	<!-- target: compile -->
    	<!-- ========================= -->
    	<target name="compile" depends="init"
    		description="--> compile  this component" >
             <!--  编译src目录下以com开头的所有子包中的类 
             '*' matches zero or more characters, '?' matches one character.
             When ** is used as the name of a directory in the pattern, it matches zero or more directories
             -->
    		<javac srcdir="${src.dir}" destdir="${build.dir}" includes="com/**" includeAntRuntime="false">
    			<classpath refid="build.classpath" />
    		</javac>
    	</target>
    	
    	<!-- 打包 -->
    	<target name="ejbjar" depends="compile" description="打包ejb">
    	   <jar jarfile="${basedir}${ant.project.name}.jar">
    	   	<fileset dir="${build.dir}">
    	   		<!-- 将build目录下的所有已class结尾的文件打包进去 -->
    	   		<include name="**/*.class"></include>
    	   	</fileset>
    	   	<!--将src目录下的META-INF目录下的文件打包进去 -->
    	   	<metainf dir="${src.dir}META-INF"></metainf>
    	   </jar>
    	</target>
      
        <!-- 部署 -->
        <target name="delopy" depends="ejbjar" description="部署ejb">
        	<copy file="${basedir}${ant.project.name}.jar"  todir="${jboss.home}${jboss.server.home}${dep}" />
        </target>
        
        <!-- 卸载ejb -->
        <target name="undeploy" description="卸载ejb">
          <delete file="${jboss.home}${jboss.server.home}${dep}${ant.project.name}.jar"></delete>
        </target>
        
    	<!-- 打包接口 -->
    	<target name="package_inter" depends="compile" description="打包接口">
    		<jar jarfile="${basedir}${ant.project.name}Interface.jar">
    			   	<fileset dir="${build.dir}">
    			   		<!-- 将build目录下中impl目录下的已class结尾的文件不打包进去 -->
    			   		<exclude name="**/impl/*.class"></exclude>
    			   	</fileset>
    			   </jar>
    	</target>
    	
    	<!--  删除生成的class和打包的文件 -->
    	<target name="clean" description="清除项目">
    		<delete dir="${build.dir}"></delete>
    		<delete file="${basedir}${ant.project.name}.jar"></delete>
    		<delete file="${basedir}${ant.project.name}Interface.jar"></delete>
    	</target>
    	
    
    </project>
    


    将无状态bean使用ant工具进行发布到jboss 中  后 即可通过客户端进行访问无状态的服务bean了


    2、

    客户端

    工具类 用于获取EJB服务

    package com.client.undergrowth.util;
    
    import java.util.Hashtable;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    import com.undergrowth.bean.service.IPerson;
    
    
    
    public class JndiUtil {
    
    	/**
    	 * 获取EJB PersonDao的服务
    	 * @return
    	 * @throws NamingException
    	 */
    	public static IPerson lookupIPersonRemoteBean() throws NamingException{
    	   return (IPerson)lookupRemoteBean("EJB3QL","PersonDao",IPerson.class.getName());
    	}
    	
    	/**
    	 * 通过模块名,Bean名称,接口名称获取远程服务
    	 * @param moduleName
    	 * @param beanName
    	 * @param viewClassName
    	 * @return
    	 * @throws NamingException
    	 */
    	public static Object lookupRemoteBean(String moduleName,String beanName,String viewClassName) throws NamingException {
            final Hashtable jndiProperties = new Hashtable();
            jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
            final Context context = new InitialContext(jndiProperties);
            // The app name is the application name of the deployed EJBs. This is typically the ear name
            // without the .ear suffix. However, the application name could be overridden in the application.xml of the
            // EJB deployment on the server.
            // Since we haven't deployed the application as a .ear, the app name for us will be an empty string
            final String appName = "";
            // This is the module name of the deployed EJBs on the server. This is typically the jar name of the
            // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
            // In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is
            // jboss-as-ejb-remote-app
            //final String moduleName = "EJB3QL";
            // AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for
            // our EJB deployment, so this is an empty string
            final String distinctName = "";
            // The EJB name which by default is the simple class name of the bean implementation class
           // final String beanName = "PersonDao";
            // the remote view fully qualified class name
           // final String viewClassName = HelloWorldRemote.class.getName();
           // final String viewClassName = IPerson.class.getName();
            // let's do the lookup
            return context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
            
     }
    	
    }
    



    单元测试类

    package com.junit.test;
    
    import static org.junit.Assert.*;
    
    import java.util.Iterator;
    import java.util.List;
    
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    import com.client.undergrowth.util.JndiUtil;
    import com.undergrowth.bean.IDCard;
    import com.undergrowth.bean.Person;
    import com.undergrowth.bean.SimplePerson;
    import com.undergrowth.bean.service.IPerson;
    
    public class PersonDaoTest {
    
    	static IPerson personDao = null;
        final int cudNum=8;
        
    	@BeforeClass
    	public static void setUpBeforeClass() throws Exception {
    		// 获取服务
    		personDao = JndiUtil.lookupIPersonRemoteBean();
    	}
    
    	/**
    	 * 保存
    	 */
    	@Test
    	public void testSave() {
    		IDCard idCard = new IDCard("333333333", "太平洋美国");
    		// 将关系被维护端的数据传递给关系维护端的数据 用于外键的更新
    		Person person = new Person("奥巴马", 5, idCard);
    		// 因为级联关系设置了级联保存 所以这里保存person 同时也会保存idCard
    		personDao.save(person);
    	}
    
    	/**
    	 * 删除
    	 */
    	@Test
    	public void testDelete() {
    		personDao.delete(cudNum);
    	}
    
    	/**
    	 * 更新
    	 */
    	@Test
    	public void testUpdate() {
    		Person person=personDao.getById(cudNum);
    		person.setName("普京");
    		personDao.update(person);
    	}
    
    	/**
    	 * 通过id获取对象
    	 */
    	@Test
    	public void testGetById() {
    		System.out.println(personDao.getById(cudNum));
    	}
    
    	/**
    	 * 获取对象代理
    	 */
    	@Test
    	public void testGetReferencesById() {
    		//可避免数据库加载的持久化开销 
    		//因为返回的是代理对象  没有持久化操作 所以这里会报错  无法获取对象
    		//System.out.println(personDao.getReferencesById(8));
    	}
    
    	/**
    	 * 对象查询
    	 */
    	@Test
    	public void testGetBySql() {
    		String sqlString="select p from Person p where p.age>12";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 对象查询带排序
    	 * order by asc/desc
    	 */
    	@Test
    	public void testGetBySqlOrderBy() {
    		String sqlString="select p from Person p order by p.age desc";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    
    	/**
    	 * 查询条件中使用构造器 返回构造器对象的结果集
    	 */
    	@Test
    	public void testGetSimplePersonThroSql() {
    		String sqlString="select new com.undergrowth.bean.SimplePerson(p.id,p.name,p.age) from Person p where p.age>8 order by p.age desc";
    		outListSimplePerson(personDao.getSimplePersonThroSql(sqlString));
    	}
    	
    	/**
    	 * 测试运算符 not 、between and 、like、in、is null、exists
    	 */
    	@Test
    	public void testOperatorBetween() {
    		String sqlString="select p from Person p where p.age between 2 and 15";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试运算符 not 、between and 、like、in、is null、exists
    	 */
    	@Test
    	public void testOperatorLike() {
    		String sqlString="select p from Person p where p.name like '%奥%' ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试运算符 not 、between and 、like、in、is null、exists
    	 */
    	@Test
    	public void testOperatorExists() {
    		String sqlString="select p from Person p where  exists(select pe from IDCard pe where pe.id>13) ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试字符串函数  upper lower concat length substring trim locate
    	 */
    	@Test
    	public void testStrFunc() {
    		String sqlString="select p from Person p where  length(p.name)>2 ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试计算函数  abs mod sqrt size
    	 */
    	@Test
    	public void testNumberFunc() {
    		String sqlString="select p from Person p where  mod(p.age,10) > 1 ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 返回单一的结果集 聚合函数 count max min avg sum
    	 */
    	@Test
    	public void testGetBySqlRetSimple() {
    		//这里不能使用count(1) 因为这是基于对象的查询 1被当做值 导致报错
    		String sqlString="select count(*) from Person p where p.age>8";
    		System.out.println("年龄大于8岁的人有"+personDao.getBySqlRetSimple(sqlString));
    	}
    	
    	/**
    	 * 使用语句进行更新 删除 增加
    	 */
    	@Test
    	public void testCudBySql() {
    		String sqlUpdateString="update Person p set p.name='刘德华' where p.age=20";
    		System.out.println("影响结果集为:"+personDao.cudBySql(sqlUpdateString)+"条");
    	}
    
    	/**
    	 * 获取所有对象
    	 */
    	@Test
    	public void testGetAllPersons() {
    		List<Person> list=personDao.getAllPersons();
    		outListPerson(list);
    	}
    
    	/**
    	 * 遍历输出结果集
    	 * @param list
    	 */
    	private void outListPerson(List<Person> list) {
    		// TODO Auto-generated method stub
    		for (Person person : list) {
    			System.out.println(person);	
    			}
    	}
    	
    	/**
    	 * 输出SimplePerson
    	 * @param list
    	 */
    	private void outListSimplePerson(List<SimplePerson> list) {
    		// TODO Auto-generated method stub
    		for (SimplePerson person : list) {
    			System.out.println(person);	
    			}
    	}
    	
    	
    
    }
    


    客户端连接jboss的jndi配置文件

    jboss-ejb-client.properties

    endpoint.name=client-endpoint  
    remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false  
       
    remote.connections=default  
       
    remote.connection.default.host= localhost
    remote.connection.default.port = 4447
    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false  
      
    remote.connection.default.username=qq     
    remote.connection.default.password=q  



  • 相关阅读:
    trackr: An AngularJS app with a Java 8 backend – Part III
    trackr: An AngularJS app with a Java 8 backend – Part II
    21. Wireless tools (无线工具 5个)
    20. Web proxies (网页代理 4个)
    19. Rootkit detectors (隐形工具包检测器 5个)
    18. Fuzzers (模糊测试器 4个)
    16. Antimalware (反病毒 3个)
    17. Debuggers (调试器 5个)
    15. Password auditing (密码审核 12个)
    14. Encryption tools (加密工具 8个)
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275549.html
Copyright © 2011-2022 走看看