【声明】

欢迎转载,但请保留文章原始出处→_→

生命壹号:http://www.cnblogs.com/smyhvae/

文章来源:http://www.cnblogs.com/smyhvae/p/4085684.html

【正文】

这一周状态不太好,连续打了几天的点滴,所以博客中断了一个星期,现在继续。

我们在之前的几篇文章中学习了JDBC对数据库的增删改查。其实在实际开发中,一般都是使用第三方工具类,但是只有将之前的基础学习好了,在使用开源工具的时才能得心应手。如果对JDBC基础不太清楚,或者对本文看不太懂,建议先回顾一下本人之前的几篇和“MySQL数据库学习笔记”相关的文章。但是不管怎样,今后如果用到了数据库的增删改查,肯定是这篇文章中的代码用的最多。

一、DbUtils简介:

DBUtils是apache下的一个小巧的JDBC轻量级封装的工具包,其最核心的特性是结果集的封装,可以直接将查询出来的结果集封装成JavaBean,这就为我们做了最枯燥乏味、最容易出错的一大部分工作。

下载地址:http://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi

下载上图中的红框部分,然后解压。解压之后的文件如下 :

上图中红框部分的文件就是我们所需要的内容。

二、核心方法:

DbUtils中的核心的类是QueryRunner类。来看一下里面的核心方法:

更新操作:

runner.update("delete from user where userName=?","用户名");

int rowEffects = runner.update("insert into user(userName,password,comment)values(?,?,?)", "用户名","密码","备注");

查询操作:

//返回bean
User user = runner.query("select * from user where userId=?",1,new BeanHandler<User>(User.class)); //返回beanlist
System.out.println("返回BeanList结果......");
List<User> beanListResult =runner.query("select * from user",new BeanListHandler(User.class)); //返回一个值
Object increaseId=runner.query("select last_insert_id()", new ScalarHandler()); 

 

三、代码实现:

下面来看一下DbUtils是怎么用的。先来看一下整个工程的文件结构:

  • DBUtils:初步封装的JDBC工具类;
  • db-config.properties:属性文件,方便修改配置信息;
  • Person类就是领域模型,表示是对它(数据库表)进行增删改查。
  • PersonDao接口:专门对Person类进行操作(例如增删改查)的接口。注:这里不直接写操作类,是因为接口利于维护,可以在这里写上公共的代码。一个领域模型对应一个Dao接口。
  • PeronDaoImpl类:实现上面的PeronDao接口(也就是在这里用到了DbUtils工具,避免了自己写很多代码)
  • Test类:测试代码的可用性。

步骤如下:

首先创建数据库表:person。字段:id,name,age,description。建表的命令如下:

CREATE TABLE person(
id int primary key auto_increment,
name varchar(20),
age int(2),
description varchar(100)
); 

然后往表中填入一些简单地数据,供稍后查询。最终效果如下:

接下来是具体的代码实现:

打开eclipse,新建Java工程DBTest,然后在根目录下新建一个文件夹libs,将mysql-connector-java-5.1.33-bin.jar和刚刚下载好的commons-dbutils-1.6.jar添加到工程的Build path中。(如果不想去官网下载,可以在本文末尾的工程文件中找到)

(1)先新建一个DBUtils工具类:(package com.util.db)

 package com.util.db;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle; /**
* 数据库操作工具类
*
* @author lamp
*
*/
public class DBUtils { // 数据库连接地址
public static String URL;
// 用户名
public static String USERNAME;
// 密码
public static String PASSWORD;
// mysql的驱动类
public static String DRIVER; private static ResourceBundle rb = ResourceBundle.getBundle("com.util.db.db-config");

private DBUtils() {
} // 使用静态块加载驱动程序
static {
URL = rb.getString("jdbc.url");
USERNAME = rb.getString("jdbc.username");
PASSWORD = rb.getString("jdbc.password");
DRIVER = rb.getString("jdbc.driver");
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} // 定义一个获取数据库连接的方法
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
System.out.println("获取连接失败");
}
return conn;
} // 关闭数据库连接
public static void close(ResultSet rs, Statement stat, Connection conn) {
try {
if (rs != null)
rs.close();
if (stat != null)
stat.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
} }

注意:27行中,注意获取属性文件的包名是否正确。稍后会定义这个属性文件。

29行:既然是工具类,一般不要实例化,此时可以采用单例设计模式,或者将构造方法私有化。

27行:很明显可以看到,我们是将连接数据库的URL、用户名,密码等信息编写在一个属性文件(jdbc.properties)中,稍后再来定义这个属性文件。

32行:为避免重复代码,使用静态代码块:只会在类加载的时候执行一次。

45行:定义一个获取数据库连接的方法

