JDBC中的细节

1、为什么要使用JDBC?
因为把要数据持久化,持久化数据的最好方式就是把数据保存到数据库,而Java要数据保存到数据,就需要使用JDBC

2、持久化到数据库的技术,唯一的只有JDBC ,其他的所有框架实现的底层都是JDBC,eg:Hibernate, MyBatis,JPA,SpringData JDBC

3、什么是JDBC?
JDBC(Java DataBase Connectivity,Java数据库连接):
是一种用于执行SQL语句(DML,DDL,DQL)的Java API,可以为多种关系数据库(oracle,mysql,SQL server)提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序.

4、结论:以后我们不管使用哪一种数据库,都需要去导入这个数据库给我们提供的jdbc实现的jar包(如mysql:mysql-connector-java-5.1.7-bin.jar)

5、JDBC使用步骤:加(加载驱动)、连(连接数据库)、预(获取预编译对象)、执(执行SQL)、释(释放连接)

	//添加示例
	public void testAdd() throws ClassNotFoundException, SQLException {
		//1.注册驱动[反射机制:jvm 拿到Mysql已经写好的驱动类] 
		Class.forName("com.mysql.jdbc.Driver");
		//2.获得连接对象
		//url可简写为jdbc:mysql:///数据库名
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库名", "用户名", "密码");
		//3.获得预编译对象,准备执行Sql
		Statement statement = conn.createStatement();
		//4执行Sql 
		String sql = "insert into user(name,sex,phoneNum) value ('孙孙',false,'666')";
		System.out.println(sql);
		statement.execute(sql);//执行sql语句
		//5.释放资源
		statement.close();//关闭  
		conn.close();
	}

6、ResultSet:保存查询返回的数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7、PreparedStatement与createStatement的区别
(1)Statement在创建语句对象,不需要传入sql;而PreparedStatement是预处理语句,需要传入sql,这个时候数据库已经收到sql语句,编译完了(用?先代替参数占个位,所以?叫占位符),等待参数进行操作,所以比createStatement的速度快;
(2)所以,在执行sql语句的时候,Statement 需要传入sql;PreparedStatement在执行sql语句时候,不需要传入sql;
(3)PreparedStatement使用占位符?进行赋值的方式(ps.setObject(index,value)),而createStatement是通过拼接+的方式
(4)所以,PreparedStatement是安全的,createStatement是不安全的(万能密码:’ or 1=1 or '),存在sql注入
(5)联系:PreparedStatement是Statement的子接口

8、dao层抽取工具:增、删、查、改使用一个方法

	public List<User> execute(String sql, Object... arr) {
		ArrayList<User> userList = new ArrayList<User>();
		Connection connection = null;
		PreparedStatement ps =null;
		try {
			connection = DBCPUtil2.getConnection();
			ps = connection.prepareStatement(sql);
			
			for (int i = 0; i < arr.length; i++) 
				ps.setObject(i+1, arr[i]);
			
			if (sql.contains("select")) {//是select,获取结果集,放到集合里,返回集合
				ResultSet eq = ps.executeQuery();
				while (eq.next()) {
					userList.add(new User(eq.getInt("id"), eq.getString("name"), eq.getBoolean("sex"), eq.getString("phoneNum"), eq.getString("pwd")));
				}
				return userList;
			} 
			ps.execute();//是DML操作,执行即可,最后返回null
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

9、事务:
指一组逻辑操作单元,使数据从一种状态变换到另一种状态
ACID属性:Atomic原子性、Consistency一致性、Isolation隔离性和Durability持久性

	/**
	*	转账示例
	*/
	public void testTransaction() {
		Connection conn = null;
		Statement cs =null;
		try {
			conn = JDBCUtil.getConnection();//一个连接就是一个事务
			conn.setAutoCommit(false);//事务默认是自动提交,所以设置为手动提交
			
			cs = conn.createStatement();
			
			String sql="update user set money=money-10 where name=shp";//转钱:转方
			cs.execute(sql);
			
			System.out.println(1/0);//模仿异常发生
			
			sql="update user set money=money+10 where name=heping";//转钱:收方
			cs.execute(sql);
			
			conn.commit();//在操作完成后提交事务
		} catch (Exception e) {
			try {
				conn.rollback();//发生异常就事务回滚
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}finally {
			JDBCUtil.close(conn, cs, null);
		}
	}

10、解决数据库配置信息硬编码问题,通过DHCP实现连接池,解析资源文件
导包commons-dbcp-1.3.jar和commons-pool-1.5.6.jar
(1)连接池

public class DBCPUtil {
	static Properties properties = new Properties();
	
	static BasicDataSource bds = new BasicDataSource();//BasicDataSource
	static{
		try(
			InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
		) {
			properties.load(is);//解析资源文件,解决硬编码问题
			
			bds.setDriverClassName(properties.getProperty("driverClassName"));
			bds.setUrl(properties.getProperty("url"));
			bds.setUsername(properties.getProperty("username"));
			bds.setPassword(properties.getProperty("password"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection() {
		try {
			return bds.getConnection();//向连接池获取连接
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

(2)工厂模式

public class DBCPUtil2 {
	static Properties properties = new Properties();
	
	static DataSource bds;
	static{
		try(
			InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
		) {
			properties.load(is);//解析资源文件,解决硬编码问题
			
			//工厂已定义好字段名,所以想要正确获取,就应该在配置文件中的配置参数写对应的名字
			bds=BasicDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection() {
		try {
			return bds.getConnection();//向连接池获取连接
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值