三、JDBC编写步骤
我们可以通过DriverManager对象下的getConnection()方法创建与当前数据库的连接,得到connection对象。得到该对象表示完成和数据库的一次连接。创建好连接之后需要使用Connection对象创建statement对象或者是PreparedStatement对象发送SQL语句,如果执行的语句是查询语句的话返回一个resultSet对象。
3.1获取连接
package cn.it.bz.JDBC; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; //获取数据库连接 public class GetConnection { public static void main(String[] args) throws ClassNotFoundException, SQLException { //连接MySQL的url、username、password String url = "jdbc:mysql://localhost:3306/test?&useSSL=false&serverTimezone=UTC"; String username = "root"; String password = "123456"; //通过反射实现数据库驱动对象的加载和注册 Class.forName("com.mysql.cj.jdbc.Driver"); /*在加载com.mysql.jdbc.Driver类信息时,会执行静态块中的代码。 在静态块中,数据库驱动会实例化自己并通过DriverManager的registerDriver方法, 将自己注册DriverManager驱动管理器中.*/ // 获取数据库连接对象 Connection conn = DriverManager.getConnection(url, username, password); System.out.println(conn); } }
3.1.1Properties文件的使用
properties文件介绍
后缀properties的文件是一种属性文件。这种文件以key=value格式存储内容。Java中可以使用Properties工具类来读取这个文件。项目中会将一些配置信息放到properties文件中,所以properties文件经常作为配置文件来使用。
Properties工具类
Properties工具类,位于java.util包中,该工具类继承自Hashtable<Object,Object>。通过Properties工具类可以读取.properties类型的配置文件。
工具类中常用方法
load(InputStream is):通过给定的输入流对象读取properties文件并解析,将解析的结果放在Properties工具类存储。
getProperty(String key):根据key获取对应的value
注意
如果properties文件中含有中文那么需要对idea进行设置。
使用properties文件
package cn.it.bz.JDBC; import java.io.IOException; import java.io.InputStream; import java.util.Properties; //读取配置文件信息 public class PropertiesTest { public static void main(String[] args) throws IOException { //实例化操作配置文件的对象 Properties prop = new Properties(); //获取能读取配置文件的输入流对象 InputStream resourceAsStream = PropertiesTest.class.getClassLoader().getResourceAsStream("cn/it/bz/JDBC/JDBC.properties"); //通过Properties工具类读取已经转换为输入流的JDBC.properties文件并解析 prop.load(resourceAsStream); //解析后的文件放在Properties工具类中, String name = prop.getProperty("name"); System.out.println(name); String name1 = prop.getProperty("name1"); System.out.println(name1); } }
3.1.2优化获取数据库连接
# 连接MySQL的url、username、password、driverName url = jdbc:mysql://localhost:3306/test?&useSSL=false&serverTimezone=UTC username = root password = 123456 driverName = com.mysql.cj.jdbc.Driver
package cn.it.bz.JDBC; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; public class GetConnection2 { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { //实例化配置文件工具类 Properties props = new Properties(); //通过类加载器获取配置文件的字节输入流数据 InputStream resourceAsStream = GetConnection2.class.getClassLoader().getResourceAsStream("cn/it/bz/JDBC/JDBC.properties"); //读取并解析文件 props.load(resourceAsStream); //获取连接数据库的url String url = props.getProperty("url"); //获取连接数据库的用户名 String username = props.getProperty("username"); //获取连接数据库的密码 String password = props.getProperty("password"); //获取连接数据库驱动的全名 String driverName = props.getProperty("driverName"); //加载并注册驱动 Class.forName(driverName); //获取连接数据库的对象 Connection conn = DriverManager.getConnection(url, username, password); System.out.println(conn); } }
3.1.3封装JDBC工具类
package cn.it.bz.JDBC; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties; //数据库连接工具(工具类的异常不能往外抛出) public class JdbcUtils { private static String url = null; private static String username = null; private static String password = null; //类加载的时候执行,只进行一次加载,适合读取配置文件的IO操作。 static { Properties prop = new Properties(); try { InputStream resourceAsStream = JdbcUtils.class.getClassLoader().getResourceAsStream("cn/it/bz/JDBC/JDBC.properties"); prop.load(resourceAsStream); //获取配置文件中的连接数据库的url url = prop.getProperty("url"); //获取配置文件中的连接数据库的用户名 username = prop.getProperty("username"); //获取配置文件中的连接数据库的密码 password = prop.getProperty("password"); //获取驱动程序的全名 String driverName = prop.getProperty("driverName"); //实例化驱动 Class.forName(driverName); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } //获取数据库连接对象 public static Connection getConnection(){ Connection conn = null; try { conn = DriverManager.getConnection(url, username,password); } catch (SQLException e) { e.printStackTrace(); } return conn; } //关闭数据库连接对象 public static void closeConnection(Connection conn) { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } //提交事务 public static void commit(Connection conn) { if (conn != null) { try { conn.commit(); } catch (SQLException e) { e.printStackTrace(); } } } //事务回滚 public static void rollback(Connection conn) { if (conn != null) { try { conn.rollback(); } catch (SQLException e) { e.printStackTrace(); } } } //关闭statement对象(preparedStatement) public static void closeStatement(Statement stmt) { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } //关闭resultSet public static void closeResultSet(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } //关闭DML操作时的资源 public static void closeDMLResource(Statement ps, Connection con){ closeStatement(ps);//先关闭statement对象 closeConnection(con);//再关闭Connection对象 } //关闭DQL时的资源 public static void closeDQLResource(Connection conn, Statement stmt, ResultSet rs) { closeResultSet(rs);//先关闭ResultSet closeStatement(stmt);//再关闭Statement closeConnection(conn);//最后关闭Connection } }
3.2发送SQL、处理结果
3.2.1通过Statement添加、修改、删除数据
package cn.it.bz.JDBC; import java.sql.Connection; import java.sql.Statement; public class TestStatement { //添加用户 public void insertUser(String username,int userAge) { Connection conn = null; Statement stmt = null; try { //获取数据库连接对象 conn = JdbcUtils.getConnection(); //获取statement对象 stmt = conn.createStatement(); //定义需要statement对象执行的sql String sql = "insert into users values(default,'"+username + "',"+userAge + ")"; //执行该sql;true表示添加成功,false表示添加失败 boolean execute = stmt.execute(sql); System.out.println(execute); }catch (Exception e) { e.printStackTrace(); }finally { //关闭连接(先关闭Statement,再关闭Connection) JdbcUtils.closeDMLResource(stmt,conn); } } //修改数据 public void updateUser(int id,String username, int userAge) { Connection conn = null; Statement stmt = null; try { conn = JdbcUtils.getConnection(); stmt = conn.createStatement(); String sql = "update users set username='"+username + "',userage="+userAge + " where userid=" + id; int i = stmt.executeUpdate(sql); System.out.println(i); } catch (Exception e) { e.printStackTrace(); }finally { JdbcUtils.closeDMLResource(stmt, conn); } } //删除数据 public void deleteUser(int id) { Connection conn = null; Statement stmt = null; try { conn = JdbcUtils.getConnection(); stmt = conn.createStatement(); String sql = "delete from users where userid="+id; int i = stmt.executeUpdate(sql); System.out.println(i); } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.closeDMLResource(stmt, conn); } } public static void main(String[] args) { TestStatement testStatement = new TestStatement(); testStatement.insertUser("zhangsan", 18); testStatement.updateUser(1, "lisi", 20); testStatement.deleteUser(1); } }
3.2.2通过PreparedStatement添加、修改、删除数据
package cn.it.bz.JDBC; import java.sql.Connection; import java.sql.PreparedStatement; public class TestPreparedStatement { //添加数据 public void insertUser(String username, int userAge){ Connection conn = null; PreparedStatement ps = null; try { // 获取数据库连接 conn = JdbcUtils.getConnection(); //定义sql,?是参数占位符位置是从1开始计算的。 String sql = "insert into users values(default,?,?)"; //完成参数绑定 ps = conn.prepareStatement(sql); ps.setString(1, username); ps.setInt(2, userAge); int i = ps.executeUpdate(); System.out.println(i); }catch (Exception exception){ exception.printStackTrace(); }finally { //PreparedStatement是Statement的子接口 JdbcUtils.closeDMLResource(ps,conn); } } //修改数据 public void updateUser(int id, String username, int userAge) { Connection con = null; PreparedStatement ps = null; try { con = JdbcUtils.getConnection(); String sql = "update users set username=?,userage=? where userid=?"; ps = con.prepareStatement(sql); ps.setString(1, username); ps.setInt(2, userAge); ps.setInt(3, id); int i = ps.executeUpdate(); System.out.println(i); }catch (Exception exception) { exception.printStackTrace(); }finally { JdbcUtils.closeDMLResource(ps, con); } } //删除数据 public void deleteUser(int id) { Connection con = null; PreparedStatement ps = null; try { con = JdbcUtils.getConnection(); String sql = "delete from users where userid=?"; ps = con.prepareStatement(sql); ps.setInt(1, id); int i = ps.executeUpdate(); System.out.println(i); } catch (Exception exception) { exception.printStackTrace(); } finally { JdbcUtils.closeDMLResource(ps, con); } } public static void main(String[] args) { TestPreparedStatement testPreparedStatement = new TestPreparedStatement(); testPreparedStatement.insertUser("Java",123); testPreparedStatement.updateUser(3, "Tom", 20); testPreparedStatement.deleteUser(3); } }
3.2.3ResultSet的使用
ResultSet接口的特点
ResultSet用来存放数据库查询操作获得结果集,通过对ResultSet的操作可以获取查询到的结果集数据。
注意:
ResultSet 对象中存放的并不是我们查询到的所有的结果集。它采用分块加载的方式来载入结果集数据,防止大量数据涌入到内存。
ResultSet特点
- ResultSet 对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。next 方法将指针移动到下一行;因为该方法在 ResultSet 对象中没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
- 默认的 ResultSet 对象仅有一个向前移动的指针。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。
- ResultSet 接口提供用于获取当前行检索列值的获取方法(getBoolean、getLong 等)。可以使用列的索引位置或列的名称检索值。
ResultSet使用原理
3.2.4通过ResultSet获取查询结果
package cn.it.bz.JDBC; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class TestResultSet { //查询所有用户 public ResultSet getAllUsers(){ Connection con = null; PreparedStatement ps = null; ResultSet resultSet = null; try { //获取Connection对象 con = JdbcUtils.getConnection(); String sql = "select * from users"; ps = con.prepareStatement(sql); resultSet = ps.executeQuery(); }catch (Exception e) { e.printStackTrace(); } return resultSet; } public static void main(String[] args) throws SQLException { TestResultSet testResultSet = new TestResultSet(); ResultSet allUsers = testResultSet.getAllUsers(); while (allUsers.next()) { System.out.println(allUsers.getInt("userid")); System.out.println(allUsers.getString("username")); System.out.println(allUsers.getString("userAge")); } } }
四、ORM编程思想
4.1ORM简介
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/R mapping)是一种为了解决面向对象语言与关系数据库存在的互不匹配的现象。
4.2实体类
实体类就是一个定义了属性,拥有getter、setter、无参构造方法(基本必备)的一个类。实体类可以在数据传输过程中对数据进行封装,相当于一个“工具”、“容器”、“载体”,能存储、传输数据,能管理数据。
实体类特点:
- 实体类名,尽量和数据库中的表名一一对应
- 实体类中的属性对应数据库表中的字段,相关的命名最好也一一对应
- 实体类内方法主要有,getter、setter方法,用于设置、获取数据
- 实体类属性一般为private类型,方法为public类型
- 实体类应该有,无参、有参构造方法
4.3ORM的使用
List<Users> usersList = new ArrayList<Users>(); while (allUsers.next()) { //ORM映射 Users users = new Users(); users.setUserid(allUsers.getInt("userid")); users.setUsername(allUsers.getString("username")); users.setUserage(allUsers.getInt("userage")); usersList.add(users); }