一编写步骤
二 获取数据库连接
2.1 diver接口实现
-
java.sal.Driver接口是说有jdbc驱动程序接口需要实现的接口也
-
在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用 这些Driver实现。 Oracle的驱动:oracle.jdbc.driver.OracleDriver mySql的驱动: com.mysql.jdbc.Driver
- 将上述jar包拷贝到Java工程的一个目录中,习惯上新建一个lib文件夹。
注意:如果是Dynamic Web Project(动态的web项目)话,则是把驱动jar放到WebContent(有的开发工具叫 WebRoot)目录中的WEB-INF目录中的lib目录下即可
2.2 加载与注册jdbc驱动
JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到 数据库的连接。 JDBC URL的标准由三部分组成,各部分间用冒号分隔。 jdbc:子协议:子名称 协议:JDBC URL中的协议总是jdbc 子协议:子协议用于标识一个数据库驱动程 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库 提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名
几种常用数据库的 JDBC URL MySQL的连接URL编写方式:
jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值 jdbc:mysql://localhost:3306/atguigu
jdbc:mysql://localhost:3306/atguigu?useUnicode=true&characterEncoding=utf8(如果JDBC 程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集) jdbc:mysql://localhost:3306/atguigu?user=root&password=123456 Oracle 9i的连接URL编写方式: jdbc:oracle:thin:@主机名称:oracle服务端口号:数据库名称 jdbc:oracle:thin:@localhost:1521:atguigu SQLServer的连接URL编写方式: jdbc:sqlserver://主机名称:sqlserver服务端口号:DatabaseName=数据库名称 jdbc:sqlserver://localhost:1433:DatabaseName=atguigu
2.3 要素三:用户名和密码
user,password可以用“属性名=属性值”方式告诉数据库 可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
2.4数据库连接方式
1
@Test
public void test(){
//1 提供java.sql.driver接口实现对象
Driver driver = bull
driver = com.mysql.jdbc.dirver();
//2提供url,指明具体操作数据
string url = "jdbc://mysql://localhost3306/text"
// 3 提供properties对象指名密码 用户名
Properties info = new Properties();
in.setProperties("username","root");
info.setProperties("password","123456");
// 4 调用connect连接数据库
Connection conn = driver.connect(url,info);
}
2 使用反射实例化driver 实现连接数据库
@Test
public void test(){
//1 实例化deiver
string classname = "com.sql.mysql.driver"
Class clazz = Class.forName(className);
Driver driver = (Driver) clazz.newInstance();
//2提供url,指明具体操作数据
string url = "jdbc://mysql://localhost3306/text"
// 3 提供properties对象指名密码 用户名
Properties info = new Properties();
in.setProperties("username","root");
info.setProperties("password","123456");
// 4 调用connect连接数据库
Connection conn = driver.connect(url,info);
}
3 使用drivermanger操作数据库
String Driver = "com.sql.mysql.Driver"
String url = "jdbc:mysql://locahost:3306/test"
string username ="root"
string password = "123456"
// 实例化driver
class clazz = class.forname(driver)
Driver driver = (driver)clazz.newInstance();
// 注册驱动
Drivermanger.registerDriver(driver) //可不需要
//获取连接
Connect con = Drivermanger,getConnection(url,username,password);
4 使用配置文件io流的形式进性配置(类加载器加载)
@test
public void textconnections() throw exception{
//1 加载配置文件
InputStream is = ConnectionTest.class.getClassLoader.GetRousoureAssStream("jdbc.properties");
Properties pros = new Properties();
String user =pros.getProperties("user")
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//加载驱动(可有可无)
class.forname(driverClass);
// 建立连接
Connection conn = DriverManneger.getConnection(url,user,password)
}
第3章:使用PreparedStatement实现CRUD操作
操作和访问数据库
数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连 接就是一个Socket连接。
在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式: Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。 PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。 CallableStatement:用于执行 SQL 存储过程
2 使用Statement操作数据表的弊端
-
通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返 回执行结果。
-
Statement 接口中定义了下列方法用于执行 SQL 语句:
int excuteupdate(String sql) 执行更新操作 update delect insert
ResultSet executeQuery(String sq) 执行查询操作SELECT
缺点
问题一:存在拼串操作,繁琐 问题二:存在SQL注入问题
对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(从Statement扩展而来) 取代 Statement 就可 以了。
代码演示
public class statementTest{
// 使用Statement的弊端:需要拼写sql语句,并且存在SQL注入的问题
@test
public void test(){
scanner scan = new Sacnner(system.in);
System.out.print("用户名:");
String userName = scan.nextLine();
System.out.print("密 码:");
String password = scan.nextLine();
String sql = "SELECT user,password FROM user_table WHERE USER = '" + userName + "' AND PASSWORD = '" + password
User user = get(sql, User.class);
if (user != null) {
System.out.println("登陆成功!");
}
else {
System.out.println("用户名或密码错误!");
}
}
}
}
3.3 PreparedStatement的使用
PreparedStatement介绍
可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象
PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值
3.3.2 PreparedStatement vs Statement
PreparedStatement 能最大可能提高性能: DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的 编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参 数直接传入编译过的语句执行代码中就会得到执行。 在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意 义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。 (语法检查,语义检查,翻译成二进制命令,缓存)
PreparedStatement 可以防止 SQL 注入
3.3.3 Java与SQL对应数据类型转换
3.3.4 使用PreparedStatement实现增、删、改操作
//1 加载配置文件
InputStream is = ConnectionTest.class.getClassLoader.GetRousoureAssStream("jdbc.properties");
Properties pros = new Properties();
String user =pros.getProperties("user")
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//加载驱动(可有可无)
class.forname(driverClass);
// 建立连接
Connection conn = DriverManneger.getConnection(url,user,password)
// 预编译sql语句返回Perparedstatement示例
String sql = "insert into test (name,email , date) values(?,?,?)"
PerparedStatement pre = conn.PerparedStatement();
//填充但唯独
pre.setString(1,“张三")
pre.setString(2,"2990895005@qq.com")
pre.setDate(3,"2020/8/8")
//执行sql
pre.excute();
//关闭
pre.close();
conn.colse();
一般jdbc的增删改
public class JDBCUtil{
public Connection getconnection(){
// 一加载配置文件
InputStream is = class.ClassLoader().getSystemStream().getSouresStream(jdbc.properties);
Properties pres = New Properties();
pres.load(is);
//获取配置文件
string user =is.getproperties("user")
string url = is.getproperties("url")
string password = is.getproperties("psd")
string driver = is.properties("driver")
// 加载驱动
class.forname(driver)
//连接数据库
Connection conn = DriberMannger.getconnection(url,username,password)
return conn
}
public class text{
public void update(string sql , object... args){
//1 连接数据库
Connection conn = JDBCUtil.getconntion();
// 创建conn的子类statement的子类perparestament的接口
Perparedstatement st = conn.Perparedastatement(sql);
// 填充占位符
1 获取元素局
for(int i = 0 ; i < args.length(),i++){
st.setobject(i+1,args[i])
}
st.execute();
//关闭
}
}
}
查询操作
public T List<T> getInstance(class<T> claszz,string sql,onject...args){
Connection conn = JDBCUtil.getconnection();
perparedstatment st =conn.ProParedstatement(sql);
for(int i = 0; i< args.length ;i++){
st.setobject(i+1,args[i]);
}
rs = st.executeQuery();
ResultSetmetadata resd = st.getMetadata();
// 6.1通过ResultSetMetaData得到columnCount,columnLabel;通过ResultSet得到列值
int columnCount = rsmd.getColumnCount();
Arrey<t> List = new Array();
while(rs.next()){
T t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {// 遍历每一个
// 获取列值
Object columnVal = rs.getObject(i + 1);
// 获取列的别名:列的别名,使用类的属性名充当
String columnLabel = rsmd.getColumnLabel(i + 1);
// 6.2使用反射,给对象的相应属性赋值
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnVal);
}
lisr.add(t);
}