57行:关闭数据库连接

(2)接下来新建一个属性文件,new-->file,命名为:db-config.properties,代码如下:

jdbc.url=jdbc:mysql://localhost:3306/jdbcdb
jdbc.username=root
jdbc.password=smyh
jdbc.driver=com.mysql.jdbc.Driver

以后如果需要修改配置信息,只需要在这里改就行了。注意在上面的DBUtils类中是怎么来调用这个配置信息的。

(3)新建文件,定义好Person类:(package com.vae.domain)

 package com.vae.domain;

 public class Person {
private int id;
private String name;
private int age;
private String description; 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 int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} public Person(int id, String name, int age, String description) {
super();
this.id = id;
this.name = name;
this.age = age;
this.description = description;
} public Person(String name, int age, String description) {
super();
this.name = name;
this.age = age;
this.description = description;
} public Person() {
super();
// TODO Auto-generated constructor stub
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", description=" + description + "]";
} }

这个Person类就是领域模型,表示是对它进行增删改查。

紧接着定义PersonDao接口:专门对Person类进行操作(例如增删改查)的接口(package com.vae.dao)

注意:是定义接口,不是定义类。代码如下:

 package com.vae.dao;

 import java.sql.SQLException;
import java.util.List; import com.vae.domain.Person; public interface PersonDao {
// 添加方法
public void add(Person p) throws SQLException; // 更新方法
public void update(Person p) throws SQLException; // 删除方法
public void delete(int id) throws SQLException; // 查找方法
public Person findById(int id) throws SQLException; // 查找所有
public List<Person> findAll() throws SQLException; // 查询有几条记录
public long personCount() throws SQLException; }

(4)然后,定义PeronDaoImpl实现类 ,实现上面的PeronDao接口(package com.vae.dao)

 package com.vae.dao;

 import java.sql.SQLException;
import java.util.List; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler; import com.util.db.DBUtils;
import com.vae.domain.Person; public class PersonDaoImpl implements PersonDao {
private QueryRunner runner = null;//查询运行器
public PersonDaoImpl(){
runner = new QueryRunner();
} //方法:向数据库中添加一条记录
@Override
public void add(Person p) throws SQLException {
String sql = "insert into person(name,age,description)values(?,?,?)";
runner.update(DBUtils.getConnection(), sql, p.getName(), p.getAge(),p.getDescription());
} //方法:根据id向数据库中修改某条记录
@Override
public void update(Person p) throws SQLException {
String sql = "update person set name=?,age=?,description=? where id=?";
runner.update(DBUtils.getConnection(), sql, p.getName(),p.getAge(),p.getDescription(),p.getId());
} //方法:根据id删除数据库中的某条记录
@Override
public void delete(int id) throws SQLException {
String sql = "delete from person where id=?";
runner.update(DBUtils.getConnection(), sql, id);
} //方法:使用BeanHandler查询一个对象
@Override
public Person findById(int id) throws SQLException {
String sql = "select name,age,description from person where id=?";
Person p = runner.query(DBUtils.getConnection(), sql, new BeanHandler<Person>(Person.class),id);
return p;
} //方法:使用BeanListHandler查询所有对象
@Override
public List<Person> findAll() throws SQLException {
String sql = "select name,age,description from person";
List<Person> persons = runner.query(DBUtils.getConnection(), sql, new BeanListHandler<Person>(Person.class));
return persons;
} //方法:使用ScalarHandler查询一共有几条记录
@Override
public long personCount()throws SQLException{
String sql = "select count(id) from person";
return runner.query(DBUtils.getConnection(),sql, new ScalarHandler<Long>());
} } 

核心代码:15行、17行、24行、31行、38行、46行、54行、62行。

(5)新建一个测试类Test.java(package com.vae.test)

 package com.vae.test;

 import java.sql.SQLException;
import java.util.List; import com.vae.dao.PersonDao;
import com.vae.dao.PersonDaoImpl;
import com.vae.domain.Person; public class Test { public static void main(String[] args) throws SQLException {
PersonDao dao = new PersonDaoImpl(); //dao.add(new Person("生命叁号",22,"我是通过Java命令而增加的记录")); //dao.update(new Person(1,"生命壹号",23,"我是通过Java命令而修改的记录")); //dao.delete(4); //Person p = dao.findById(1);
//System.out.println(p); //List<Person> persons = dao.findAll();
//System.out.println(persons); long count = dao.personCount();
System.out.println(count);
} }

经测试,上述15至28行的代码都能运行。

例如,当执行第21至22代码时,后台输出如下:

当执行第24至25代码时,后台输出如下:

当执行第27至28代码时,后台输出如下:

【工程文件】

