发布网友 发布时间:2022-04-08 02:39
共2个回答
懂视网 时间:2022-04-08 07:00
class Account { private int id; private String name; private double money; 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 double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }在未使用框架时编写AccountDAO
public void insertAccount(Account account) { Connection conn = null; PreparedStatement stmt = null; try { conn = JDBCUtils.getConnection(); String sql = "insert into account values(null,?,?)"; stmt = conn.prepareStatement(sql); // 设置参数 stmt.setString(1, account.getName()); stmt.setDouble(2, account.getMoney()); stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.release(stmt, conn); } }
通过不同对象DAO模式下的SQL操作比较对方法进行提取编写通用框架
public static void update(String sql, Object... args) { Connection conn = null; PreparedStatement stmt = null; try { conn = JDBCUtils.getConnection(); stmt = conn.prepareStatement(sql); // 设置参数 --- 根据?设置参数 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, args[i - 1]); } stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.release(stmt, conn); } }
在使用框架之后写的AccountDAO
public void insertAccount(Account account) { String sql = "insert into account values(null,?,?)"; Object[] params={account.getNmae(),account.getMoney()} JDBCFramework.update(sql,params) }
通用框架的编写使用在后来可以不断重复使用,大大的简化了开发。但是上面的通用框架方法只适合CUD增删改,对于查询R来说是不能使用的,所以需要单独进行抽取编写框架方法
在未使用框架时
public Account findById(int id) { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; Account account = null; try { conn = JDBCUtils.getConnection(); String sql = "select * from account where id = ?"; stmt = conn.prepareStatement(sql); //设置参数 stmt.setInt(1, id); rs = stmt.executeQuery(); if (rs.next()) { account = new Account(); account.setId(rs.getInt("id")); account.setName(rs.getString("name")); account.setMoney(rs.getDouble("money")); } } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.release(rs, stmt, conn); } return account; }
编写框架
public static <T> T query(String sql, MyResultSetHandler<T> handler, Object... args) { T obj = null; Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtils.getConnection(); stmt = conn.prepareStatement(sql); // 设置参数 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, args[i - 1]); } rs = stmt.executeQuery(); obj = handler.handle(rs); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.release(rs, stmt, conn); } return obj; }
要另外定义接口将rs结果集中的数据封装成一个对象
public interface MyResultSetHandler<T> { // 将rs中数据封装对象 public T handle(ResultSet rs); }
使用框架之后
public Account findById(int id) { // 使用自定义框架 String sql = "select * from account where id = ?"; MyResultSetHandler handler = new MyResultSetHandler() {//内部类实现框架的接口封装数据。但是每次都要实现 MyResultSetHandler接口,手动完成数据的封装的动作,所以此动作依然可以继续向上抽取。 @Override public Object handle(ResultSet rs) { try { if (rs.next()) { Account account = new Account(); account.setId(rs.getInt("id")); account.setName(rs.getString("name")); account.setMoney(rs.getDouble("money")); return account; } } catch (SQLException e) { e.printStackTrace(); } return null; } }; return (Account) JDBCFramework.query(sql, handler, id); }
内部类实现框架的接口封装数据。但是每次都要实现 MyResultSetHandler接口,手动完成数据的封装的动作,所以此动作依然可以继续向上抽取。
将封装结果集数据的动作进行向上提取,利用泛型和反射在框架中编写通用的Handler程序,☆难点。
public class MyBeanHandler<T> implements MyResultSetHandler<T> { private Class<T> domainClass; public MyBeanHandler(Class<T> domainClass) {//泛型是存在编译时期的,要创建T泛型的实例,需要将具体类的字节码文件对象传入利用反射技术去创建对象。 this.domainClass = domainClass; } @Override public T handle(ResultSet rs) {//用泛型去指代返回的数据类型。 try { ResultSetMetaData resultSetMetaData = rs.getMetaData();// 结果集元数据 int count = resultSetMetaData.getColumnCount(); BeanInfo beanInfo = Introspector.getBeanInfo(domainClass);//使用内省技术获得字节码文件对象的属性描述器。 PropertyDescriptor[] descriptors = beanInfo .getPropertyDescriptors(); if (rs.next()) { T t = domainClass.newInstance();//此处获得T的实例对象 for (int i = 1; i <= count; i++) { String columnName = resultSetMetaData.getColumnName(i); // 获得列名 --- 需要去查找匹配属性 for (PropertyDescriptor propertyDescriptor : descriptors) { if (columnName.equals(propertyDescriptor.getName())) { // 列名 存在 同名属性 ---- 列值 存到属性里 Method writeMethod = propertyDescriptor .getWriteMethod(); // setName setMoney writeMethod.invoke(t, rs.getObject(columnName)); } } } return t; } } catch (Exception e) { e.printStackTrace(); } return null; } }
最后简化出的DAO下的查询方法
public Account findById(int id) { String sql = "select * from account where id = ?"; return JDBCFramework.query(sql,new MyBeanHandler<Account>(Account.class),id) }
JDBC框架的编写
标签:
热心网友 时间:2022-04-08 04:08
方法/步骤
打开tomcat目录,进入conf配置目录,有个context.xml文件,一般建议把数据源配置放在这个文件里进行配置,放在server.xml也是可以的,但不建议这么做,server.xml文件一般是tomcat服务相关的配置
添加Resource节点,name就是JNDI资源访问的名称,注意和应用程序中保持一致,然后配置用户名和密码信息,如果是mysql,配置driverClass的就是mysql的驱动程序的类路径,如果是oracle,就配置对应的oracle驱动类路径。
maxPoolSize,minPoolSize,initialPoolSize这些是连接池相关的配置,可以根据应用的需要配置,一次配置不合适,可以多次调整
<Resource
name="jdbc/chargeService"
auth="Container"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
factory="org.apache.naming.factory.BeanFactory"
user="root"
password="xxx"
driverClass="com.mysql.jdbc.Driver"
jdbcUrl="jdbc:mysql://xxx:3306/bus"
maxPoolSize="5"
minPoolSize="2"
initialPoolSize="3"
acquireIncrement="1"
maxIdleTime="300"
acquireRetryAttempts="30"
acquireRetryDelay="1000"
unreturnedConnectionTimeout="3000"
debugUnreturnedConnectionStackTraces="true"
checkoutTimeout="5000"
idleConnectionTestPeriod="60"
preferredTestQuery="SELECT CURRENT_USER"
/>
这里我们使用的数据源连接池是c3p0,所以得引入c3p0的c3p0-0.9.1.2.jar包,连接池的jar可以按照自己的需要选择,相关的实现方式有(dbcp,c3p0,proxool,druid)
这里我们使用的mysql数据库,所以引入的是mysql-connector-java-5.1.30.jar驱动包,如果是oracle或其它数据库,引入对于数据库的驱动包即可,然后在driverClass配置对于的驱动程序的类路径
tomcat数据源配置上之后,就可以在我们的应用程序中来获取数据源了。通过spring的
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/chargeService</value>
</property>
</bean>
方法来获取
高版本的spring为我们提供了
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/chargeService"/>
方式配置,这种方式更为简洁方便,使用方式是一样的