一、持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各种关系数据库来完成。
二、持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。
在Java中,数据库存取技术可分为如下几类:
JDBC接口(API)包括两个层次:
补充:ODBC(Open Database Connectivity,开放式数据库连接),是微软在Windows平台下推出的。使用者在程序中只需要调用ODBC API,由 ODBC 驱动程序将调用转换成为对特定的数据库的调用请求。
总结为如下几点:
一、Driver接口介绍
二、加载与注册JDBC驱动
1、加载驱动:加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名
2、注册驱动:DriverManager 类是驱动程序管理器类,负责管理驱动程序
JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
几种常用数据库的 JDBC URL:
1. MySQL的连接URL编写方式:
①jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值
②jdbc:mysql://localhost:3306/test
③jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8(如果JDBC程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集)
④- jdbc:mysql://localhost:3306/test?user=root&password=123456
2. Oracle 9i的连接URL编写方式:
①jdbc:oracle:thin:@主机名称:oracle服务端口号:数据库名称
②jdbc:oracle:thin:@localhost:1521:test
3. SQLServer的连接URL编写方式:
①jdbc:sqlserver://主机名称:sqlserver服务端口号:DatabaseName=数据库名称
②jdbc:sqlserver://localhost:1433:DatabaseName=test
可以用“属性名=属性值”方式告诉数据库
可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
可以用“属性名=属性值”方式告诉数据库
可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
public class GetConnection {
public static void main(String[] args) throws SQLException {
//一、获取Driver的实现类对象
//①导入java.sql(包下的类Driver)
//②加载Mysql驱动(提供Driver的实现类)【需要手动导入jar包】
Driver driver = new com.mysql.jdbc.Driver();
//jdbc:mysql 协议
//localhost:3306 ip:mysql默认的端口号
//test test数据库
String url = "jdbc:mysql://localhost:3306/test";//提供要连接的数据库
//将用户名和密码封装在Properties中
Properties info = new Properties();
info.setProperty("user","root");
info.setProperty("password","zzw123");
Connection conn = driver.connect(url,info);//需要传入两个参数String url、Properties info
System.out.println(conn);//打印,看获取成功与否
}
}
方式二与方式一的不同在于使用反射获取Driver的实现类对象,目的是不出现第三方API,使得程序具有更好的可移植性
public class GetConnection {
public static void main(String[] args) throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException {
//一、获取Driver的实现类对象(通过反射的方式)
Class clazz = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver)clazz.newInstance();
//二、提供要连接的数据库
String url = "jdbc:mysql://localhost:3306/test";
//三、提供需要的用户名和密码
Properties info = new Properties();
info.setProperty("user","root");
info.setProperty("password","zzw123");
//四、获取连接
Connection conn = driver.connect(url,info);
System.out.println(conn);
}
}
public class GetConnection {
public static void main(String[] args) throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException {
//1、获取Driver实现类的对象(注册驱动时作为参数传入)
Class clazz = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) clazz.newInstance();
//2、提供另外三个连接的基本信息
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "zzw123";
//注册驱动
DriverManager.registerDriver(driver);
//获取连接
Connection conn = DriverManager.getConnection(url,user,password);
System.out.println(conn);
}
}
public class GetConnection {
public static void main(String[] args) throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException {
//1、提供另外三个连接的基本信息
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "zzw123";
//2、加载Driver
Class.forName("com.mysql.jdbc.Driver");
/*Driver driver = (Driver) clazz.newInstance();
注册驱动
DriverManager.registerDriver(driver);*/
//获取连接
Connection conn = DriverManager.getConnection(url,user,password);
System.out.println(conn);
}
}
不用注册驱动的原因是因为加载类Driver实现类时,Driver实现类中静态代码块部分已经帮我们注册了驱动
为了web阶段的使用,最好将配置文件放到src下,以免之后部署到Tomcat服务器下后配置文件缺失
【注意】:jdbc配置文件内容不要带双引号后
public class GetConnection {
public static void main(String[] args) throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException, IOException {
//读取配置文件的4个基本信息
//InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream();
InputStream is = GetConnection.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pro = new Properties();
pro.load(is);
String driverClass = pro.getProperty("driverClass");
String url = pro.getProperty("url");
String user = pro.getProperty("user");
String password = pro.getProperty("password");
//1、加载Driver(注册了Driver(因为Driver实现类中静态代码块中有注册驱动功能))
Class.forName(driverClass);
//2、获取数据库连接
Connection conn = DriverManager.getConnection(url,user,password);
System.out.println(conn);
}
}
使用配置文件的好处
①实现了代码和数据的分离,解耦,如果需要修改配置信息,直接在配置文件中修改,不需要深入代码
②如果修改了配置信息,省去重新编译的过程,避免程序重新打包
一、可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象
二、PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
三、PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1
开始),第二个是设置的 SQL 语句中的参数的值
由于操作数据库的通用步骤都是先获取数据库连接、操作数据库、关闭资源。
所以想到创建一个操作数据库的工具类,将获取数据库连接、关闭资源封装到其中。
操作数据库的工具类
public class JDBCUtils {
//获取数据库的连接
public static Connection getConnection() throws Exception {
//1、获取配置文件中的4个基本信息
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
Properties pro = new Properties();
pro.load(is);
//2、加载Driver
Class.forName(pro.getProperty("driverClass"));
//3、获取数据库连接
Connection conn = DriverManager.getConnection(pro.getProperty("url"),
pro.getProperty("user"),pro.getProperty("password"));
return conn;
}
//关闭资源
public static void closeResource(Connection conn, Statement ps){
try {
if(ps != null){
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
修改customers表的一条记录
public class GetConnection {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
//获取数据库连接
conn = JDBCUtils.getConnection();
//提供预编译的sql语句,返回PreparedStatement实例
String sql = "update customers set name=? where id=?";
ps = conn.prepareStatement(sql);
//填充占位符
ps.setObject(1,"张一");
ps.setObject(2,19);
//执行
ps.execute();
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭资源
JDBCUtils.closeResource(conn,ps);
}
}
}
public class GetConnection {
public static void main(String[] args) {
String sql = "delete from customers where id = ?";
update(sql,"20");
}
//实现通用的增、删、改操作
public static void update(String sql,Object ... args){
Connection conn = null;
PreparedStatement ps = null;
try {
//获取数据库连接
conn = JDBCUtils.getConnection();
//提供预编译的sql语句,返回PreparedStatement实例
ps = conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1,args[i]);
}
//执行
ps.execute();
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭资源
JDBCUtils.closeResource(conn,ps);
}
}
}
查询操作会返回一个ResultSet实例,其中有next()方法,返回值是boolean[拥有了Iterator当中hasNext()判断下一个是否有元素的功能,也拥有next()方法指针下移的功能]
ORM编程思想(Object relational mapping):
1、一个数据表对应一个类
2、表中的一条记录对应java类的一个对象
3、表中的一个字段对应java类的一个属性
public class Test {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
//获取数据库连接
conn = JDBCUtils.getConnection();
//预编译sql语句返回PreparedStatement实例
String sql = "select * from customers where id BETWEEN ? and ?";
ps = conn.prepareStatement(sql);
ps.setObject(1,1);
ps.setObject(2,10);
//执行并返回结果集
resultSet = ps.executeQuery();
//处理结果集
while(resultSet.next()){//判断结果集的下一条是否有数据,如果有数据返回true ,并指针下移;如果返回false,指针不会下移。
//获取当前结果集各个字段的值
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String email = resultSet.getString(3);
java.sql.Date birth = resultSet.getDate(4);
System.out.println(new Customer(id,name,email,birth));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭资源
JDBCUtils.closeResource(conn,ps,resultSet);
}
}
}
public class Customer {
private int id;
private String name;
private String email;
private java.sql.Date birth;
public Customer() {
}
public Customer(int id, String name, String email, Date date) {
this.id = id;
this.name = name;
this.email = email;
this.birth = date;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public Date getBirth() {
return birth;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setEmail(String email) {
this.email = email;
}
public void setDate(Date date) {
this.birth = date;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", birth=" + birth +
'}';
}
}
public class CustomerForQuery {
public static void main(String[] args) {
String sql = "select id,name,email,birth from customers where name = ?";
Customer cust1 = queryForCustomers(sql, "周杰伦");
System.out.println(cust1);
}
public static Customer queryForCustomers(String sql,Object ... args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//获取数据库连接
conn = JDBCUtils.getConnection();
//预编译sql语句返回PreparedStatement对象
ps = conn.prepareStatement(sql);
//将执行后的结果保存到结果集中
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
//获取结果集的元数据
ResultSetMetaData rsmd = rs.getMetaData();
//处理结果集
if(rs.next()){
Customer cust = new Customer();
//通过结果集获取列数
int columnCount = rsmd.getColumnCount();
//为Customer对象的属性赋值
for (int i = 0; i < columnCount; i++) {
//获取列名
String columnName = rsmd.getColumnName(i + 1);
//获取值
Object columnValue = rs.getObject(i + 1);
//通过反射获取属性名并赋值
Field fieldName = Customer.class.getDeclaredField(columnName);
fieldName.setAccessible(true);
fieldName.set(cust,columnValue);
}
return cust;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.closeResource(conn,ps,rs);
}
return null;
}
}
代码部分通过反射获取到属性之后,不要忘记setAccessible(true);
public class OrderForQuery {
public static void main(String[] args) {
String sql = "select order_id orderId,order_name orderName,order_date orderDate from `order` where order_id = ?";
Order order1 = queryForOrders(sql, 2);
System.out.println(order1);
}
public static Order queryForOrders(String sql,Object ... args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//获取数据库连接
conn = JDBCUtils.getConnection();
//预编译sql语句返回PreparedStatement实例
ps = conn.prepareStatement(sql);
//给占位符赋值
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1,args[i]);
}
//执行并获取结果集
rs = ps.executeQuery();
//获取结果集的元数据
ResultSetMetaData rsmd = rs.getMetaData();
//获取列数
int columnCount = rsmd.getColumnCount();
if(rs.next()){
Order order = new Order();
for (int i = 0; i < columnCount; i++) {
//获取列名(或者别名)
String columnName = rsmd.getColumnLabel(i + 1);
//获取列值
Object columnValue = rs.getObject(i + 1);
//通过反射对属性名赋值
Field fieldName = Order.class.getDeclaredField(columnName);
fieldName.setAccessible(true);
fieldName.set(order,columnValue);
}
return order;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,ps,rs);
}
return null;
}
}
public class OrderForQuery {
public static void main(String[] args) {
String sql = "select id,name,birth from customers where id=?";
Customer cust = getInstance(Customer.class, sql, 10);
System.out.println(cust);
}
public static <T>T getInstance(Class<T> clazz,String sql,Object ... args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1,args[i]);
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
if(rs.next()){
T t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {
String columnName = rsmd.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(t,columnValue);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps,rs);
}
return null;
}
}
public class OrderForQuery {
public static void main(String[] args) {
String sql = "select id,name,birth from customers where id between ? and ?";
List<Customer> list = getForList(Customer.class, sql, 1, 10);
/*for(Customer cust : list){
System.out.println(cust);
}*/
//用jdk8新特性Lambda表达式
list.forEach(System.out::println);
}
public static <T> List<T> getForList(Class<T> clazz, String sql, Object ... args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//获取数据库连接诶
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
List<T> list = new ArrayList<>();
for (int i = 0; i < args.length; i++) {
//赋值占位符
ps.setObject(i + 1,args[i]);
}
//获取结果集
rs = ps.executeQuery();
//获取元数据
ResultSetMetaData rsmd = rs.getMetaData();
//通过元数据获取结果集的列数
int columnCount = rsmd.getColumnCount();
while(rs.next()){
T t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {
//获取列名
String columnName = rsmd.getColumnLabel(i + 1);
//获取列值
Object columnValue = rs.getObject(i + 1);
//通过反射获取属性并赋值
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(t,columnValue);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps,rs);
}
return null;
}
}
public class TestInsert {
public static void main(String[] args) throws Exception{
String sql = "insert into customers(name,email,birth,photo) values(?,?,?,?)";
Connection conn = JDBCUtils.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"李一");
ps.setString(2,"[email protected]");
ps.setDate(3,new java.sql.Date(new java.util.Date().getTime()));
FileInputStream fis = new FileInputStream(new File("G://html_code//img//py3.jpg"));
ps.setBlob(4,fis);
ps.execute();
JDBCUtils.closeResource(conn,ps);
}
}
public class TestInsert {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
InputStream is = null;
try {
String sql = "select photo from customers where id = ?";
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement(sql);
ps.setInt(1,23);
ResultSet rs = ps.executeQuery();
if(rs.next()){
//将Blob类型字段下载下来,以文件的形式保存到本地
Blob photo = rs.getBlob(1);
//photo存取的是二进制数据,以下操作获取二进制流
is = photo.getBinaryStream();
//保存到本地
FileOutputStream fos = new FileOutputStream(new File("C://Users//18369//Desktop//copypy3.jpg"));
byte[] buf = new byte[1024];
int len;
while((len = is.read(buf)) != -1){
fos.write(buf,0,len);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(is != null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(conn,ps);
}
}
}
当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
JDBC的批量处理语句包括下面三个方法:
通常我们会遇到两种批量执行SQL语句的情况:
数据库中提供一个goods表。创建如下:
create table goods(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME varchar(20)
);
举例:向数据表中插入20000条数据
在实现该层次之前需要做一些修改:
public class TestInsert {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtils.getConnection();
String sql = "insert into goods(name) VALUES(?)";
ps = conn.prepareStatement(sql);
long start = System.currentTimeMillis();
for (int i = 1; i <= 20000; i++) {
ps.setObject(1,"name" + i);
//"攒"sql
ps.addBatch();
if(i % 500 == 0){
//执行
ps.executeBatch();
//清空
ps.clearBatch();
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.closeResource(conn,ps);
}
}
}
使用Connection 的 setAutoCommit(false) / commit()
public class TestInsert {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtils.getConnection();
//1.设置为不自动提交数据
conn.setAutoCommit(false);
String sql = "insert into goods(name) VALUES(?)";
ps = conn.prepareStatement(sql);
long start = System.currentTimeMillis();
for (int i = 1; i <= 1000000; i++) {
ps.setObject(1,"name" + i);
//"攒"sql
ps.addBatch();
if(i % 500 == 0){
//执行
ps.executeBatch();
//清空
ps.clearBatch();
}
}
//提交数据
conn.commit();
long end = System.currentTimeMillis();
System.out.println(end - start);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.closeResource(conn,ps);
}
}
}
若此时 Connection 没有被关闭,还可能被重复使用,则需要恢复其自动提交状态
setAutoCommit(true)。尤其是在使用数据库连接池技术时,执行close()方法前,建议恢复自动提交状态。
模拟AA对BB转账的操作
其中对数据库操作的方法为
补充操作
//封装了针对于数据表的通用操作
public abstract class BaseDao<E> {
private Class<E> clazz = null;
{
Type type = this.getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType)type;
Type[] actualTypeArguments = pt.getActualTypeArguments();
clazz = (Class<E>) actualTypeArguments[0];
}
//通用的增、删、改操作(考虑到事务)
public void update(Connection conn, String sql, Object ... args){
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1,args[i]);
}
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
//6.恢复每次DML操作的自动提交功能
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(null,ps);
}
}
//通用的查询操作(考虑到事务),返回 1 条记录
public E queryForOne(Connection conn,String sql,Object ... args){
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
if(rs.next()){
E e = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {
String columnName = rsmd.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(e,columnValue);
}
return e;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
//6.恢复每次DML操作的自动提交功能
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(null,ps,rs);
}
return null;
}
//通用的查询操作(考虑到事务),返回多条记录
public List<E> queryForList(Connection conn, String sql, Object ... args){
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1,args[i]);
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
ArrayList<E> list = new ArrayList<>();
while(rs.next()){
E e = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {
String columnName = rsmd.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(e,columnValue);
}
list.add(e);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
//6.恢复每次DML操作的自动提交功能
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(null,ps,rs);
}
return null;
}
//对组函数使用的返回结果获取
public <T> T getValue(Connection conn,String sql,Object ... args){
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1,args[i]);
}
rs = ps.executeQuery();
if(rs.next()){
return (T) rs.getObject(1);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
//6.恢复每次DML操作的自动提交功能
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(null,ps,rs);
}
return null;
}
}
public interface CustomerDao {
//将Customer实例添加到数据库中
void insert(Connection conn, Customer cust);
//针对指定id删除数据库中一条记录
void delete(Connection conn,int id);
//根据内存中的Customer实例,修改表中的一条记录
void updateC(Connection conn, Customer cust);
//根据指定id查询数据库中的一条记录
Customer getCustomerById(Connection conn,int id);
//查询表中的所有记录
List<Customer> getAllCustomers(Connection conn);
//返回表中的记录数量
long getCount(Connection conn);
}
public class CustomerDaoImpl extends BaseDao<Customer> implements CustomerDao{
@Override
public void insert(Connection conn, Customer cust) {
String sql = "insert into customers(name,email,birth) values(?,?,?)";
update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth());
}
@Override
public void delete(Connection conn, int id) {
String sql = "delete from customers where id=?";
update(conn,sql,id);
}
@Override
public void updateC(Connection conn, Customer cust) {
String sql = "update customers set name=?,email=?,birth=? where id=?";
update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth(),cust.getId());
}
@Override
public Customer getCustomerById(Connection conn, int id) {
String sql = "select id,name,email,birth from customers where id=?";
return queryForOne(conn,sql,id);
}
@Override
public List<Customer> getAllCustomers(Connection conn) {
String sql = "select id,name,email,birth from customers";
return queryForList(conn,sql);
}
@Override
public long getCount(Connection conn) {
String sql = "select count(*) from customers";
return getValue(conn,sql);
}
}
Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、Proxool等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,是目前最好的连接池之一