简单通用JDBC辅助类封装(实例)

哎,最近很好久没写点东西了,由于工作的原因,接触公司自己研发的底层orm框架,偶然发现该框架在调用jdbc操作的时候参考的是hibernate 里面的SimpleJdbcTemplate,这里我想到了在大学的时候自己用过的一个简单的jdbc封装,现在我将代码贴出来,和大家一起分享:

Config类:读取同一包下的数据库连接配置文件,这样是为了更好的通用性考虑

package com.tly.dbutil;

import java.io.IOException;
import java.util.Properties;

public class Config {
  private static Properties prop = new Properties();
  static{
    try {
      //加载dbconfig.properties配置文件
      prop.load(Config.class.getResourceAsStream("dbconfig.properties"));
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  //设置常量
  public static final String CLASS_NAME = prop.getProperty("CLASS_NAME");
  public static final String DATABASE_URL = prop.getProperty("DATABASE_URL");
  public static final String SERVER_IP = prop.getProperty("SERVER_IP");
  public static final String SERVER_PORT = prop.getProperty("SERVER_PORT");
  public static final String DATABASE_SID = prop.getProperty("DATABASE_SID");
  public static final String USERNAME = prop.getProperty("USERNAME");
  public static final String PASSWORD = prop.getProperty("PASSWORD");

}

dbconfig.properties:数据库配置文件,你也可以用xml格式等,注意Config类里面该文件的调用位置

CLASS_NAME=com.mysql.jdbc.Driver
DATABASE_URL=jdbc:mysql
SERVER_IP=localhost
SERVER_PORT=3306
DATABASE_SID=employees
USERNAME=root
PASSWORD=1

接下来就是数据库连接辅助类DBConn了

package com.employees.dbutil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBConn {
  //三属性、四方法

  //三大核心接口
  private Connection conn = null;
  private PreparedStatement pstmt = null;
  private ResultSet rs = null;

  //四个方法
  //method1: 创建数据库的连接
  public Connection getConntion(){
    try {
      //1: 加载连接驱动,Java反射原理
      Class.forName(Config.CLASS_NAME);
      //2:创建Connection接口对象,用于获取MySQL数据库的连接对象。三个参数:url连接字符串  账号 密码
      String url = Config.DATABASE_URL+"://"+Config.SERVER_IP+":"+Config.SERVER_PORT+"/"+Config.DATABASE_SID;
      conn = DriverManager.getConnection(url,Config.USERNAME,Config.PASSWORD);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException e) {
      e.printStackTrace();
    }
    return conn;
  }

  //method2:关闭数据库的方法
  public void closeConn(){
    if(rs!=null){
      try {
        rs.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
    if(pstmt!=null){
      try {
        pstmt.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
    if(conn!=null){
      try {
        conn.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }

  //method3: 专门用于发送增删改语句的方法
  public int execOther(PreparedStatement pstmt){
    try {
      //1、使用Statement对象发送SQL语句
      int affectedRows = pstmt.executeUpdate();
      //2、返回结果
      return affectedRows;
    } catch (SQLException e) {
      e.printStackTrace();
      return -1;
    }
  }

  //method4: 专门用于发送查询语句
  public ResultSet execQuery(PreparedStatement pstmt){
    try {
      //1、使用Statement对象发送SQL语句
      rs = pstmt.executeQuery();
      //2、返回结果
      return rs;
    } catch (SQLException e) {
      e.printStackTrace();
      return null;
    }
  }

}

平时的用上面的代码能够解决一些简单的CRUD的应用了,但是还有很多限制,比如每次程序拿连接都要new,这样就给系统加大了负担,没有事务,没有dataSource等等,今天看见一哥们在园里面写的一篇用反射解决直接以对象参数的方式CRUD,这个我以前也写过,没写完,主要是自己想写一个通用的DButil,最后研究来研究去,发现越来越和hibernate里面的simpleJdbcTemplate接近了,所以就直接去看hibernate的源码了,加上那段时间有些事,没有时间,就将这件事闲置起来了,现在把这个东西补上,也给自己回顾一下下

BaseDao类

package com.employees.dao;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.employees.dbutil.DBConn;

public class BaseDAO<T> {

  DBConn conn = new DBConn();
  private Connection connection = null;

  @SuppressWarnings("unused")
  private Class<T> persistentClass;

  @SuppressWarnings("unchecked")
  public BaseDAO() {
    initConnection();
    //获得参数化类型
    ParameterizedType type = (ParameterizedType)getClass().getGenericSuperclass();
    persistentClass = (Class<T>)type.getActualTypeArguments()[0];
  }

  /**
   * 获得数据库连接
   */
  public void initConnection() {
    connection = conn.getConntion();
  }

  /**
   * 保存
   */
  public void save(T entity) throws Exception{
    //SQL语句,insert into table name (
    String sql = "insert into " + entity.getClass().getSimpleName().toLowerCase() + "(";

    //获得带有字符串get的所有方法的对象
    List<Method> list = this.matchPojoMethods(entity,"get");

    Iterator<Method> iter = list.iterator();

    //拼接字段顺序 insert into table name(id,name,email,
    while(iter.hasNext()) {
      Method method = iter.next();
      sql += method.getName().substring(3).toLowerCase() + ",";
    }

    //去掉最后一个,符号insert insert into table name(id,name,email) values(
    sql = sql.substring(0, sql.lastIndexOf(",")) + ") values(";

    //拼装预编译SQL语句insert insert into table name(id,name,email) values(?,?,?,
    for(int j = 0; j < list.size(); j++) {
      sql += "?,";
    }

    //去掉SQL语句最后一个,符号insert insert into table name(id,name,email) values(?,?,?);
    sql = sql.substring(0, sql.lastIndexOf(",")) + ")";

    //到此SQL语句拼接完成,打印SQL语句
    System.out.println(sql);

    //获得预编译对象的引用
    PreparedStatement statement = connection.prepareStatement(sql);

    int i = 0;
    //把指向迭代器最后一行的指针移到第一行.
    iter = list.iterator();
    while(iter.hasNext()) {
      Method method = iter.next();
      //此初判断返回值的类型,因为存入数据库时有的字段值格式需要改变,比如String,SQL语句是'"+abc+"'
      if(method.getReturnType().getSimpleName().indexOf("String") != -1) {
        statement.setString(++i, this.getString(method, entity));
      } else if(method.getReturnType().getSimpleName().indexOf("Date") != -1){
        statement.setDate(++i, this.getDate(method, entity));
      } else if(method.getReturnType().getSimpleName().indexOf("InputStream") != -1) {
        statement.setAsciiStream(++i, this.getBlob(method, entity),1440);
      } else {
        statement.setInt(++i, this.getInt(method, entity));
      }
    }
    //执行
    conn.execOther(statement);
    //关闭连接
    conn.closeConn();
  }

  /**
   * 修改
   */
  public void update(T entity) throws Exception{
    String sql = "update " + entity.getClass().getSimpleName().toLowerCase() + " set ";

    //获得该类所有get方法对象集合
    List<Method> list = this.matchPojoMethods(entity,"get");

    //临时Method对象,负责迭代时装method对象.
    Method tempMethod = null;

    //由于修改时不需要修改ID,所以按顺序加参数则应该把Id移到最后.
    Method idMethod = null;
    Iterator<Method> iter = list.iterator();
    while(iter.hasNext()) {
      tempMethod = iter.next();
      //如果方法名中带有ID字符串并且长度为2,则视为ID.
      if(tempMethod.getName().lastIndexOf("Id") != -1 && tempMethod.getName().substring(3).length() == 2) {
        //把ID字段的对象存放到一个变量中,然后在集合中删掉.
        idMethod = tempMethod;
        iter.remove();
      //如果方法名去掉set/get字符串以后与pojo + "id"想符合(大小写不敏感),则视为ID
      } else if((entity.getClass().getSimpleName() + "Id").equalsIgnoreCase(tempMethod.getName().substring(3))) {
        idMethod = tempMethod;
        iter.remove();
      }
    }

    //把迭代指针移到第一位
    iter = list.iterator();
    while(iter.hasNext()) {
      tempMethod = iter.next();
      sql += tempMethod.getName().substring(3).toLowerCase() + "= ?,";
    }

    //去掉最后一个,符号
    sql = sql.substring(0,sql.lastIndexOf(","));

    //添加条件
    sql += " where " + idMethod.getName().substring(3).toLowerCase() + " = ?";

    //SQL拼接完成,打印SQL语句
    System.out.println(sql);

    PreparedStatement statement = this.connection.prepareStatement(sql);

    int i = 0;
    iter = list.iterator();
    while(iter.hasNext()) {
      Method method = iter.next();
      //此初判断返回值的类型,因为存入数据库时有的字段值格式需要改变,比如String,SQL语句是'"+abc+"'
      if(method.getReturnType().getSimpleName().indexOf("String") != -1) {
        statement.setString(++i, this.getString(method, entity));
      } else if(method.getReturnType().getSimpleName().indexOf("Date") != -1){
        statement.setDate(++i, this.getDate(method, entity));
      } else if(method.getReturnType().getSimpleName().indexOf("InputStream") != -1) {
        statement.setAsciiStream(++i, this.getBlob(method, entity),1440);
      } else {
        statement.setInt(++i, this.getInt(method, entity));
      }
    }

    //为Id字段添加值
    if(idMethod.getReturnType().getSimpleName().indexOf("String") != -1) {
      statement.setString(++i, this.getString(idMethod, entity));
    } else {
      statement.setInt(++i, this.getInt(idMethod, entity));
    }

    //执行SQL语句
    statement.executeUpdate();

        //关闭预编译对象
        statement.close();

        //关闭连接
        connection.close();
  }

  /**
   * 删除
   */
  public void delete(T entity) throws Exception{
    String sql = "delete from " + entity.getClass().getSimpleName().toLowerCase() + " where ";

    //存放字符串为"id"的字段对象
    Method idMethod = null;

    //取得字符串为"id"的字段对象
    List<Method> list = this.matchPojoMethods(entity, "get");
    Iterator<Method> iter = list.iterator();
    while(iter.hasNext()) {
      Method tempMethod = iter.next();
      //如果方法名中带有ID字符串并且长度为2,则视为ID.
      if(tempMethod.getName().lastIndexOf("Id") != -1 && tempMethod.getName().substring(3).length() == 2) {
        //把ID字段的对象存放到一个变量中,然后在集合中删掉.
        idMethod = tempMethod;
        iter.remove();
      //如果方法名去掉set/get字符串以后与pojo + "id"想符合(大小写不敏感),则视为ID
      } else if((entity.getClass().getSimpleName() + "Id").equalsIgnoreCase(tempMethod.getName().substring(3))) {
        idMethod = tempMethod;
        iter.remove();
      }
    }

    sql += idMethod.getName().substring(3).toLowerCase() + " = ?";

    PreparedStatement statement = this.connection.prepareStatement(sql);

    //为Id字段添加值
    int i = 0;
    if(idMethod.getReturnType().getSimpleName().indexOf("String") != -1) {
      statement.setString(++i, this.getString(idMethod, entity));
    } else {
      statement.setInt(++i, this.getInt(idMethod, entity));
    }    

    //执行
    conn.execOther(statement);
    //关闭连接
    conn.closeConn();
  }

  /**
   * 通过ID查询
   */
  public T findById(Object object) throws Exception{
    String sql = "select * from " + persistentClass.getSimpleName().toLowerCase() + " where ";

    //通过子类的构造函数,获得参数化类型的具体类型.比如BaseDAO<T>也就是获得T的具体类型
    T entity = persistentClass.newInstance();

    //存放Pojo(或被操作表)主键的方法对象
    Method idMethod = null;

    List<Method> list = this.matchPojoMethods(entity, "set");
    Iterator<Method> iter = list.iterator();

    //过滤取得Method对象
    while(iter.hasNext()) {
      Method tempMethod = iter.next();
      if(tempMethod.getName().indexOf("Id") != -1 && tempMethod.getName().substring(3).length() == 2) {
        idMethod = tempMethod;
      } else if((entity.getClass().getSimpleName() + "Id").equalsIgnoreCase(tempMethod.getName().substring(3))){
        idMethod = tempMethod;
      }
    }
    //第一个字母转为小写
    sql += idMethod.getName().substring(3,4).toLowerCase()+idMethod.getName().substring(4) + " = ?";

    //封装语句完毕,打印sql语句
    System.out.println(sql);

    //获得连接
    PreparedStatement statement = this.connection.prepareStatement(sql);

    //判断id的类型
    if(object instanceof Integer) {
      statement.setInt(1, (Integer)object);
    } else if(object instanceof String){
      statement.setString(1, (String)object);
    }

    //执行sql,取得查询结果集.
    ResultSet rs = conn.execQuery(statement);

    //记数器,记录循环到第几个字段
    int i = 0;

    //把指针指向迭代器第一行
    iter = list.iterator();

    //封装
    while(rs.next()) {
      while(iter.hasNext()) {
        Method method = iter.next();
        if(method.getParameterTypes()[0].getSimpleName().indexOf("String") != -1) {
          //由于list集合中,method对象取出的方法顺序与数据库字段顺序不一致(比如:list的第一个方法是setDate,而数据库按顺序取的是"123"值)
          //所以数据库字段采用名字对应的方式取.
          this.setString(method, entity, rs.getString(method.getName().substring(3).toLowerCase()));
        } else if(method.getParameterTypes()[0].getSimpleName().indexOf("Date") != -1){
          this.setDate(method, entity, rs.getDate(method.getName().substring(3).toLowerCase()));
        } else if(method.getParameterTypes()[0].getSimpleName().indexOf("InputStream") != -1) {
          this.setBlob(method, entity, rs.getBlob(method.getName().substring(3).toLowerCase()).getBinaryStream());
        } else {
          this.setInt(method, entity, rs.getInt(method.getName().substring(3).toLowerCase()));
        }
      }
    }

    //关闭结果集
    rs.close();

    //关闭预编译对象
    statement.close();

    return entity;
  }

  /**
   * 过滤当前Pojo类所有带传入字符串的Method对象,返回List集合.
   */
  private List<Method> matchPojoMethods(T entity,String methodName) {
    //获得当前Pojo所有方法对象
    Method[] methods = entity.getClass().getDeclaredMethods();

    //List容器存放所有带get字符串的Method对象
    List<Method> list = new ArrayList<Method>();

    //过滤当前Pojo类所有带get字符串的Method对象,存入List容器
    for(int index = 0; index < methods.length; index++) {
      if(methods[index].getName().indexOf(methodName) != -1) {
        list.add(methods[index]);
      }
    }
    return list;
  }

  /**
   * 方法返回类型为int或Integer类型时,返回的SQL语句值.对应get
   */
  public Integer getInt(Method method, T entity) throws Exception{
    return (Integer)method.invoke(entity, new Object[]{});
  }

  /**
   * 方法返回类型为String时,返回的SQL语句拼装值.比如'abc',对应get
   */
  public String getString(Method method, T entity) throws Exception{
    return (String)method.invoke(entity, new Object[]{});
  }

  /**
   * 方法返回类型为Blob时,返回的SQL语句拼装值.对应get
   */
  public InputStream getBlob(Method method, T entity) throws Exception{
    return (InputStream)method.invoke(entity, new Object[]{});
  }

  /**
   * 方法返回类型为Date时,返回的SQL语句拼装值,对应get
   */
  public Date getDate(Method method, T entity) throws Exception{
    return (Date)method.invoke(entity, new Object[]{});
  }

  /**
   * 参数类型为Integer或int时,为entity字段设置参数,对应set
   */
  public Integer setInt(Method method, T entity, Integer arg) throws Exception{
    return (Integer)method.invoke(entity, new Object[]{arg});
  }

  /**
   * 参数类型为String时,为entity字段设置参数,对应set
   */
  public String setString(Method method, T entity, String arg) throws Exception{
    return (String)method.invoke(entity, new Object[]{arg});
  }

  /**
   * 参数类型为InputStream时,为entity字段设置参数,对应set
   */
  public InputStream setBlob(Method method, T entity, InputStream arg) throws Exception{
    return (InputStream)method.invoke(entity, new Object[]{arg});
  }

  /**
   * 参数类型为Date时,为entity字段设置参数,对应set
   */
  public Date setDate(Method method, T entity, Date arg) throws Exception{
    return (Date)method.invoke(entity, new Object[]{arg});
  }
}

EmployeesDao继承BaseDAO,可以直接使用父类的方法,增加了代码的复用

package com.employees.dao;

import java.util.ArrayList;
import java.util.List;
import com.employees.po.Employees;

public class EmployeesDao extends BaseDAO<Employees> {

  // 添加员工信息的操作
  public boolean addEmployees(final Employees employees) throws Exception {
    save(employees);
    return true;
  }

  // 将员工信息添加到表格中
  public List<Employees> addEmployees(int id) throws Exception {
    List<Employees> lstEmployees = new ArrayList<Employees>();
    Employees employees = findById(id);
    // 将当前封转好的数据装入对象中
    lstEmployees.add(employees);
    return lstEmployees;
  }

  public void deleteEmp(final Employees entity) throws Exception {
    this.delete(entity);
  }

  public void updateEmp(final Employees entity) throws Exception {
    this.update(entity);
  }

}

po层的代码就不贴了,现在用junit4做一下测试

package com.employees.dao;

import org.junit.Test;

import com.employees.po.Employees;

public class EmployeesDaoTest {

  @Test
  public void testAdd() throws Exception {
    Employees emp = new Employees();
    emp.setPname("tly");
    emp.setPsex("男");
    emp.setPbeliefs("xxxxx");
    emp.setPaddr("天河");
    emp.setPhobby("打篮球");
    emp.setPsubject("计算机");
    emp.setPtel("123456");
    EmployeesDao dao = new EmployeesDao();
    dao.addEmployees(emp);
  }
  @Test
  public void testUpdate() throws Exception {
    EmployeesDao dao = new EmployeesDao();
    Employees emp = dao.findById(14);
    emp.setPtel("999999");
    dao.updateEmp(emp);
  }
  @Test
  public void testdelete() throws Exception {
    EmployeesDao dao = new EmployeesDao();
    Employees emp = dao.findById(15);
    dao.deleteEmp(emp);
  }

}

经过测试,这三个方法都能正常运行,时间仓促,有些代码是参考其他哥们的,有些地方可能考虑的不是很全面或者有些代码会有冗余,BaseDAO中做通用crud操作没有写全,要是哪位小伙伴有兴趣,可以接下去写写,比如查询,批量化操作等等,如果测试通过的话,记得给我发一份啊,呵呵

以上这篇简单通用JDBC辅助类封装(实例)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 基于JDBC封装的BaseDao(实例代码)

    最近闲暇时萌发写一写dao的封装的例子,就将以前写的整理一下. public class BaseDao<T> { Connection conn; PreparedStatement st; ResultSet rs; JdbcUtil jdbcUtil = new JdbcUtil(); int result = 0; private Class<T> persistentClass; @SuppressWarnings("unchecked") publi

  • java的jdbc简单封装方法

    学习了jdbc一段时间后感觉自己写一个简单的封装来试试,于是参考的一些资料就写了一下不是多好,毕竟刚学也不太久 首先写配置文件:直接在src下建立一个db.properties文件然后写上内容 <span style="font-size:18px;">MysqlDriver=com.mysql.jdbc.Driver MysqlURL=jdbc\:mysql\://localhost\:3306/one User=root Pwd=123456 </span>

  • 关于JDBC的简单封装(实例讲解)

    如下所示: import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; /** * 数据库连接工具 * @author 2017 * */ public class DbTool { /** * 数据库的类 */ private static final String ORACLE_DRIVER = "oracle.

  • 详解JDBC数据库链接及相关方法的封装

    详解JDBC数据库链接及相关方法的封装 使用的是MySQL数据库,首先导入驱动类,然后根据数据库URL和用户名密码获得数据的链接.由于使用的是MySQL数据库,它的URL一般为,jdbc:mysql://主机地址:端口号/库名. 下面是封装的具体类,用到了泛型和反射,不过还存在些问题,就是对使用的泛型对象有些限制,只能用于泛型类对象属性名与数据库表中列名相同的对象,而且初始化对象的方法必须为set+属性名的方法.本来想通过返回值类型,参数列表来确定该属性初始化方法的,然而可能是目前学到的还是太少

  • 简单通用JDBC辅助类封装(实例)

    哎,最近很好久没写点东西了,由于工作的原因,接触公司自己研发的底层orm框架,偶然发现该框架在调用jdbc操作的时候参考的是hibernate 里面的SimpleJdbcTemplate,这里我想到了在大学的时候自己用过的一个简单的jdbc封装,现在我将代码贴出来,和大家一起分享: Config类:读取同一包下的数据库连接配置文件,这样是为了更好的通用性考虑 package com.tly.dbutil; import java.io.IOException; import java.util.

  • jdbc结合dpcp连接池的封装实例

    demo需求: 实现jdbc结合dpcp连接池的封装(以oracle数据库为例)并实现简单地查找demo主要技术: (1)Properties类加载.properties的方式 (2)dpcp连接池建立数据库连接的方式 (3)查询数据的方式 (4)静态代码块的使用,分离驱动的加载和连接信息的载入,整个服务器生命周期只执行一次 demo所用jar包: classes12.jar commons-dbcp-1.4.jar commons-pool-1.5.4.jar demo主要代码展示: Util

  • 微信小程序之网络请求简单封装实例详解

    微信小程序之网络请求简单封装实例详解 在微信小程序中实现网络请求相对于Android来说感觉简单很多,我们只需要使用其提供的API就可以解决网络请求问题. 普通HTTPS请求(wx.request) 上传文件(wx.uploadFile) 下载文件(wx.downloadFile) WebSocket通信(wx.connectSocket) 为了数据安全,微信小程序网络请求只支持https,当然各个参数的含义就不在细说,不熟悉的话可以:可以去阅读官方文档的网络请求api,当我们使用request

  • 打造通用的匀速运动框架(实例讲解)

    本文,是接着上 基于匀速运动的实例讲解(侧边栏,淡入淡出) 继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让他变得更加的通用和强大: 1,支持多个物体的运动 2,同时运动 3,顺序运动 这三种运动方式也是jquery中animate函数支持的 一.animate函数中怎么区分变化不同的样式? 上文中,侧边栏效果 用的animate函数 改变的是left值 function animate(obj, target, s

  • Javascript简单实现面向对象编程继承实例代码

    本文讲述了Javascript简单实现面向对象编程继承实例代码.分享给大家供大家参考,具体如下: 面向对象的语言必须具备四个基本特征: 1.封装能力(即允许将基本数据类型的变量或函数放到一个类里,形成类的成员或方法) 2.聚合能力(即允许类里面再包含类,这样可以应付足够复杂的设计) 3.支持继承(父类可以派生出子类,子类拥有父母的属性或方法) 4.支持多态(允许同样的方法名,根据方法签名[即函数的参数]不同,有各自独立的处理方法) 这四个基本属性,javascript都可以支持,所以javasc

  • jQuery Ajax 全局调用封装实例代码详解

    有一种情况:全站都要用异步方式来调用 数据,提交数据,那么你每次操作 都会要$.ajax({.....}) 写重复的方法 和代码,冗余太大, 也浪费时间,虽说你有代码自动提示补全,但真的不优雅,身为前端极客,是不能允许的! [嘿嘿!虽说我现在基本不用jquery了 ,不过异步概念 是永远要用的,就帮助下新人] jQuery Ajax通用js封装 第一步:引入jQuery库 <script type="text/javascript" src="/js/jquery.mi

  • SpringBoot+MyBatis简单数据访问应用的实例代码

    因为实习用的是MyBatis框架,所以写一篇关于SpringBoot整合MyBatis框架的总结. 一,Pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:

  • 自定义一个简单的JDBC连接池实现方法

    一.什么是JDBC连接池? 在传统的JDBC连接中,每次获得一个Connection连接都需要加载通过一些繁杂的代码去获取,例如以下代码: public static Connection getConn(){ Connection conn = null; String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "root"

  • Node之简单的前后端交互(实例讲解)

    node是前端必学的一门技能,我们都知道node是用的js做后端,在学习node之前我们有必要明白node是如何实现前后端交互的. 这里写了一个简单的通过原生ajax与node实现的一个交互,刚刚学node的朋友可以看一看.一方面理解服务端与客户端是如何交互的,一方面更熟悉node开发. 先贴代码:(有兴趣的可以copy到本地自己run一下) 主页面的html index.html: <!doctype> <html> <head> <meta charset=&

随机推荐