链接:http://pan.baidu.com/s/1qWqKreO

密码:9wed

MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)的更多相关文章

  1. MYSQL进阶学习笔记十二:MySQL 表分区!(视频序号:进阶_29,30)

    知识点十三:MySQL 表的分区(29) 一.什么要采用分区: 分区的定义: 当数据量过大的时候(通常是指百万级或千万级数据的时候),这时候需要将一张表划分几张表存储.一些查询可以得到极大的优化,这主 ...

  2. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  3. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  4. python学习笔记(十 二)、操作数据库

    每一种语言都少不了多数据库进行各种操作. python支持多种数据库.有关python支持的数据库清单,请参阅:https://wiki.python.org/moin/DatabaseInterfa ...

  5. MyBatis学习(二)、SQL语句映射文件(2)增删改查、参数、缓存

    二.SQL语句映射文件(2)增删改查.参数.缓存 2.2 select 一个select 元素非常简单.例如: <!-- 查询学生,根据id --> <select id=" ...

  6. 学习MyBatis必知必会(5)~了解myBatis的作用域和生命周期并抽取工具类MyBatisUtil、mybatis执行增删改查操作

    一.了解myBatis的作用域和生命周期[错误的使用会导致非常严重的并发问题] (1)SqlSessionFactoryBuilder [ 作用:仅仅是用来创建SqlSessionFactory,作用 ...

  7. MySQL学习笔记十二:数据备份与恢复

    数据备份 1.物理备份与逻辑备份 物理备份 物理备份就是将数据库的数据文件,配置文件,日志文件等复制一份到其他路径上,这种备份速度一般较快,因为只有I/O操作.进行物理备份时,一般都需要关闭mysql ...

  8. 数据库学习笔记(二)MySQL数据库进阶

    MySQL 进阶 关于连表 左右连表: join 上下连表: union #自动去重 (当两张表里的数据,有重复的才会自动去重) union all #不去重 #上下连表示例: select sid, ...

  9. Python学习笔记(十二)—Python3中pip包管理工具的安装【转】

    本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...

  10. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

随机推荐

  1. AIX上通过IPSEC进行IP包过滤

    AIX上的IPSEC 在AIX可以通过以下步骤打开IP Security smitty ipsec4 --> Start/Stop IP Security --> Start IP Sec ...

  2. C#编码标准

    一.命名约定 1.PascalCasting PascalCasing 每一个单词第一个字母大写,其余字母均小写.例如:FileAccess,ArraySegment等. 除了参数.变量.常量外,所有 ...

  3. Java面试宝典2015版(绝对值得收藏超长版)

    31.String s = "Hello";s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有? 没有.因为Str ...

  4. python实现删除文件与目录的方法

    os.remove(path) 删除文件 path. 如果path是一个目录, 抛出 OSError错误.如果要删除目录,请使用rmdir().os.rmdir()只能删除空目录 remove() 同 ...

  5. VB-获取本机计算机名,登录名、ip地址

    真的是很简单,执行结果:Computer:不平凡总在于坚持  User:Administrator  IP:192.168.0.111     '获取计算机名.用户名.本机ip     Dim Loc ...

  6. ExtJS4.2学习(6)——基础知识之proxy篇

    本次讨论下数据代理,其实个人第一次听到这个短语的时候,并不是特别的适应,在英语中的含义是proxy,其实如若大家也觉得不适应的话,就直接称呼proxy吧. 在ExtJS中,proxy是进行数据读写的主 ...

  7. php_PHP与Mysql的连接

    展示效果: 繁写: <?php    echo "This is a test</br>";     echo "asdfasdfadsf"; ...

  8. runtime统计页面数据或者统计按钮的点击次数

    一.按钮的点击统计 有的时候我们遇见这样的需求,让我们统计用户点击我们页面的动作的次数给与用户以统计,供以后给客户端推送不同的页面数据,这时候我们就会用到iOS的黑魔法(runtime). 首先我们不 ...

  9. P0505

      算法训练 P0505   时间限制:1.0s   内存限制:256.0MB      一个整数n的阶乘可以写成n!,它表示从1到n这n个整数的乘积.阶乘的增长速度非常快,例如,13!就已经比较大了 ...

  10. Python Solve UnicodeEncodeError &#39;gbk&#39; / &#39;ascii&#39; / &#39;utf8&#39; codec can&#39;t encode character &#39;\x??&#39; in position ? 解决有关Python编码的错误

    在Python中,处理中文字符一直是很令人头痛的问题,一言不合就乱码,而且引起乱码的原因也不尽相同,有时候是python本身默认的编码器设置的不对,有时候是使用的IDE的解码器不对,还有的时候是终端t ...