前言:最近要找工作,忙着复习,好久没用JDBC了,所以简单的回顾下:JDBC、JDK自带日志。
一:准备Jar包
ojdbc14.jar:oracle数据库驱动
commons-lang-2.6.jar:工具包
二:日志工具类
1:建立数据库链接配置文件db.properties(保存在src下):
jdbc.url=jdbc:oracle:thin:@xx.xx.xx.xx:1521:YY
jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.userName=root
jdbc.password=root
jdbc.initPoolsSize=4
2:建立DBUtil.java及QueryBuilder.java:
这里还有很多考虑不足的地方,比如:需要建立一个定时任务,定时进行查询来防止链接超时。
public class DBUtil {
private static String url = null;
private static String driverClass = null;
private static String userName = null;
private static String password = null;
private static int initPoolsSize = 2;
private static int poolIndex = 0;//当前已使用的链接数量
private static Object locked = new Object();//lock对象
private static List<Connection> connPools = new ArrayList<Connection>();
/**
* 静态初始化
*/
static {
InputStream in = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
Properties p = new Properties();
try {
p.load(in);
url = p.getProperty("jdbc.url");
driverClass = p.getProperty("jdbc.driverClass");
userName = p.getProperty("jdbc.userName");
password = p.getProperty("jdbc.password");
initPoolsSize = Integer.parseInt(p.getProperty("jdbc.initPoolsSize"));
} catch (IOException e) {
WebLogger.showWarning("数据库链接属性文件读取失败:"+e.getCause());
}
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
WebLogger.showWarning("驱动加载失败:"+e.getCause());
}
initConnPools(initPoolsSize);
}
/**
* 初始化数据库连接池
*/
private static boolean initConnPools(int poolSize){
boolean flag = false;
try {
for(int i=0;i<poolSize;i++){
connPools.add(DriverManager.getConnection(url,userName,password));
}
flag = true;
} catch (SQLException e) {
WebLogger.showWarning("初始化化数据库连接池失败:"+e.getCause());
}
return flag;
}
/**
* 获取数据库连接池中的链接
* @return
*/
public static Connection getConnection(){
Connection conn = null;
synchronized(locked){
if(poolIndex==connPools.size()){
initConnPools(1);
}
conn = connPools.get(poolIndex++);
}
return conn;
}
/**
* 释放链接
* @param conn
* @param stat
* @param rs
*/
public static void closeConnection(Connection conn,Statement stat,ResultSet rs){
if(conn!=null){
synchronized (locked) {
poolIndex--;//占用的连接数量减少
}
}
if(stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 查询工具方法
* @param <T>
* @param <T>
* @param conn
* @param sql
* @param params
*/
public static <T> T query(QueryBuilder<T> qb){
T obj = null;
Connection conn = getConnection();
if(conn==null){
return obj;
}
try {
PreparedStatement ps = conn.prepareStatement(qb.getPrepareSQL());
Object[] params = qb.getPrepareParams();
if(params.length>0){
qb.setParams(ps,params);
}
ResultSet rs = ps.executeQuery();
obj = qb.execute(rs);
String sqlMsg = "执行SQL:["+qb.getPrepareSQL();
if(params.length>0){
sqlMsg += ArrayUtils.toString(params);
}
sqlMsg += "]";
WebLogger.showInfo(sqlMsg);
closeConnection(conn,ps,rs);
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}
QueryBuilder中运用泛型来返回对象,参数预处理的方法是可选的,如果需要处理就需要重写setParams方法。
public abstract class QueryBuilder<T> {
private String sql = null;
private Object[] params = null;
public QueryBuilder(String sql,Object...params){
this.sql = sql;
this.params = params;
}
public String getPrepareSQL(){
return this.sql;
}
public Object[] getPrepareParams(){
return this.params;
}
/**
* 参数预处理
* @param ps
* @param params
*/
public void setParams(PreparedStatement ps,Object... params) throws Exception{};
/**
* 处理查询出来的数据
* @param rs
* @return
*/
public abstract T execute(ResultSet rs) throws Exception;
}
日志工具类:
/**
* @author WJL
* @date 2014-1-22
* @email wjl@zving.com
*/
public class WebLogger {
private static Logger logger = Logger.getLogger(WebLogger.class.getName());
static{
try {
FileHandler fileHandler = new FileHandler("D:\\log_"+System.currentTimeMillis()+".log");
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
fileHandler.setFormatter(new Formatter() {
@Override
public String format(LogRecord arg0) {
return String.format("%-8s",arg0.getLevel().getLocalizedName())+sdf.format(new Date(arg0.getMillis()) )+" : "+ arg0.getMessage()+"\n";
}
});
logger.addHandler(fileHandler);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void showWarning(String message){
logger.log(Level.WARNING, message);
}
public static void showInfo(String message){
logger.info(message);
}
public static void main(String[] args) {
WebLogger.showInfo("Hello World");
}
}
三:建立Dao层代码:
public interface UserDao {
/**
* 列出用户名
* @return
*/
public List<String> listUserName();
/**
* 根据邮箱查出用户信息
* @param name
* @param email
* @return
*/
public List<User> findUser(String email);
}
public class UserDaoImp implements UserDao{
@Override
public List<String> listUserName() {
return DBUtil.query(new QueryBuilder<List<String>>("Select UserName from ZDUser"){
@Override
public List<String> execute(ResultSet rs) throws SQLException {
List<String> names = new ArrayList<String>();
while(rs.next()){
names.add(rs.getString("UserName"));
}
return names;
}
});
}
@Override
public List<User> findUser(String email) {
return DBUtil.query(new QueryBuilder<List<User>>("Select * from ZDUser where email like ? ","%"+email+"%"){
@Override
public void setParams(PreparedStatement ps, Object... params) throws SQLException{
ps.setString(1, params[0].toString());
}
@Override
public List<User> execute(ResultSet rs) throws SQLException {
List<User> users = new ArrayList<User>();
User user = null;
while(rs.next()){
user = new User();
user.setEmail(rs.getString("Email"));
user.setLastLoginTime(rs.getDate("LastLoginTime"));
user.setName(rs.getString("UserName"));
user.setStatus(rs.getString("Status"));
users.add(user);
}
return users;
}
});
}
}
四:Bean对象及Service层
public class User {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
@Override
public String toString() {
return "User [name=" + name + ", status=" + status + ", email=" + email
+ ", lastLoginTime=" + lastLoginTime + "]";
}
private String name = null;
private String status = null;
private String email = null;
private Date lastLoginTime = null;
}
public interface UserService {
/**
* 列出用户名
* @return
*/
public List<String> listUserName();
/**
* 根据邮箱查出用户信息
* @param name
* @param email
* @return
*/
public List<User> findUser(String email);
}
public class UserServiceImp implements UserService{
@Override
public List<String> listUserName() {
return new UserDaoImp().listUserName();
}
@Override
public List<User> findUser(String email) {
return new UserDaoImp().findUser(email);
}
}
五:建立测试代码,调用及结果
public class Test {
public static void main(String[] args) {
UserService userService = new UserServiceImp();
for(User user : userService.findUser("wang")){
System.out.println(user);
}
}
}
注:数据库表结构请根据User对象自行设计
改工程代码可以到源码下载