这里主要使用EJB+JPA+Primefaces+glassfish实现对单表的增删改查操作。首先我们需要了解的是,这三个是什么东西。这里就不做赘述了,直接上代码吧。有需要可以去找相关的资料来学习。
首先是我们的项目结构。这是一个Web项目,使用maven进行管理。
创建的过程也大概讲一下吧。我使用的工具是IDEA,这里直接使用maven模版创建项目就好了。
项目创建完成之后,根据前面的项目结构创建好相关的文件夹及文件就可以了。
然后,首先我们需要引入我们所需的Jar包:首先我们需要引入相关的Jar包。这是我的pom文件,就不用一个个去加依赖了。注意这里的groupId、artifactId、name、filename等,记得修改成大家自己的项目相关的信息。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>demo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>demo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>demo</finalName>
</build>
</project>
然后就可以开始创建我们的entity类。对应我们数据库表的相关内容。
@Entity
@Table(name = "tablename")
public class TableName implements Serializable {
@Id
@Column(name = "table_id")
private String table_id;
@Column(name="table_column")
String table_column;
这里就不写具体的字段了,大家可以根据自己的表进行entity类的编写。几个注意点:这里的几个注解,@Entity表示这是一个Entity类,@Table表明这个类对应数据库中的表,name属性对应数据库中的表名。然后记得实现序列化接口implements Serializable。然后@Id表明这是主键,@Column表明对应到数据库中的字段,name对应字段名。
然后是我们的数据库操作类。这里我们使用JPA的方式进行dao操作。
@Stateless
public class EJBService {
@PersistenceContext(unitName = "xlJpa")
private EntityManager em;
public void add(PatientInfo patientInfo){
em.persist(patientInfo);
em.flush();
}
public void delete(String patient_number){
PatientInfo patientInfo = em.find(PatientInfo.class,patient_number);
em.remove(patientInfo);
}
public void update(PatientInfo patientInfo){
em.merge(patientInfo);
}
public List<PatientInfo> selectById(String patient_number){
List<PatientInfo> list = em.createNativeQuery("select * from patient_info where patient_number = ?patient_number",PatientInfo.class)
.setParameter("patient_number",patient_number).getResultList();
return list;
}
public List<PatientInfo> selectAll(){
List<PatientInfo> list =
em.createNativeQuery("select * from patient_info",PatientInfo.class).getResultList();
return list;
}
}
这里各个方法分别对应增删改查,方法简单易懂就不写注释了。只需要注意两个地方:一个是这个类需要使用@Stateless注解,表明这是一个无状态会话bean,我们待会会在controller中进行依赖注入。第二个是@PersistenceContext(unitName = "xlJpa")这个注解,对应到我们的persistence配置文件,这个待会再说。
然后就是我们的controller了。
@Named(value = "xlController")
@ViewScoped
public class EJBController implements Serializable {
private PatientInfo patientInfo;
@Inject
private EJBService ejbService;
private List<PatientInfo> patientInfos;
public List<PatientInfo> getPatientInfos() {
patientInfos = getPatientInfoList();
return patientInfos;
}
public void setPatientInfos(List<PatientInfo> patientInfos) {
this.patientInfos = patientInfos;
}
public void select(PatientInfo patientInfo){
this.patientInfo = patientInfo;
}
public PatientInfo getPatientInfo() {
return patientInfo;
}
public void setPatientInfo(PatientInfo patientInfo) {
this.patientInfo = patientInfo;
}
public void add(){
ejbService.add(patientInfo);
}
public void delete(){
ejbService.delete(patientInfo.getPatient_number());
}
public void update(){
ejbService.update(patientInfo);
}
public void selectById(){
if(patientInfo.getPatient_number().equals("")) {
patientInfos = ejbService.selectAll();
}else{
patientInfos = ejbService.selectById(patientInfo.getPatient_number());
}
}
public List<PatientInfo> getPatientInfoList(){
patientInfos = ejbService.selectAll();
return patientInfos;
}
}
这里主要是注意类的两个注解,一个是给这个bean命名,一个是声明这个bean的作用域。然后我们使用@Inject来进行依赖注入,将Service注入到我们的Controller中。
然后是我们的persistence配置文件。这里是指定我们的数据库连接池,连接池配置在glassfish中进行,我们待会再讲。这里的jta-data-source对应glassfish中的数据库连接配置名。
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="xlJpa" transaction-type="JTA">
<!-- SmartInterface Configuration-->
<jta-data-source>jdbc/xlJPA2</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="none"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
</properties>
</persistence-unit>
</persistence>
然后要使用primefaces需要使用到faces-config.xml的配置文件。
<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
</faces-config>
然后在web.xml中也需要进行相关的配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>0</param-value>
</context-param>
<!--设置本地时区-->
<context-param>
<param-name>
javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE
</param-name>
<param-value>true</param-value>
</context-param>
<!--忽略注释-->
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>aristo</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<!--模型文件类型-->
<mime-mapping>
<extension>model</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
<extension>ttf</extension>
<mime-type>application/font-sfnt</mime-type>
</mime-mapping>
<mime-mapping>
<extension>woff</extension>
<mime-type>application/font-woff</mime-type>
</mime-mapping>
<mime-mapping>
<extension>woff2</extension>
<mime-type>application/font-woff2</mime-type>
</mime-mapping>
<mime-mapping>
<extension>eot</extension>
<mime-type>application/vnd.ms-fontobject</mime-type>
</mime-mapping>
<mime-mapping>
<extension>eot?#iefix</extension>
<mime-type>application/vnd.ms-fontobject</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#exosemibold</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#exobolditalic</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#exomedium</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#exoregular</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#fontawesomeregular</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
</web-app>
最后就是我们的界面了,之前我们的Controller已经Named了。这里直接使用我们起的名字+方法名或属性名就可以直接调用controller中的方法和属性了。
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title> List </title>
</h:head>
<h:body>
<h:form id="selectForm">
<p:outputLabel value="请输入住院号:"/>
<p:inputText value="#{xlController.patientInfo.patient_number}"/>
<p:commandButton value="搜索" actionListener="#{xlController.selectById}" update=":listForm:datalist"/>
</h:form>
<p:commandButton value="新增" οnclick="PF('addDialog').show()"/><br/>
<h:form id="listForm">
<p:dataTable id="datalist"
paginatorPosition="bottom"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {CurrentPageReport} "
currentPageReportTemplate="共{totalRecords}记录"
value="#{xlController.patientInfos}"
var="item"
paginator="true"
rows="5"
rowKey="#{item.patient_number}"
rowsPerPageTemplate="5,10,15">
<p:column headerText="入院号">
<h:outputText value="#{item.patient_number}" />
</p:column>
<p:column headerText="入院日期">
<h:outputText value="#{item.inhos_date}" />
</p:column>
<p:column headerText="身份证">
<h:outputText value="#{item.card_id}" />
</p:column>
<p:column headerText="姓名">
<h:outputText value="#{item.customer_name}" />
</p:column>
<p:column headerText="操作">
<!-- 刷新需要获取当前选中的条目的信息。并且刷新upDialog,来显示其当前信息. -->
<p:commandButton value="修改" actionListener="#{xlController.select(item)}" update=":upForm" oncomplete="PF('upDialog').show()"/>
<p:commandButton value="删除" actionListener="#{xlController.select(item)}" oncomplete="PF('delDialog').show()"/>
</p:column>
</p:dataTable>
</h:form>
<p:dialog header="确认删除?" widgetVar="delDialog" modal="true">
<h:form id="delForm">
<h:panelGrid columns="2" cellpadding="5" id="addPanel">
<p:outputLabel value="确认删除该信息?" /><br/>
<p:commandButton value="是" actionListener="#{xlController.delete}" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
oncomplete="PF('delDialog').hide()" update="listForm:datalist"/>
<p:commandButton value="否" oncomplete="PF('delDialog').hide()" />
</h:panelGrid>
</h:form>
</p:dialog>
<p:dialog header="add" widgetVar="addDialog" modal="true">
<h:form id="addForm">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="住院号:"/>
<p:inputText value="#{xlController.patientInfo.patient_number}"/>
<p:outputLabel value="入院日期:"/>
<p:inputText value="#{xlController.patientInfo.inhos_date}" />
<p:outputLabel value="身份证:"/>
<p:inputText value="#{xlController.patientInfo.card_id}" />
<p:outputLabel value="姓名:"/>
<p:inputText value="#{xlController.patientInfo.customer_name}"/>
<!--提交表单。并刷新数据列表和新增的表单。 -->
<p:commandButton value="新增" oncomplete="PF('addDialog').hide()"
actionListener="#{xlController.add}" update="addForm,listForm:datalist" />
<p:commandButton value="取消" oncomplete="PF('addDialog').hide()"/>
</h:panelGrid>
</h:form>
</p:dialog>
<p:dialog header="修改" widgetVar="upDialog" modal="true">
<h:form id="upForm">
<h:panelGrid columns="2" cellpadding="5">
<!--不可编辑。 -->
<!--<p:outputLabel value="住院号:"/>-->
<!--<p:inputText value="#{xlController.patientInfo.patient_number}"/>-->
<p:outputLabel value="入院日期:"/>
<p:inputText value="#{xlController.patientInfo.inhos_date}" />
<p:outputLabel value="身份证:"/>
<p:inputText value="#{xlController.patientInfo.card_id}" />
<p:outputLabel value="姓名:"/>
<p:inputText value="#{xlController.patientInfo.customer_name}"/>
<p:commandButton value="提交" icon="ui-icon-check" update="upForm,:listForm:datalist" actionListener="#{xlController.update}" oncomplete="PF('upDialog').hide()" />
<p:commandButton value="取消" oncomplete="PF('upDialog').hide()"/>
</h:panelGrid>
</h:form>
</p:dialog>
<br/>
</h:body>
</html>
然后就可以运行我们的程序了,这里我使用的服务器是glassfish5.0,第一次运行肯定是不能成功的,因为数据库连接相关配置还没有进行。这里等glassfish启动后,进入其管理端。默认端口4848,例如本地glassfish启动,就访问localhost:4848。在左侧找到相关的项,点击进行配置。先配置JDBC Connection Pools,这里我是用的mysql,所以是mysql相关的配置。
点击Next,编辑连接相关信息。
完成之后我们再配置JDBC Resource。
注意这里的JNDI Name需要和persistence中的jta-data-source配置保持一直。
完成之后重启glassfish,就可以访问到我们的项目了。
就一个JDBC的操作,内容还是蛮多的。这里主要是一个入门程序,后续我会继续完善一些注释的内容,这里时间有限就先撤了~代码优化后面也会进行。有问题希望大家提出,共同学习进步。
最后呢,作者水平有限,有什么问题大家可以提出来共同探讨学习。
差不多就是这样,祝大家学习愉快。谢谢。
—— by:轩辚 ——