JNDI技术简介
JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.naming包,
这套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需通过名称检索即可。
其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。
配置Tomcat数据源
示例代码:
<Context>
<Resource name="jdbc/datasource" auth="Container"
type="javax.sql.DataSource" username="root"password="root"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/jdbc"
maxActive="8" maxIdle="4"/>
</Context>
Context initCtx = new InitialContext();
Context envCtx = (Context)initCtx.lookup("java:comp/env");
dataSource =(DataSource)envCtx.lookup("jdbc/datasource");
特别提醒:此种配置下,驱动jar文件需放置在tomcat的lib下
编写自己的JDBC框架
元数据-DataBaseMetaData
元数据:数据库、表、列的定义信息。
Connection.getDatabaseMetaData()
DataBaseMetaData对象
getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
元数据-ParameterMetaData
PreparedStatement . getParameterMetaData()
获得代表PreparedStatement元数据的ParameterMetaData对象。
Select * from user where name=? Andpassword=?
ParameterMetaData对象
getParameterCount()
获得指定参数的个数
getParameterType(int param)
获得指定参数的sql类型
元数据-ResultSetMetaData
ResultSet. getMetaData()
获得代表ResultSet对象元数据的ResultSetMetaData对象。
ResultSetMetaData对象
getColumnCount()
返回resultset对象的列数
getColumnName(int column)
获得指定列的名称
getColumnTypeName(int column)
获得指定列的类型
使用元数据简化JDBC代码
业务背景:系统中所有实体对象都涉及到基本的CRUD操作:
所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句。
实体的R操作,除SQL语句不同之外,根据操作的实体不同,对ResultSet的映射也各不相同,因此可义一个query方法,除以参数形式接收变化的SQL语句外,可以使用策略模式由qurey方法的调用者决定如何把ResultSet中的数据映射到实体对象中。
例子:
DBManger_dbcp.java--------------用于建立连接和简化的CRUD代码
package com.hbsi.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class DBManger_dbcp {
private staticDataSource ds;
static {
try {
InputStreamin = DBManger_dbcp.class.getClassLoader()
.getResourceAsStream("dbcpconfig.properties");
Propertiesprop = new Properties();
prop.load(in);
ds= BasicDataSourceFactory.createDataSource(prop);
} catch(Exception e) {
e.printStackTrace();
}
}
public staticConnection getConnection() throws SQLException {
returnds.getConnection();
}
public staticvoid dbClose1(Statement st, Connection con) {
if (st!= null) {
try{
st.close();
}catch (SQLException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
if (con!= null) {
try{
con.close();
}catch (SQLException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public staticvoid dbClose(ResultSet rs, Statement st, Connection con) {
if (rs!= null) {
try{
rs.close();
}catch (SQLException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
dbClose1(st,con);
}
public staticvoid update(String sql, Object[] params) {
Connectionconn = null;
PreparedStatementst = null;
try {
conn= DBManger_dbcp.getConnection();
st= conn.prepareStatement(sql);
for(int i = 0; i < params.length; i++) {
st.setObject(i+ 1, params[i]);
}
st.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
}finally {
DBManger_dbcp.dbClose1(st,conn);
}
}
public staticObject query(String sql, Object[] params, ResultSetHandler h) {
Connectionconn = null;
PreparedStatementst = null;
ResultSetrs = null;
try {
conn= DBManger_dbcp.getConnection();
st= conn.prepareStatement(sql);
for(int i = 0; i < params.length; i++) {
st.setObject(i+ 1, params[i]);
}
rs= st.executeQuery();
returnh.handler(rs);
} catch(Exception e) {
thrownew RuntimeException(e);
}finally {
DBManger_dbcp.dbClose(rs,st, conn);
}
}
}
User.java-----------------------一个实体类
packagecom.hbsi.bean;
publicclass User {
private int id;
private String name;
private String pass;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
ResultSetHandler.java------------一个接口,提供数据库查找所用的方法
package com.hbsi.util;
import java.sql.ResultSet;
public interface ResultSetHandler {
public Objecthandler(ResultSet rs);
}
BeanHandler.java---------------------实现上面的接口
package com.hbsi.util;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class BeanHandler implements ResultSetHandler {
private Classclazz;
public BeanHandler(Class clazz){
this.clazz=clazz;
}
@Override
public Objecthandler(ResultSet rs) {
try{
if(!rs.next()){
returnnull;
}
Objectbean=clazz.newInstance();
ResultSetMetaDatameta=rs.getMetaData();
intcount=meta.getColumnCount();
for(inti=0;i<count;i++){
StringcolumnName=meta.getColumnName(i+1);
Objectvalue=rs.getObject(columnName);
//Fieldf=bean.getClass().getField(columnName);
Fieldf=bean.getClass().getDeclaredField(columnName);
f.setAccessible(true);
f.set(bean,value);
}
returnbean;
}catch(Exceptione){
e.printStackTrace();
thrownew RuntimeException(e);
}
}
}
CRUDTest.java----------------测试方法的类
package com.hbsi.demo;
import org.junit.Test;
import com.hbsi.bean.User;
import com.hbsi.util.BeanHandler;
import com.hbsi.util.DBManger_dbcp;
public class CRUDTest {
@Test
public voidinsert() {
Stringsql = "insert into pool(id,name,pass)values(?,?,?)";
Object[]params = { 4, "d", "123" };
DBManger_dbcp.update(sql,params);
}
@Test
public voiddelete() {
Stringsql = "delete from pool where id=?";
Object[]params = { 4};
DBManger_dbcp.update(sql,params);
}
@Test
public voidupdate() {
Stringsql = "update pool set name=?,pass=? where id=?";
Object[]params = { "f", "123",4 };
DBManger_dbcp.update(sql,params);
}
@Test
public voidfind() {
Stringsql = "select * from pool where id=?";
Object[]params = {1};
Userusers=(User) DBManger_dbcp.query(sql, params, new BeanHandler(User.class));
System.out.println(users.getId()+"--"+users.getName()+"--"+users.getPass());
}
}