刚开始使用JNDI,网上也查了不少资料,磕磕盼盼鼓捣了大半天才成功,在此记录一下。

介绍

首先还是再啰嗦两句,介绍一下JNDI技术。
JNDI是Java 命名和目录接口(Java Naming and Directory Interface,JNDI)的简称.从一开始就一直是 JavaEE 企业的核心技术之一。在JMS,JMail,JDBC,EJB等技术中,就大量应用的这种技术。

服务端容器配置(基于Tomcat)

修改conf/server.xml文件,在GlobalNamingResources节点中添加

1
2
3
4
5
6
7
8
9
10
<Resource name="jdbc/bookshop" auth="Container"
scope="jdbc/bookshop"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.1.2:3306/bookshop"
username="root"
password="lu123"
maxActive="50"
maxIdle="30"
maxWait="10000" />

然后接着再修改conf/context.xml文件,在Context节点中添加引用

1
2
3
4
5
<ResourceLink
global="jdbc/bookshop"
name="jdbc/bookshop"
auth="Container"
type="javax.sql.DataSource"/>

很简单,这个服务器就配置好了,最后还需要重启一下tomcat服务,别忘啦。。接下来再看看项目配置。

项目配置

项目只是一个简单的测试Demo,首先看看pom.xml文件项目依赖配置。

### 项目依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.0.Final</version>
</dependency>

<!--<dependency>-->
<!--<groupId>mysql</groupId>-->
<!--<artifactId>mysql-connector-java</artifactId>-->
<!--<version>6.0.3</version>-->
<!--</dependency>-->

<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>

</dependencies>

这里因为我们使用JNDI技术,数据库的驱动由Tomcat容器提供,所以我们的项目中就不需要再依赖它了,这样一来灵活性也非常高了。

Hibernate配置

这里列出简单的hibernate配置,新建一个hibernate.cfg.xml文件放置到项目classpath中,我用的是Idea,也可以放在resources目录中,添加文件内容:

hibernate.cfg.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--<property name="connection.url">jdbc:mysql://192.168.1.2:3306/bookshop</property>-->
<!--<property name="connection.driver_class">com.mysql.jdbc.Driver</property>-->
<!--<property name="connection.username">root</property>-->
<!--<property name="connection.password">lu123</property>-->

<!-- JNDI -->
<property name="connection.datasource">java:comp/env/jdbc/bookshop</property>

<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>

<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

<property name="hibernate.current_session_context_class">thread</property>


<mapping resource="Users.hbm.xml"/>

</session-factory>
</hibernate-configuration>

可以看到,在使用JNDI之前需要配置一大堆的东西,如:url,数据库连接用户名,密码,驱动类等等。现在使用JNDI之后,只需要提供一个数据源即可,确实比之前方便不少。
注意配置文件中映射了一个Users.hbm.xml文件,这个文件其实就是用hibernate映射一个JavaBean的配置文件,不过貌似现在都提倡使用注解的方式了。但是还是有可能会遇到需要维护旧的项目,而旧的项目大都是使用xml来进行配置的,所以还是了解下这个比较好。

Users.hbm.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/xsd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

<class name="com.example.hibernate.bean.Users" table="users" catalog="bookshop">
<id name="id" type="java.lang.Integer">
<column name="Id"/>
<generator class="native"></generator>
</id>

<property name="loginName" type="java.lang.String">
<column name="LoginName" length="50"/>
</property>

<property name="loginPwd" type="java.lang.String">
<column name="LoginPwd" length="16"/>
</property>
</class>
</hibernate-mapping>

很简单,就不做过多介绍,根据这个再创建JavaBean类就行,就不贴那个了。

web.xml配置

一般JavaEE web项目都需要一个web.xml文件的,不过貌似随着Spring的潮流,提倡不需要web.xml也可以了。。但还是那句老话,旧的项目正赚钱着不可能都给推掉了。

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8" ?>
<web-app 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"
version="3.1">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
<servlet-name>user</servlet-name>
<servlet-class>com.example.hibernate.controller.UserController</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>

</web-app>

这个文件很简单,就只配置一个Servlet,项目配置的东西基本上就都说完了,现在再来看看项目代码结构了。

项目代码结构

Idea
Idea

