JDBC
JDBC就是 数据库链接 ,java语言操作数据库
JDBC本质:其实是官方定义的一套操作所有关系型数据库的规
则,即接口,各个数据库厂商去实现这套接口,提供数据
库驱动jar包,我们可以使用接口编程,真正执行的代码是驱动jar包中的实现类
使用步骤
导入驱动jar包
赋值驱动jar包到项目下的libs目录下
右键--->Add as Library
注册驱动
获取数据库链接对象
定义sql、获取执行sql语句的对象Statement
执行sql,返回结果集
处理结果
释放资源
遇到的对象
1.DriverManager:驱动管理对象
2.Connection: 数据库连接对象
3.Statement: 执行sql的对象
4.ResultSet; 结果集对象
5 .PreparedStatement ;执行sql的对象
详解
DriverManager:驱动管理对象
1.注册驱动:
static void registerDriver(Driver driver):注册与给定的驱程序动DriverManager
为什么我们注册驱动是使用Class.for(“com.mysql.jdbc.Driver”) 呢
查看源码我们发现该类有一个静态代码块
static {
try {
DriverManager.registerDriver(new Driver());
向DriverManager注册一个Driver
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
该静态代码块里有注册驱动,我们我们写的时候可以简便的写,
将该类加载进内存,就会自动注册驱动
DriverManager的一个静态方法
public static Connection getConnection(String url, String user, String password)
返回一个Connection对象
Connection
获取执行sql的对象
1.Statement createStatement()
2.PreparedStatement prepareStatement(String sql)
事务
开启事务: void setAutoCommit(boolean autoCommit) true表示自动提交,false手动提交
提交事务: void commit()
回滚事务: void rollback()
Statement
执行sql
boolean execute(String sql) :可以执行任意的sql语句·
int executeUpdate(String sql) : 该方法用于执行增删改的sql语句,返回的是受影响的记录数
ResultSet executeQuery(String sql); 执行的是查询的sql,返回的是
ResultSet
结果集 ,封装的是查询结果
boolean next() 游标向下移动一行
如果是最后一行,则返回false,否则返回true,
getXxxx(参数) :获取数据
xxx代表数据类型,如int ,getint()
参数:
int :代表列的编号,第几列
String:代表列的名称
补充
动态的获取资源文件的路径
如
ClassLoader classloader=类名.class.getClassLoader()
URL url=classloader.getResource("文件名")
String path=url.getPath(); 得到的就是该文件名的路径(相对路径)
PreparedStatement
1.sql注入问题
在拼接sql时,有一些sql的关键字参与字符串的拼接,会造成安全问题
1.如 'a or 'a' = 'a'
2. 解决sql注入问题: 使用PreparedStatement 对象来解决
3. 预编译的sql :参数使用占位符 (?)
那么前几个步骤和之前的一样,
PreparedStatement connection.preparedstatement(String sql)
这里开始就不一样了
给?赋值
方法 : set Xxx(参数1,参数2)
参数1:占位符的位置编号,从1开始
参数2:占位符所需的值
接下来的增删改查的方法都不需要带sql语句参数
数据库连接池
就是一个容器,存放数据库连接的容器, 当系统初始化好后,容器被创建,容器中会申请一些对象,当用户来访问数据库时,从容
器中获取连接对象,用户访问完后,会将对象归还到容器
好处: 节约资源,用户访问高效
实现:
1.标准接口DataSource javax.sql
方法:
获取连接 :getConnection()
归还连接:如果连接对象Connection是从连接池中获取的,那么调用Connection的.close()方法
则不会关闭连接,而是归还连接
2一般我们不实现,由数据库厂商实现
1.c3p0 ;数据库连接池技术
2.Druid: 数据库连接池实现技术,由ailibab提供
使用3p0
步骤:
导入jar包 c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
定义配置文件: c3p0.properties 或者 c3p0-config.xml(必须2选1)
路径:文件要放在classpath下
创建核心对象:数据库连接池对象 CombopooledDataSource
获取连接
DataDource datasource=new CombopooledDataSource()
Connection connection=datasource.getConnection()
<c3p0-config>
<!--使用默认的配置读取连接池对象-->
<default-config>
<properties name="driverClass">com.mysql.jdbc.Driver</properties>
<properties name="jdbcUrl">jdbc:mysql://localhost:3306/aa</properties>
<properties name="user">root</properties>
<properties name="password">root</properties>
<!--连接池参数-->
<!--初始化申请的连接数量-->
<properties name="initialPoolSize">5</properties>
<!--最大的连接数量-->
<properties name="maxPoolSize">10</properties>
<!--超时时间-->
<properties name="checkoutTimeout">3000</properties>
</default-config>
<!--数据源通过该name创建,则使用的是该连接池参数-->
<named-config name="otherc3p0">
<properties name="driverClass">com.mysql.jdbc.Driver</properties>
<properties name="jdbcUrl">jdbc:mysql://localhost:3306/aa</properties>
<properties name="user">root</properties>
<properties name="password">root</properties>
<!--连接池参数-->
<!--初始化申请的连接数量-->
<properties name="initialPoolSize">5</properties>
<!--最大的连接数量-->
<properties name="maxPoolSize">10</properties>
<!--超时时间-->
<properties name="checkoutTimeout">3000</properties>
</named-config>
</c3p0-config>
Druid:
使用步骤
导入jar包 :druid-1.0.9.jar
定义配置文件
是properties文件 ,需要自己读取文件
可以叫任意名字,可放在任意目录下
获取数据库连接池对象
通过工厂来获取DruidDataSourceFactory
Properties propertiies=new Properties();
InputStream inputStream=Connections.class.getClassLoader().getResourceAsStream("druid.properties");
propertiies.load(inputStream);
DataSource dataSource=DruidDataSourceFactory.createDataSource(propertiies);
Connection connection = dataSource.getConnection();
通过这种方式来读取配置文件信息
配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/aa
username=root
password=123456
#初始化连接数
ininialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
Spring JDBC
spring 框架对JDBC的封装,提供了一个JDBCTemplate对象来简化JDBC的开发
1.导入jar包
2.创建Template对象,依赖数据源DataSource
JDBCTemplate temp=new Template(datasource)
3.调用jdbctemplate的方法
update():执行增删改语句
queryForMap(): 查询结果将结果集封装未map集合(只能封装一个对象,将字段做为key,数据为value)
queryForList(): 查询结果将结果集封装未list集合(获取多条数据,封装为list,泛型是map,相当于上面的再封装)
query(): 查询结果,将结果封装为javaBean对象(可查询多条数据)
其中,该方法要提供一个RowMapper(接口)对象,但已经有实现子类了,
BeanPropertyRowMapper<>(Aa.class)将查询到的数据封装到实体类中,
返回一个Aa对象, 我们也可以自己实现接口,重写方法,但不建议
queryForObject(): 查询
还有返回记录数,如count,AVG,max,min等函数唯一值时
可以使用该方法。 但是使用时参数第一个是sql语句,第二个是
所查询返回的类型,如,int类型,可以些Integer.class,注意| 。
该方法也可以使用BeanPropertyRowMapper<>(Aa.class)参数来获取一条记录
查询将结果封装为对象(单个对象,需要使用RowMapper实现类)
BeanPropertyRowMapper<>(Aa.class)的作用就是将结果集封装到泛型指定的实体类中
批量(c,u,d)
使用jdbcTemplate
public void updateAll(){
int ids[]={16,17,18,19,20,21,22,23,24,25,26,27};
jdbcTemplate.batchUpdate(
"update t_user set name=? where id=?", new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
preparedStatement.setInt(1, ids[i]);
preparedStatement.setInt(2, ids[i]);
}
@Override
public int getBatchSize() {
return ids.length;
}
});
}
内部使用了PreparedStatement语句效率还行
使用 BatchSqlUpdate来进行批量正删改
public void updateAll2(){
int ids[]={16,17,18,19,20,21,22,23,24,25,26,106};
BatchSqlUpdate batchSqlUpdate=new BatchSqlUpdate();
batchSqlUpdate.setSql("update t_user set name=? where id=?");
batchSqlUpdate.setDataSource(dataSource2);
batchSqlUpdate.setBatchSize(1);
batchSqlUpdate.setTypes(new int[]{Types.INTEGER,Types.INTEGER});
for (int j=0;j<ids.length;j++)
batchSqlUpdate.update(new Object[]{ids[j],ids[j]});
batchSqlUpdate.flush();
}
注意:使用这种方式必须是c3po连接池 , BatchSqlUpdate有四个构造重载,
其中三个是需要传入数据源胡,还有一个空参的,
但一定要在使用前设置数据源,如果使用空参的,他还提供了一个设置数据源的set方法
和上面的相比,这种方式还可以设置当update的记录有多少条时,提交事物
batchSqlUpdate.setBatchSize(5); 表示当update胡记录达到了5条时,提交事物,
如果没有达到这个值,则不会提交事物, 但当不满足这个值时,却有记录发生改变时,
这时我们就需要使用 batchSqlUpdate.flush(); 来提交事物
因此,每次使用披露update时,都必须调用该方法