day06-JDBC高级
2020-03-26 本文已影响0人
建国同学
一、PreparedStatement相比Statement的优势
- PreparedStatement:更好的可读性,可维护性
- 可以提供更好的性能(预编译).MySQL不支持PreparedStatement性能优化,高版本已支持,默认关闭
- 更安全,可以防止SQL注入的问题(' or 1 = 1 or ')
二、JDBC的事务操作
1.事务(Transaction,简写为tx):
指构成单个逻辑工作单元的操作集合
2.事务的ACID属性:
- 1)原子性(Atomicity):
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 - 2) 一致性(Consistency):包装数据的完整性:
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏) - 3)隔离性(Isolation):
事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 - 4)持久性(Durability):
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
3.事务操作:
要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态
操作事务的模板:
try{
取消事务的自动提交机制,设置为手动提交. connection对象.setAutoCommit(false);
操作1
操作2
异常
操作3
....
手动提交事务 connection对象.commit();
}catch(Exception e){
//处理异常
回滚事务 connection对象.rollback();
}
三、获取自动生成的主键
1.为什么要获取主键:
- 为了注册后进入另一个页面填写详细信息时可以继续完善该用户的信息
(在数据库中创建这行数据并填写部分信息)》》》(获取id以在数据库继续该条数据的填写)
2.如何获取自动生成的主键:
Statement方式:
int executeUpdate(String sql,int autoGeneratedKeys):
执行SQL:| 参数:autoGeneratedKeys,是否需要返回自动生成的主键.
常量值:Statement.RETURN_GENERATED_KEYS.
ResultSet getGeneratedKeys():获取自动生成的主键
-----------------------------------------------------------------------------
PreparedStatement方式:
创建PreparedStatement对象,并指定是否需要返回生成的主键.
PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) :
常量值:Statement.RETURN_GENERATED_KEYS
ResultSet getGeneratedKeys():获取自动生成的主键
四、连接池
javax.sql.DataSource接口表示连接池.
DataSource(数据源) = Connection Pool(连接池)
1.为什么必须使用数据库连接池:
- 性能好
- 连接资源利用率高
- 适合高并发问题
2.连接池实现
是否使用连接池区别在如何去获取Connection对象:
1)连接池获取Connection对象:
Connection conn = DataSource对象.getConnection();
2)连接池释放Connection对象
Connection对象.close();
连接池的关键在于:如何创建DataSource对象.
3. DBCP: Spring框架推荐的
注意:
需要jar包:commons-dbcp-1.4.jar
配置文件中的key名必须等于BasicDataSource中的属性名(由setter方法决定).
- 1.创建连接池获取Connection对象
BasicDataSource basicDataSource = new BasicDataSource();
Connection connection = basicDataSource .getConnection(); - 2.、工厂模式加载读取配置文件并返回获取Connection对象
Connection connection = DruidDataSourceFactory.createDataSource(properties)
4.C3P0: Hibernate框架推荐的
- 需要jar包:jar:c3p0-0.9.1.2.jar
- c3p0连接池,是Hibernate推荐使用的连接池,该连接池已有接近10年没有更新了.
很多人说c3p0性能很高,其实是在测试环境高,真实应用中很低.
5. druid: 阿里巴巴的连接池
号称Java语言中性能最好的连接池
需要jar包:druid-1.0.15.jar.
(1). DruidDataSource创建连接池对象方式获取
@Test
public void testGetDruidDate1() throws Exception {
// 1.创建连接池
DruidDataSource druidDataSource = new DruidDataSource();
// 2.设置四要素
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setUsername("root");
druidDataSource.setPassword("admin");
druidDataSource.setUrl("jdbc:mysql:///javaweb");
druidDataSource.setMaxActive (10);//设置最大连接数
// 3.从连接池中获取连接对象
Connection connection = druidDataSource.getConnection();
System.out.println(connection);
// 4.把连接对象归还会连接池
connection.close();
}
(2). DruidDataSourceFactory方式获取
public class DruidJDBCUtil {
private static DataSource druidDataSource = null;
static {
Properties properties = new Properties();
// 1. 读取配置文件,设置四要素
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
try {
// 加载配置文件
properties.load(inputStream);
// 设置四要素,并返回连接池对象
druidDataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
// 2.返回连接池连接对象
return druidDataSource.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
五、JDBC操作模板:JdbcTemplate
DQL模板
/**
* 需求: 3. 使用druid + 内省 + 反射 完成一个查询案例
* (查询 account 表 ,获取id为2的数据,封装成Account对象打印出来 )
*
*/
public class DruidDQLTest {
@Test
public void testDQL() throws Exception {
Object druidDQLByID = DruidDQLByID(Account.class,2L);
System.out.println(druidDQLByID);
}
public Object DruidDQLByID(Class beanClz,Long id) throws Exception {
String sql = "select * from account where id = ?";
// 1.工具类实现 1)加载驱动 2)连接池中获取连接对象
Connection connection = DruidUtil.getConnection();
// 2.获取预编译语句对象
PreparedStatement ps = connection.prepareStatement(sql);
// 3.设置参数
ps.setLong(1, id);
// 4.执行sql
ResultSet resultSet = ps.executeQuery();
// 5.处理结果集
if (resultSet.next()) {
Object newInstance = beanClz.newInstance();
// 6.内省处理bean
// 获取BeanInfo信息
BeanInfo beanInfo = Introspector.getBeanInfo(beanClz,Object.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
// 属性名称
String name = propertyDescriptor.getName();
// 属性对应的值
Object objectValue = resultSet.getObject(name);
// 获取set方法对象
Method writeMethod = propertyDescriptor.getWriteMethod();
// 反射方式执行真实对象的方法
writeMethod.invoke(newInstance, objectValue);
}
return newInstance;
}
// 7.释放资源
DruidUtil.release(ps, connection);
return null;
}
}
package cn.wolfcode._06_select;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
public class DruidUtil {
private static DataSource druidDataSource = null;
static {
Properties properties = new Properties();
// 1. 读取配置文件,设置四要素
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
try {
// 加载配置文件
properties.load(inputStream);
// 设置四要素,并返回连接池对象
druidDataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
// 2.返回连接池连接对象
return druidDataSource.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
// 3. 释放资源
public static void release(ResultSet rs, Statement ps, Connection conn) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void release(Statement ps, Connection conn) {
release(null, ps, conn);
}
}