我使用的是IntelliJ IDEA,据说这个是Java中最好的IDE。。
项目结构也很简单,能省的都给省了。
先看一下HibernateSessionFactory.java这个文件,它主要就是在项目中引入Hibernate的配置,并获取到Session,而我们增删改查等操作就都是通过这个Session来控制的。

HibernateSessionFactory.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.example.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
* Created by Administrator on 2016/9/25.
*/
public class HibernateSessionFactory {

private static Configuration configure;
private static SessionFactory sessionFactory;

static {
configure = new Configuration().configure();
sessionFactory = configure.buildSessionFactory();
}

public static Session getSession() {
return sessionFactory.openSession();
}
}

也很简单的操作,就是根据配置文件来获取Session的,而Hibernate的实际操作就是通过这个Session来完成的。
我们先从DAO层开始,来看下BaseHibernateDAO.java文件

BaseHibernateDAO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.example.hibernate.dao;

import com.example.hibernate.HibernateSessionFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;

import java.io.Serializable;

/**
* Created by Administrator on 2016/9/25.
*/
public abstract class BaseHibernateDAO {

protected void add(Object object) {
Transaction tx = null;

// 获取session
Session session = HibernateSessionFactory.getSession();

try {
// 开始事务
tx = session.beginTransaction();

// 持久化操作
session.save(object);

tx.commit();
} catch (Exception e) {
if (tx != null) {
// 回滚事务
tx.rollback();
}
e.printStackTrace();
} finally {
// 关闭session
session.close();
}
}


protected Object get(Class cla, Serializable id) {
Object obj = null;

Session session = HibernateSessionFactory.getSession();
try {
obj = session.get(cla, id);
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}

return obj;
}

protected void delete(Object object) {

Transaction tx = null;

Session session = HibernateSessionFactory.getSession();

try {
tx = session.beginTransaction();
session.delete(object);

tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}


protected void update(Object object) {
Transaction tx = null;
Session session = HibernateSessionFactory.getSession();

try {
tx = session.beginTransaction();
session.update(object);

tx.commit();
} catch (Exception e) {

if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}
}

这里也很简单,毕竟只是为了演示测试使用,真正的项目肯定不应该这样的。
再来看看UserDAO.java文件,它主要是提供了上层能够操作的接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.hibernate.dao;

import com.example.hibernate.bean.Users;

/**
* Created by Administrator on 2016/9/25.
*/
public interface UserDAO {

void add(Users users);
void delete(Users users);

Users load(Integer id);

void update(Users users);
}

UserDAOImpl.java也没什么内容,其实就是我懒。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.hibernate.dao;

import com.example.hibernate.bean.Users;

/**
* Created by Administrator on 2016/9/25.
*/
public class UserDAOImpl extends BaseHibernateDAO implements UserDAO {
public void add(Users users) {
super.add(users);
}

public void delete(Users users) {
super.delete(users);
}

public Users load(Integer id) {
return (Users) super.get(Users.class, id);
}

public void update(Users users) {
super.update(users);
}
}

再来看看关键的Controller,主要就是响应web页面的请求的。

UserController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.example.hibernate.controller;

import com.example.hibernate.bean.Users;
import com.example.hibernate.dao.UserDAO;
import com.example.hibernate.dao.UserDAOImpl;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
* Created by Administrator on 2016/10/2.
*/
public class UserController extends HttpServlet {


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
UserDAO dao = new UserDAOImpl();
Users load = dao.load(3);

PrintWriter writer = resp.getWriter();
writer.print("get = " + load.toString());
}


@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

也很简单,相信初学者也都能看懂,当然了我也是一个Web的初学者,之前都是做Android应用开发,现在是做Android系统Framework开发,而未来我打算想做Web后端开发,努力学习ing…

哦,对了。还有最关键的数据库方面还没说。。

数据库配置

Mysql user data
Mysql user data

使用Navicat for MySQL可以很方便设计数据库表和进行增删改查等操作,挺强大的一个功能是还能从excel表格中导入数据。

mysql user design
mysql user design

总结

好了,一个简单Hibernate+JNDI配置就说到这吧。当然,配置的方式有很多种,但是只要适合自己就好了。
这里最后再吐槽一句,网上的教程一大堆也太不完整了,东一点西一点的,说一大堆还是不会用。即使是只作为自己的一个笔记,起码也要说清楚一点比较好吧,万一后来自己再来翻的时候都看不懂,那就笑了。
而作为一个教程类,起码得要能run跑起来吧?