- 一、JDBC概述
- 1.软件架构
- 2.数据的持久化
- 3. Java中的数据存储技术
- 4.JDBC介绍
- 5. JDBC体系结构
- 二、获取数据库连接
- 1.连接的方式
- 2.通用方式
- 3.Statement *** 作数据表的弊端
- 三、实现表数据的添加 *** 作
- 1.Java与SQL对应数据类型转换表
- 2.PreparedStatement的使用
- (1)实现增、删、改 *** 作
- (2)实现查询 *** 作
- 总结
一、JDBC概述 1.软件架构
- B/S:Browser Server(浏览器/服务器模式)
- C/S:Client Server(服务器/客户机)
把数据保存到可掉电式存储设备中以供之后使用
3. Java中的数据存储技术-
在Java中,数据库存取技术可分为如下几类:
-
JDBC直接访问数据库
-
JDO (Java Data Object )技术
-
第三方O/R工具,如Hibernate, Mybatis 等
-
-
JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。
- JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和 *** 作的公共接口
- 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。
- 面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
JDBC是sun公司提供一套用于数据库 *** 作的接口,java程序员只需要面向这套接口编程即可。
不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。 ————面向接口编程
二、获取数据库连接 1.连接的方式代码如下(示例):
//方式一 @Test public void testConnection1() throws SQLException { Driver driver = new com.mysql.jdbc.Driver(); // url:http://localhost:8080/gmall/keyboard.jpg // jdbc:mysql:协议 // localhost:ip地址 // 3306:默认mysql的端口号 // test:test数据库 String url="jdbc:mysql://localhost:3306/test"; // 将用户名和密码封装在Properties中 Properties info=new Properties(); info.setProperty("user","root"); info.setProperty("password","123456"); Connection conn = driver.connect(url, info); System.out.println(conn); } //方式二 //在如下的程序中不出现第三方的api,使得程序具有更好的移植性 @Test public void testConnection2() throws Exception { //获取Driver实现类的对象:使用反射 Class clazz = Class.forName("com.mysql.jdbc.Driver"); Driver driver = (Driver) clazz.newInstance(); //提供要连接的数据库 String url="jdbc:mysql://localhost:3306/test"; Properties info=new Properties(); info.setProperty("user","root"); info.setProperty("password","123456"); Connection conn = driver.connect(url, info); System.out.println(conn); } //方式三 // 方式三:使用DriverManager替换Driver @Test public void testConnection3() throws Exception{ //获取Driver实现类的对象:使用反射 Class clazz = Class.forName("com.mysql.jdbc.Driver"); Driver driver = (Driver) clazz.newInstance(); //注册驱动 DriverManager.registerDriver(driver); String url="jdbc:mysql://localhost:3306/test"; String user="root"; String password = "123456"; Connection conn = DriverManager.getConnection(url,user,password); System.out.println(conn); } //方式四 @Test public void testConnection4() throws Exception { // 1.提供三个连接的基本信息: String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "abc123"; // 2.加载Driver Class.forName("com.mysql.jdbc.Driver");//这个也可以省略,但是最好不要省略,因为只有mysql好使,其他不行 //相较于方式三,可以省略如下的 *** 作: // Driver driver = (Driver) clazz.newInstance(); // // 注册驱动 // DriverManager.registerDriver(driver); //为什么可以省略上述 *** 作呢? // 3.获取连接 Connection conn = DriverManager.getConnection(url, user, password); System.out.println(conn); }2.通用方式
代码如下(示例):
//方式五(final版):将数据库连接需要的4个基本信息声明在配置文件中,通过读取配置文件的方式,获取连接 @Test public void getConnection5() throws Exception{ //1.读取配置文件中的4个基本信息 InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties"); Properties pros = new Properties(); pros.load(is); String user = pros.getProperty("user"); String password = pros.getProperty("password"); String url = pros.getProperty("url"); String driverClass = pros.getProperty("driverClass"); //2.加载驱动 Class.forName(driverClass); //3.获取连接 Connection conn = DriverManager.getConnection(url, user, password); System.out.println(conn); }3.Statement *** 作数据表的弊端
- 问题一:存在拼串 *** 作,繁琐
- 问题二:存在SQL注入问题
- SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令:(如:SELECt user, password FROM user_table WHERe user=‘a’ OR 1 = ’ AND password = ’ OR ‘1’ = ‘1’) ,从而利用系统的 SQL 引擎完成恶意行为的做法。
通用:
@Test public void testCommonUpdate(){ // String sql = "delete from customers where id = ?"; // update(sql,3); String sql = "update `order` set order_name = ? where order_id = ?"; update(sql,"DD","2"); } //通用的增删改 *** 作 public void update(String sql,Object ...args){//sql中占位符的个数与可变形参的长度相同! Connection conn = null; PreparedStatement ps = null; try { //1.获取数据库的连接 conn = JDBCUtils.getConnection(); //2.预编译sql语句,返回PreparedStatement的实例 ps = conn.prepareStatement(sql); //3.填充占位符 for(int i = 0;i < args.length;i++){ ps.setObject(i + 1, args[i]);//小心参数声明错误!! } //4.执行 ps.execute(); } catch (Exception e) { e.printStackTrace(); }finally{ //5.资源的关闭 JDBCUtils.closeResource(conn, ps); } }(2)实现查询 *** 作
针对于表的字段名与类的属性名不相同的情况:
- 必须声明sql时,使用类的属性名来命名字段的别名
- 使用ResultSetmetaData时,需要使用getColumnLabel()来替换getColumnName(), 获取列的别名。
说明:如果sql中没有给字段其别名,getColumnLabel()获取的就是列名
工具类
import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; // *** 作数据库的工具类 public class JDBCUtils { //获取数据库的连接 public static Connection getConnection() throws Exception { // 1.读取配置文件中的4个基本信息 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); Properties pros = new Properties(); pros.load(is); String user = pros.getProperty("user"); String password = pros.getProperty("password"); String url = pros.getProperty("url"); String driverClass = pros.getProperty("driverClass"); // 2.加载驱动 Class.forName(driverClass); // 3.获取连接 Connection conn = DriverManager.getConnection(url, user, password); return conn; } //关闭连接和Statement的 *** 作 public static void closeResource(Connection conn,Statement ps){ try { if(ps != null) ps.close(); } catch (SQLException e) { e.printStackTrace(); } try { if(conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } //关闭资源 *** 作 public static void closeResource(Connection conn,Statement ps,ResultSet rs){ try { if(ps != null) ps.close(); } catch (SQLException e) { e.printStackTrace(); } try { if(conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } try { if(rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); } } }
通用(单行数据):
@Test public void testGetInstance(){ String sql = "select id,name,email from customers where id = ?"; Customer customer = getInstance(Customer.class,sql,12); System.out.println(customer); String sql1 = "select order_id orderId,order_name orderName from `order` where order_id = ?"; Order order = getInstance(Order.class, sql1, 1); System.out.println(order); } //针对于不同的表的通用的查询 *** 作,返回表中的一条记录 publicT getInstance(Class clazz,String sql, Object... args) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JDBCUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) { ps.setObject(i + 1, args[i]); } rs = ps.executeQuery(); // 获取结果集的元数据 :ResultSetmetaData ResultSetmetaData rsmd = rs.getmetaData(); // 通过ResultSetmetaData获取结果集中的列数 int columnCount = rsmd.getColumnCount(); if (rs.next()) { T t = clazz.newInstance(); // 处理结果集一行数据中的每一个列 for (int i = 0; i < columnCount; i++) { // 获取列值 Object columValue = rs.getObject(i + 1); // 获取每个列的列名 // String columnName = rsmd.getColumnName(i + 1); String columnLabel = rsmd.getColumnLabel(i + 1); // 给t对象指定的columnName属性,赋值为columValue:通过反射 Field field = clazz.getDeclaredField(columnLabel); field.setAccessible(true); field.set(t, columValue); } return t; } } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.closeResource(conn, ps, rs); } return null; }
通用(多行数据):
@Test public void testGetForList(){ String sql = "select id,name,email from customers where id < ?"; Listlist = getForList(Customer.class,sql,12); list.forEach(System.out::println); String sql1 = "select order_id orderId,order_name orderName from `order`"; List orderList = getForList(Order.class, sql1); orderList.forEach(System.out::println); } public List getForList(Class clazz,String sql, Object... args){ Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JDBCUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) { ps.setObject(i + 1, args[i]); } rs = ps.executeQuery(); // 获取结果集的元数据 :ResultSetmetaData ResultSetmetaData rsmd = rs.getmetaData(); // 通过ResultSetmetaData获取结果集中的列数 int columnCount = rsmd.getColumnCount(); //创建集合对象 ArrayList list = new ArrayList (); while (rs.next()) { T t = clazz.newInstance(); // 处理结果集一行数据中的每一个列:给t对象指定的属性赋值 for (int i = 0; i < columnCount; i++) { // 获取列值 Object columValue = rs.getObject(i + 1); // 获取每个列的列名 // String columnName = rsmd.getColumnName(i + 1); String columnLabel = rsmd.getColumnLabel(i + 1); // 给t对象指定的columnName属性,赋值为columValue:通过反射 Field field = clazz.getDeclaredField(columnLabel); field.setAccessible(true); field.set(t, columValue); } list.add(t); } return list; } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.closeResource(conn, ps, rs); } return null; }
总结
ORM编程思想:
- 一个数据表对应一个java类
- 表中的一条记录对应java类的一个对象
- 表中的一个字段对应java类的一个属性
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)