初学数据库(2)

163 阅读3分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。

一、使用c3p0数据库连接池

通过上面的案例,可以发现,每次操作都需要创建数据库连接,这样在实际开发中是不允许的。为了避免频繁的创建数据库连接,数据库连接池技术应运而生。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。

image.png C3P0是目前最流行的开源数据库连接池之一,它实现了DataSource数据源接口,支持JDBC2和JDBC3的标准规范,易于扩展并且性能优越,著名的开源框架Hibernate和 Spring都支持该数据源。

 

1、下载c3p0数据库连接池:

c3p0-0.9.5.5.jar 以及依赖包mchange-commons-java-0.2.19.jar

Mvaen库

mvnrepository.com/artifact/co…

mvnrepository.com/artifact/co…

 

然后加入到项目中。

2、添加配置文件:c3p0-config.xml

在src根目录下面,创建一个c3p0-config.xml文件,然后添加配置信息如下:

<?xml version="1.0" encoding="UTF-8"?>\
<c3p0-config>\
   <default-config>\
      <property name="driverClass">com.mysql.cj.jdbc.Driver</property>\
      <property name="jdbcUrl">\
         jdbc:mysql://localhost:3306/train01?useSSL=FALSE&allowPublicKeyRetrieval=TRUE&serverTimezone=UTC\
       </property>\
      <property name="user">root</property>\
      <property name="password">admin</property>\
      <property name="checkoutTimeout">30000</property>\
      <!--初始化连接数-->\
      <property name="initialPoolSize">5</property>\
      <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->\
      <property name="maxIdleTime">20</property>\
      <!--连接池中保留的最大连接数。Default: 15 -->\
      <property name="maxPoolSize">10</property>\
      <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->\
      <property name="minPoolSize">1</property>\
      <!--Statement 最大数,设置为0就是关闭缓存-->\
      <property name="maxStatements">0</property>\
   </default-config>\
</c3p0-config>

image.png

3、创建c3p0utils工具类

创建一个c3p0utils工具类:

image.png

package com.hwadee.train.servlet.utils;\
\
import com.mchange.v2.c3p0.ComboPooledDataSource;\
import javax.sql.DataSource;\
\
public class C3p0Utils {\
\
    private static DataSource ds;\
    static {\
        ds = new ComboPooledDataSource();\
    }\
    public static DataSource getDataSource() {\
        return ds;\
    }\
}

4、测试:

//    使用DBUtils和c3p0工具包\
    public User findByNameAndPwd2(String username,String password){\
        try {\
            String sql = "SELECT id, username,password,sex,birthday,email,hobby,note " +\
                    "FROM user " +\
                    "where username=? and password=?";  //这里使用?占位符\
            QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
            return (User) runner.query(sql,new BeanHandler(User.class),username,password);\
        } catch (SQLException throwables) {\
            throwables.printStackTrace();\
        }\
        return null;\
    }

5、数据库增删改查

创建一个通用基础工具类:

package com.hwadee.train.servlet.dao;
import com.hwadee.train.servlet.utils.C3p0Utils;\
import org.apache.commons.dbutils.QueryRunner;\
import org.apache.commons.dbutils.handlers.BeanHandler;\
import org.apache.commons.dbutils.handlers.BeanListHandler;\
\
import java.lang.reflect.ParameterizedType;\
import java.sql.SQLException;\
import java.util.List;\
\
\
public class BaseDAO<T> {\
    private Class clasz=null;\
\
    public BaseDAO(){\
        //获得泛型参数类型的class\
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();\
        clasz = (Class) type.getActualTypeArguments()[0];\
    }\
\
    public T find(String sql, Object... parameters) {\
        try {\
            QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
            return (T) runner.query(sql,new BeanHandler(clasz),parameters);\
        } catch (SQLException throwables) {\
            throwables.printStackTrace();\
        }\
        return null;\
    }\
\
    public List<T> finds(String sql, Object... parameters) {\
        try {\
            QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
            return (List<T>) runner.query(sql,new BeanListHandler(clasz),parameters);\
        } catch (SQLException throwables) {\
            throwables.printStackTrace();\
        }\
        return  null;\
    }\
    public void update(String sql, Object... parameters) {\
        try {\
            QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
            runner.update(sql,parameters);\
        } catch (SQLException throwables) {\
            throwables.printStackTrace();\
        }\
    }\
\
    public void create(String sql, Object... parameters) {\
        try {\
            QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
            runner.update(sql,parameters);\
        } catch (SQLException throwables) {\
            throwables.printStackTrace();\
        }\
\
    }\
\
    public void delete(String sql, Object... parameters){\
        try {\
            QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
            runner.update(sql,parameters);\
        } catch (SQLException throwables) {\
            throwables.printStackTrace();\
        }\
    }\
}

创建一个UserBaseDao继承BaseDAO

package com.hwadee.train.servlet.dao;\
\
import com.hwadee.train.servlet.entity.User;\
\
public class UserBaseDao extends BaseDAO<User>{\
}

创建一个UserService

package com.hwadee.train.servlet.srvice;\
\
import com.hwadee.train.servlet.dao.AdminBaseDao;\
import com.hwadee.train.servlet.dao.BaseDAO;\
import com.hwadee.train.servlet.entity.Admin;\
\
public class UserService {\
    private  BaseDAO<User> baseDAO=new UserBaseDao();\
\
    public UserfindByName(String username){\
        String sql = "SELECT id, username,password,sex,birthday,email,hobby,note " +\
                "FROM user" +\
                "where username=?";  //这里使用?占位符\
        return baseDAO.find(sql,username);\
    }\
}

测试使用:

image.png

二、BeanUtils 工具包

在注册页面,因为字段非常多,所以使用getParameter()一个一个地获得值不方便,这里推荐一个封装用户提交数据的工具包。

1、下载

Maven里面查询BeanUtils,下载包及依赖包

mvnrepository.com/artifact/co…

commons-beanutils-1.9.4.jar

commons-collections-3.2.2.jar

commons-logging-1.2.jar

2、引用

把上面的3个包引用到项目中

image.png 然后重新添加lib包。

2、使用测试:

image.png

BeanUtils.populate(user,req.getParameterMap());

 

在注册页面,因为实体类有java.util.Date字段,但是页面输入的是String,这样使用BeanUtils自动装配时就会报错:

org.apache.commons.beanutils.ConversionException: DateConverter does not support default String to 'Date' conversion.

那么我们就需要处理这个问题,先阶段我们使用一个简单的方式来处理。

 

处理步骤:

1)在User实体类里面添加一个转换日期的方法:

public void converterDate(String birthday) {\
    Date date = null;\
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");\
    if (birthday != null && birthday.trim().length() > 0) {\
        try {\
            date = sdf.parse(birthday);\
        } catch (ParseException e) {\
            System.out.println("日期输入错误!!!");\
        }\
    }\
    setBirthday(date);\
}

2)修改注册页面生日的参数名称,使得和实体类属性名不一致,这样BeaUtils自动封装的时候,就找不到匹配的名称,就不会报错。

比如:

3)手动转换:

String date_birthday = req.getParameter("date_birthday");\ user.converterDate(date_birthday);