Home >Database >Mysql Tutorial >java自学之路-----jdbc_基础

java自学之路-----jdbc_基础

WBOY
WBOYOriginal
2016-06-07 16:09:481118browse

JDBC(Java Data Base Connectivity):便于应用程序通过jdbc来操作数据库的数据 操作数据库基本步骤:(先导入该数据库的驱动程序){ 1.先与数据库进行连接,获取该数据库的对象(1.先加载数据库的驱动 2.通过数据库的基本信息来获取连接 3.通过连接获取操

JDBC(Java Data Base Connectivity):便于应用程序通过jdbc来操作数据库的数据

操作数据库基本步骤:(先导入该数据库的驱动程序){

1.先与数据库进行连接,获取该数据库的对象(1.先加载数据库的驱动 2.通过数据库的基本信息来获取连接 3.通过连接获取操作数据库的statement对象)

2.然后使用该对象执行sql语句{

数据库url:用于标识数据库的位置,程序需要通过url告诉jdbc程序连接那个数据库,写法:

jdbc : mysql : // localhost:3306 / mydb ?参数名:参数值

协议 子协议 主机:端口 数据库名

		String url = "jdbc://localhost:3306/mydb";//数据库的地址
		String user = "root";//数据库用户名
		String password = "root";//数据库密码
//第一种方式:
//		1.先加载驱动
		DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//		2.通过驱动获取连接
		Connection conn1 = DriverManager.getConnection(url, user, password);
//		3.通过连接获取statement对象
		Statement st1 = conn1.createStatement();
//	缺点:1.驱动程序注册两次:通过查看驱动类driver.class可以知道,该类有一个构造函数,在加载该类的时候自动在驱动里注册一次,所以在内存中就会出现两个driver对象
//		  2.程序import了mysql驱动,导致程序依赖mysql驱动api,离开了该jar包,程序编译就通不过
//第二种方式:
//		1.先加载驱动
		Class.forName("com.mysql.jdbc.Driver");
//		2.通过驱动获取连接
		Connection conn2 = DriverManager.getConnection(url, user, password);
//		3.通过连接获取statement对象
		Statement st2 = conn2.createStatement();
//	优点:该方式不会导致驱动对象在内存中重复出现,并且该方式下,程序只用一个字符串,不需要依赖具体驱动。	

Connection:代表数据库的连接,用于客户端与数据库的交互

1.createStatement();创建向数据库发送sql的statement对象

2.prepareStatement(sql);创建向数据库发送预编译sql的preparestatement对象

3.prepareCall(sql);创建执行存储过程的callableStatement对象

4.setAutoCommit(boolean b);设置事务是否自动提交

5.commit();在连接上提交事务

6.rollback();在此链接上回滚事务

Statement:用于向数据库发送sql语句

1.executeQuery(sql);用于向数据库发送查询语句。返回resultset对象

2.executeUpdate(sql);用于向数据库发送更新,插入,删除语句。返回影响数据的行数,大于0说明执行成功

3.execute(sql);用于向数据库发送任意语句。返回是否执行成功

4.addBatch(sql);将多条sql语句放在一个批处理中

5.executeBatch();向数据库发送一批sql语句

}

3.如果是select的sql就会返回结果集:ResultSet

4.通过该结果集可以获取select的所有数据{

//	如果sql为select
//		4.通过对象执行sql语句
//		5.获取ResultSet对象
//		6.遍历结果集,获取数据
		ResultSet rs = st.executeQuery("select * from users");//select的sql
//		int num = st.executeUpdate("update users set name='a'");
		while(rs.next()){
			Object value1 = rs.getObject(1);
			String value2 = rs.getString(2);
			Int value3 = rs.getInt(3);
//			...通过列的名字或者该列所的索引作为参数来获取该列的值
		}

ResultSet:用于代表sql语句的执行结果,该对象采用类似表格的方式来封装执行结果。它维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用next()方法,游标就指向了具体的数据行,再通过get方法获取该行数据。

获取任意类型的数据

getObject(int index);

getObject(String columnName);

获取相对应该列的属性的方法

}

5.释放资源{

 

		} finally{
			if(rs!=null){
				try {
					rs.close();
				} catch (Exception e) {
					rs = null;
				}
			}
			if(st!=null){
				try {
					st.close();
				} catch (Exception e) {
					st = null;
				}
			}if(conn!=null){
				try {
					conn.close();
				} catch (Exception e) {
					conn = null;
				}
			}
		}

1.jdbc程序运行结束之后,需要释放程序在运行过程中创建的那些与数据库进行交互的对象,通常 是ResultSet,Statement,和Connection对象

2.Connection对象,这是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。所以需要尽量晚创建,尽量早的关闭

3.为保证释放程序的代码执行,就必须放在finally语句中

}

}

创建工具类,简化操作{

public class JdbcUtils {
//	存储配置信息
	private static Properties config = new Properties();
//	提供一个静态代码块,确保第一次加载该类的时候将相关信息,加载到内存中
	static{
		try {
//		从配置文件中获取数据库相关信息,加载到config中,该文件要放在类路径下
			InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
			config.load(in);
			Class.forName(config.getProperty("driver"));
		} catch (Exception e) {
//			直接报错,因为配置文件有问题,连接不了数据库
			throw new ExceptionInInitializerError(e);
		}
	}
	
//	提供一个静态方法,为程序提供连接,异常直接抛给调用程序处理
	public static Connection getConnection() throws SQLException{
		return DriverManager.getConnection(config.getProperty("url"), config.getProperty("user"), config.getProperty("password"));
	}
//	提供一个释放资源的方法
	public static void release(Connection conn, Statement st, ResultSet rs){
		if(rs!=null){
			try {
				rs.close();
			} catch (Exception e) {
//				记录下异常信息
				e.printStackTrace();
				rs = null;
			}
		}
		if(st!=null){
			try {
				st.close();
			} catch (Exception e) {
				e.printStackTrace();
				st = null;
			}
		}
		if(conn!=null){
			try {
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
				conn = null;
			}
		}
	}
}

db.properties文件{

driver=com.mysql.jdbc.Driver

url=jdbc:mysql://localhost:3306/mydb

user=root

password=root

}

工厂类:将程序与dao层的操作进行解耦,{

//在web程序中,该工厂实现了service和dao层解耦。在修改底层代码的时候,不需要修改上层的代码,只需要修改配置文件即可
public class DaoFactory {
//	读取配置文件来创建接口对应的dao实例,也可以将该代码放在构造函数中
	private static Properties prop = new Properties();
	static{
		try {
//			dao.properties文件内 包含: UserDao = cn.halm.dao.UserDaoImpl
			prop.load(DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties"));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
//需要设计为单例模式
//	1.构造函数私有化
	private DaoFactory() {}
//	2.创建该类的一个私有的实例化对象
	private static DaoFactory instance = new DaoFactory();
//	3.将该对象提供给程序
	public static DaoFactory getInstance(){
		return instance;
	}
//	提供一个方法,从配置文件中读取信息后根据接口创建相应的实现类实例
	public <T> T createDao(Class interfaceClazz){
		try {
//		通过接口字节码文件获取接口名
			String interfaceName = interfaceClazz.getSimpleName();
//		通过接口名获取配置文件中对应的该接口的实现类的名称
			String implName = prop.getProperty(interfaceName);
//		返回该实现类的实例
			return (T) Class.forName(implName).newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

}

PreparedStatement对象{

1.是Statement的子类

2.可以有效的防止SQL注入:

 

sql = "select * from users where username = '"+username+"' and password = '"+password+"'";如果两个变量password,username="'or 1=1 or username='",那么该语句就为:select * from users where username='' or true or username=''——>select * from users where true;该语句就一定能从数据库中找到数据。这就是SQL注入!如果使用PreparedStatement会对传入的变量进行转义,就能预防该问题

3.该对象会对sql语句进行预编译,以减轻数据库服务器的压力,提高效率。statement对象会使数据库频繁编译sql,可能造成数据库缓冲区溢出

4.允许使用占位符替换参数,简化sql语句的编写

用法:

 

//			定义sql语句,包含占位符&ldquo;?&rdquo;
			String sql = "select * from users where username=? and id=?";
//			预编译sql语句获取对象
			PreparedStatement st = conn1.prepareStatement(sql);
//			从1开始,不同类型的数据使用不同的方法
			st.setString(1, user.getUsername());
			st.setInt(2, user.getId());
			st.executeQuery();
//			st.executeUpdate();insert,update,delete语句使用

获取插入数据的主键值:getGeneratedKeys()获取新插入数据的在数据库中自动增长的值,一般为主键{

如果没有这个方法,如果该主键值在数据库中被设置为自动增长,插入数据就不需要传入主键值,所以就无法直接获取该主键值,必须通过查表

注意:在mysql数据库中只能有一个字段修饰为auto_increment

//			获取执行执行sql语句的对象,指定一个常量值Statement.RETURN_GENERATED_KEYS,说明该自动增长的主键值被返回,如果不是insert的sql可以忽略该参数值,没有该参数,就不返回主键值
			PreparedStatement st = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
//			使用该方法获取新生成的包含在数据库中自动增长的值的ResultSet对象
//			该对象中只有一列,存放新生成的主键值,不是insert的sql语句,该方法无用
			ResultSet rs = st.getGeneratedKeys();
//			遍历,获取值
			rs.next();
			rs.getInt(1);
}

}

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn