Java DataBase Connectivity java数据库连接
定义了操作所有关系型数据库的规则(接口),不同的数据库厂商编写类实现这些接口,这些类就叫数据库驱动,使得用户只需要使用统一的接口操作不同的数据库
public void test(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
//1.导入驱动jar包,如mysql-connector-java-5.1.37-bin.jar
// 新建目录,复制jar包,将存放jar包的目录右键选择add as library
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库连接对象 Connection
conn = DriverManager.getConnection("jdbc:mysql//localhost:3306/dbName,root,1234");
//4.定义sql语句
String sql = "select * from account";
//5.获取执行sql语句的对象Statement,实际开发用PreparedStatement
stmt = conn.createStatement();
//6.执行sql,接收返回结果
rs = stmt.executeQuery(sql);
//7.处理结果
while(rs.next()){
int id = rs.getInt(1);
String name = rs.getString("name");
System.out.println(id + " " + name);
}
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}finally {
//释放资源
if(rs != null){
try{
rs.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
DriverManager:驱动管理对象
注册驱动,5.0版本后可以省略注册让其自动注册
Class.forName("com.mysql.jdbc.Driver"); 实际通过静态代码块调用了 static void registerDriver(Driver driver);以注册驱动(告诉程序该使用哪个哪一个数据库驱动)
获取数据库连接
static Connection getConnection(String url, String user, String password);
url:指定连接的路径,如果连接的是本机mysql并且端口是3306,url可以写成"jdbc:mysql///dbName"
Connection:数据库连接对象
获取执行sql的对象
Statement createStatement();
PreparedStatement prepareStatement(String sql);
管理事务
开启事务:setAutoCommit(boolean autoCommit); 设置参数为false即开启
提交事务:commit();
回滚事务:rollback();
Statement:执行静态sql (参数给定不可更改) 并返回结果集的对象
执行sql
boolean execute(String sql); 执行任意sql语句(不常用)
int executeUpdate(String sql); 执行DML(insert, update, delete)和DDL(create, alter, drop)语句,DDL不返回值且不常用
返回值:受影响的行数,可以通过返回值判断执行是否成功,大于0则成功
ResultSet executeQuery(String sql); 执行DQL(select)语句
ResultSet:结果集对象
next():游标向下移动一行,游标初始在第一行上面一行
getXxx():获取数据,Xxx代表数据类型,如getInt(); getString();
参数:int:代表列的编号,从1开始
? String:代表列的名称
在try之前声明ResultSet rs = null;
PreparedStatement(常用):执行静态sql (参数给定不可更改) 并返回结果集的对象
SQL注入问题: 在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,有安全隐患
解决sql注入问题:使用PrepareStatement对象
预编译的sql:使用问号作为点位符
使用步骤
String sql = "select * from user where username = ? and password = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username); //参数位置从1开始
pstmt.setString(2, password);
rs = pstmt.executeQuery();
一般采用PreparedStatement,可以防止SQL注入,而且效率更高
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///dbName
user=root
password=1234
public class JDBCUtils{
private static String driver;
private static String url;
private static String user;
private static String password;
//使用静态代码块读取文件,使得类加载时就读取文件且只读取这一次
static{
try{
//创建Properties集合类
Properties pro = new Properties();
//获取src路径下文件的方式,ClassLoader 类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = ClassLoade.getResource("jdbc.properties");
String path = res.getPath();
//加载文件
pro.load(new FileReader(path));
//读取数据
driver = pro.getProperty("driver");
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
class.forName(driver);
} catch(IOException e){
e.printStackTrace();
} catch(ClassNotFoundException e){
e.printStackTrace();
}
}
public static Connection getConnection(){
return DriverManager.getConnection(url, user, password);
}
public static void close(Statement stmt, Connection conn){
if(rs != null){
try{
rs.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
public static void close(Statement stmt, Connection conn, Result rs){
close(stmt, conn);
if(rs != null){
try{
rs.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
使用工具类
public class login(String username, String password){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
conn = JDBCUtils.getConnection();
String sql = "select * from user where username = ? and password = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
rs = pstmt.executeQuery();
return rs.next(); //如果有结果,则返回true
}catch(SQLException e){
e.printStackTrace();
}finally{
JDBCUtils.close(rs, pstmt, conn);
}
}
用Connection对象来管理事务
开启事务:setAutoCommit(boolean autoCommit); 设置参数为false即开启
提交事务:commit();
回滚事务:rollback();
数据库连接池
c3p0
导入jar包(两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
定义配置文件 c3p0.properties 或 c3p0-config.xml 放在src目录下,也可以用dataSource.setXxx(...)在代码中配置
# c3p0.properties
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc
c3p0.user=root
c3p0.password=java
...
<!-- c3p0-config.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<property name="user">root</property>
<property name="password">1234</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/dbName</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">3</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">2</property>
<property name="maxStatements">200</property>
</default-config>
<!-- 命名的配置,配置多个config,可以通过相同的配置文件去配置不同的数据源,新建数据源时传入name即可 -->
<named-config name="test">
<property name="user">root</property>
<property name="password">1234</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/dbName</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<!-- 初始化数据库连接池时连接的数量 -->
<property name="initialPoolSize">20</property>
<!-- 数据库连接池中的最大的数据库连接数 -->
<property name="maxPoolSize">25</property>
<!-- 数据库连接池中的最小的数据库连接数 -->
<property name="minPoolSize">5</property>
</named-config>
</c3p0-config>
创建核心对象,数据库连接池对象 DataSource ds = new ComboPooledDataSource();
获取连接:getConnection();
druid
导入jar包 druid-1.0.9.jar
定义配置文件,properties类型,放在任意目录下
加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
获取数据库连接池对象,通过工厂类来获取 DruidDataSourceFactory
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
获取连接:getConnection();
自定义工具类
public class JDBCUtils{
private static DataSource ds;
static{
try{
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader(). getResourceAsStream("druid.properties"););
ds = DruidDataSourceFactory.createDataSource(pro);
}catch(IOException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
public static void close(...){...}
public static DataSource getDataSource(){return ds;}
}
Spring框架对JDBC的简单封装,提供了一个JdbcTemplate对象简化JDBC的开发
使用步骤
导入jar包
commons-logging、spring-beans、spring-core、spring-jdbc、spring-tx
创建对象,依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(dataSource);
调用JdbcTemplate的方法来完成CRUD操作
update():执行DML语句
queryForMap():DQL,并将结果集封装为map集合,key为字段名,value为字段值,只能封装一条记录,如果查出多条会报错
queryForList():DQL,并将结果集封装到list集合,将每条记录封装为map,再将map存入list中
query():DQL,并将结果集封闭到JavaBean的list中
//自定义RowMapper方式(不常用)
List<User> list = template.query(sql, new RowMapper<User>{
@Override
public User mapRow(ResultSet rs, int i) throws SQLException{
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
return user;
}
});
//使用spring提供的RowMapper方式,JavaBean中基本类型用封装类可以避免null错误
List<User> list = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
queryForObject():DQL,并将结果封装到对象,一般为基本类型的封装对象,用于聚合函数的查询
Demo
public void test(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "update account set balance = 5000 where id = ?";
int count = template.update(sql, 1); //sql后按顺序传参数
System.out.println(count);
}
原文:https://www.cnblogs.com/whteway/p/12044107.html