java的基础语法--JDBC
一、解决硬编码
提取到配置文件中读取
方法一:ResourceBundle
方法二:ClassLoader
书写方式一:
书写方式二:
二、以指定的类型获取数据
将在数据库中获取的数据插入到对象中。
注意:Date从数据库中获取的是sql.Date类型需要转换成util.Date类型
三、获取新增行的主键值
获取主键值id
四、SQL注入
创建一个 Statement 对象。这个 Statement 对象就像是一个“信使”,专门负责将 SQL 语句发送到数据库中去执行。
1、创建执行器:createStatement 方法本身不执行 SQL,它只负责生产一个可以用来执行 SQL 的工具(即 Statement 对象)。
2、发送SQL:通过这个 Statement 对象,你可以调用 executeQuery、executeUpdate 等方法来执行查询、更新、删除等静态 SQL 语句
使用 Statement (不安全)
通过字符串拼接来构造 SQL(不能用?作为占位符),非常危险。
PreparedStatement:它最大的特点是使用问号 ? 作为占位符来替代 SQL 语句中的动态参数,在执行前再通过 setXXX() 方法为这些占位符设置具体的值。
极高的安全性:有效防止 SQL 注入。由于 SQL 语句的结构和用户输入的数据是分开处理的,数据库会将通过 setXXX() 方法设置的参数永远视为数据,而不是可执行的 SQL 命令。这从根本上杜绝了 SQL 注入攻击。
五、模糊查询
方式一:
方式二:
方式三:
方式四:
修改like后的字段,前三种方式like后都是占位符?
六、分页查询
七、批量插入数据
例一:
插入10条王五数据
例二:
插入一万条数据
不使用批处理方式:
在for循环中一条一条加
八、工具类
public class DBUtils { private DBUtils(){} private static String url; private static String username; private static String password; private static String driver; static { InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties"); Properties p = new Properties(); try { p.load(in); } catch (IOException e) { throw new RuntimeException(e); } driver = p.getProperty("driver"); url = p.getProperty("url"); username = p.getProperty("username"); password = p.getProperty("password"); try { Class.forName(driver); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } // 获取连接 public static Connection getConn(){ Connection conn = null; try { conn = DriverManager.getConnection(url, username, password); } catch (Exception e) { throw new RuntimeException(e); } finally { } return conn; } // 释放资源 public static void closeRes(Connection conn, PreparedStatement ps, ResultSet rs){ if(rs != null){ try { rs.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if(ps != null){ try { ps.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } }工具类应用:
释放资源时,有的没有相应资源可以传null值
代码如下:
public class JdbcTest08 { public static void main(String[] args) { Connection conn = null; PreparedStatement ps = null; try { conn = DBUtils.getConn(); //创建SQL语句 String sql = "insert into t_user (name,password,realname,tel,gen) values (?,?,?,?,?)"; //创建操作数据库的对象(发送sql的对象) 增删改:executeUpdate() 查:executeQuery() ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);//标志 ps.setString(1,"wangwu"); ps.setString(2,"123"); ps.setString(3,"王五"); ps.setString(4,"13333333333"); ps.setString(5,"男"); int i = ps.executeUpdate(); ResultSet rs = ps.getGeneratedKeys(); while (rs.next()){ String id = rs.getString(1); System.out.println(id); } //处理结果集 System.out.println(i ==1 ? "插入成功":"插入失败"); } catch (Exception e) { throw new RuntimeException(e); } finally { //释放资源 DBUtils.closeRes(conn,ps,null); } } }补充:静态代码块、构造代码块、构造方法
先执行静态代码块,在执行构造代码块,最后执行构造方法
静态代码块只执行一次
九、JDBC事务
public class AccountTest { public static void main(String[] args) { Connection conn = null; PreparedStatement ps = null; try { conn = DBUtils.getConn(); // 手动开启事务 conn.setAutoCommit(false); String sql1 = "update t_acc set balance = balance - ? where account = ?"; String sql2 = "update t_acc set balance = balance + ? where account = ?"; //张三扣款 ps = conn.prepareStatement(sql1); ps.setDouble(1,1000); ps.setString(2,"zhangsan"); ps.executeUpdate(); int i = 1/0; //李四加款 ps = conn.prepareStatement(sql2); ps.setDouble(1,1000); ps.setString(2,"lisi"); ps.executeUpdate(); // 提交事务 conn.commit(); } catch (SQLException e) { try { // 一旦业务代码出现异常,就回滚事务 conn.rollback(); } catch (SQLException ex) { throw new RuntimeException(ex); } throw new RuntimeException(e); } finally { DBUtils.closeRes(conn,ps,null); } } }十、DAO
//查看员工列表、查看某个员工详细信息、新增员工、修改员工、删除员工 public class EmployeeDao { //查看员工列表 public static void findAll(){ Connection conn = DBUtils.getConn(); PreparedStatement ps = null; ResultSet rs = null; try { String sql = "select * from t_employee"; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); while (rs.next()){ System.out.print(rs.getString("id")); System.out.print(rs.getString("name")); System.out.print(rs.getString("job")); System.out.print(rs.getString("hiredate")); System.out.print(rs.getString("salary")); System.out.print(rs.getString("address")); System.out.println(); } } catch (SQLException e) { throw new RuntimeException(e); }finally { DBUtils.closeRes(conn,ps,rs); } } // 详情 public static void getEmpById(long id){ Connection conn = DBUtils.getConn(); PreparedStatement ps = null; ResultSet rs = null; try { String sql = "select * from t_employee where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1,id); rs = ps.executeQuery(); while (rs.next()){ System.out.print(rs.getString("id")); System.out.print(rs.getString("name")); System.out.print(rs.getString("job")); System.out.print(rs.getString("hiredate")); System.out.print(rs.getString("salary")); System.out.print(rs.getString("address")); System.out.println(); } } catch (SQLException e) { throw new RuntimeException(e); }finally { DBUtils.closeRes(conn,ps,rs); } } // 修改员工 public static void updateEmp(String name,String job,double sal,String hiredate,String add,long id){ Connection conn = DBUtils.getConn(); PreparedStatement ps = null; ResultSet rs = null; try { String sql = "update t_employee set name=?,job=?,hiredate=?,salary=?,address=? where id = ?"; ps = conn.prepareStatement(sql); ps.setString(1,name); ps.setString(2,job); ps.setString(3,hiredate); ps.setDouble(4,sal); ps.setString(5,add); ps.setLong(6,id); ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); }finally { DBUtils.closeRes(conn,ps,rs); } } }public class EmployeeSystem { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("输入用户名:"); String name1 = scanner.nextLine(); System.out.println("输入密码:"); String pas = scanner.nextLine(); Connection conn = DBUtils.getConn(); PreparedStatement ps = null; ResultSet rs = null; try { String sql = "select * from t_user where name = ? and password = ?"; ps = conn.prepareStatement(sql); ps.setString(1,name1); ps.setString(2,pas); rs = ps.executeQuery(); if (rs.next()){ System.out.println("欢迎使用员工信息管理,请认真阅读使用说明:"); System.out.println("本系统的功能主要包括:查看员工列表、查看某个员工详细信息、新增员工、修改员工、删除员工"); System.out.println("请输入对应的功能编号选择功能:"); System.out.println("[1]查看员工列表"); System.out.println("[2]查看某个员工详细信息"); System.out.println("[3]新增员工"); System.out.println("[4]修改员工"); System.out.println("[5]删除员工"); System.out.println("[0]退出系统"); EmployeeDao employeeDao = new EmployeeDao(); while(true){ System.out.print("请输入功能编号:"); int no = scanner.nextInt(); if(1 == no){ //查看员工列表 employeeDao.findAll(); } else if(2 == no){ employeeDao.findAll(); System.out.print("请输入你要查详情的员工编号:"); int i = scanner.nextInt(); employeeDao.getEmpById(i); } else if(3 == no){ // 接收员工的信息 System.out.print("请输入员工姓名:"); String name = scanner.next(); System.out.print("请输入员工岗位:"); String job = scanner.next(); System.out.print("请输入员工月薪:"); Double salary = scanner.nextDouble(); System.out.print("请输入员工入职日期:"); String hiredate = scanner.next(); System.out.print("请输入员工住址:"); String address = scanner.next(); } else if(4 == no){ //修改 employeeDao.findAll(); System.out.print("请输入你要修改的员工的编号:"); int i = scanner.nextInt(); employeeDao.getEmpById(i); System.out.print("请输入员工姓名:"); String name = scanner.next(); System.out.print("请输入员工岗位:"); String job = scanner.next(); System.out.print("请输入员工月薪:"); Double salary = scanner.nextDouble(); System.out.print("请输入员工入职日期:"); String hiredate = scanner.next(); System.out.print("请输入员工住址:"); String address = scanner.next(); employeeDao.updateEmp(name,job,salary,hiredate,address,i); employeeDao.findAll(); } else if(5 == no){ employeeDao.findAll(); } else if(0 == no){ System.out.println("下次再见!"); System.exit(0); } else { System.out.println("对不起,您输入的功能暂不支持!"); } } }else { System.out.println("用户名或密码错误"); } } catch (SQLException e) { throw new RuntimeException(e); }finally { DBUtils.closeRes(conn,ps,rs); } } }十一、连接池
step1:引入druid依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.23</version> <scope>compile</scope> </dependency>step2:实例化 Druid 数据源对象
DruidDataSource druidDataSource = new DruidDataSource();step3:配置数据库连接基本参数
druidDataSource.setDriverClassName(driver); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password);step4:(可选)配置连接池性能参数
//可选:配置连接池参数 druidDataSource.setInitialSize(5); druidDataSource.setMaxActive(20); druidDataSource.setMinIdle(5);step5:将配置好的数据源赋值给静态变量
//在工具类中定义数据源的静态变量 private static DataSource dataSource;//将配置好的数据源赋值给静态变量 dataSource = druidDataSource;十二、QueryRunner
ResultSetHandler接口:转换类型接口
BeanHandler类:实现类,把一条记录转换成对象
BeanListHandler类:实现类,把多条记录转换成 List集合
ScalarHandler类:实现类,适合获取一行一列的数 据。
QueryRunner:执行sql语句的类
增、删、改:update();
查询:query();
1、引入依赖
在文件pom.xml文件中加入commons-dbutils或者导入相应jar包
<dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.7</version> </dependency>2、使用
(1)新建QueryRunner对象
--》无需传入 Connection 参数,QueryRunner 自动管理连接的获取和关闭
dataSource为从连接池里获取的数据源
QueryRunner queryRunner = new QueryRunner(dataSource);(2)
①查询:调用query()方法(要抛异常)
返回一行数据封装为ScenicSpot对象
ScenicSpot scenicSpot = queryRunner.query("select * from scenic_spot where id=?",new BeanHandler<>(ScenicSpot.class),1);把多条记录转转成为ScenicSpot对象List集合
List<ScenicSpot> scenicSpots= queryRunner.query("select * from scenic_spot",new BeanListHandler<>(ScenicSpot.class));补充:
/** * 执行查询操作,返回结果列表 * @param sql SQL查询语句 * @param handler 结果处理器 查询结果数据---》封装哪个实体类中 * @param params 查询参数 * @return 查询结果列表 * @param <T> * @throws SQLException 如果查询失败 */ public static <T> T query(String sql, ResultSetHandler<T> handler, Object... params) throws SQLException { QueryRunner runner = getQueryRunner(); return runner.query(sql,handler,params); }②插入,更新,删除:调用update()方法(抛异常)
/** * 执行插入、更新或删除操作 * @param sql SQL语句 * @param params 参数 * @return 受影响的行数 * @throws SQLException 如果执行失败 */ public static int update(String sql, Object... params) throws SQLException { QueryRunner runner = getQueryRunner(); return runner.update(sql,params); }插入:
更新:
删除:
十三、JDBC(连接池+QueryRuuer)
引入依赖mysql-connector-j、druid、commons-dbutils
step1:加载properties
step2:加载驱动、创建数据源对象
step3:获取QueryRunner 实例,用于执行SQL 查询和删除
public class DBUtil { //static共享数据 private static String driver; private static String url; private static String username; private static String password; private static DataSource dataSource; static {//静态代码块,只执行一次 loadProperties();//step1:加载properties initDataSource();//step2:加载驱动 } /** * stepl:加载properties */ private static void loadProperties() { Properties props = new Properties();//Map下的子类 //加载文件 //流对象 加载器 根路径上的properties文件 InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties"); try { if (is != null) { props.load(is);//流对象读取的内容加载本Properties的对象中 driver = props.getProperty("db.driver");//获取Properties的对象中加载的信息 url = props.getProperty("db.url"); username = props.getProperty("db.username"); password = props.getProperty("db.password"); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (is != null) is.close(); } catch (Exception e) { e.printStackTrace(); } } } /** * step2:加载驱动、创建数据源对象 */ private static void initDataSource() { try{ //反射机制 加载驱动类 Class.forName(driver); //使用Alibaba Druid作为数据源实现 //请确保pom.xml中已添加 druid 依赖 DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setDriverClassName(driver); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password); //可选:配置连接池参数 // druidDataSource.setInitialSize(5); // druidDataSource.setMaxActive(20); // druidDataSource.setMinIdle(5); dataSource = druidDataSource; // System.out.println("druidDataSource="+druidDataSource); }catch (ClassNotFoundException e){ e.printStackTrace(); } } /** * 获取QueryRunner 实例,用于执行SQL 查询和删除 * @return QueryRunner 实例 */ public static QueryRunner getQueryRunner() { return new QueryRunner(dataSource); } /** * 执行查询操作,返回结果列表 * @param sql SQL查询语句 * @param handler 结果处理器 查询结果数据---》封装哪个实体类中 * @param params 查询参数 * @return 查询结果列表 * @param <T> * @throws SQLException 如果查询失败 */ public static <T> T query(String sql, ResultSetHandler<T> handler, Object... params) throws SQLException { QueryRunner runner = getQueryRunner(); return runner.query(sql,handler,params); } /** * 执行插入、更新或删除操作 * @param sql SQL语句 * @param params 参数 * @return 受影响的行数 * @throws SQLException 如果执行失败 */ public static int update(String sql, Object... params) throws SQLException { QueryRunner runner = getQueryRunner(); return runner.update(sql,params); } //试运行 public static void main(String[] args) throws SQLException { // DBUtil.loadProperties(); // System.out.println(driver); // System.out.println(url); // DBUtil.initDataSource(); //根据id查询景区信息 //表中的字段名于映射的实体中的属性名 名称一致 ScenicSpot scenicSpot = DBUtil.query("select * from scenic_spot where id=?",new BeanHandler<>(ScenicSpot.class),1); System.out.println("scenicSpot="+scenicSpot); //景区列表数据 List<ScenicSpot> scenicSpots= DBUtil.query("select * from scenic_spot",new BeanListHandler<>(ScenicSpot.class)); System.out.println("scenicSpots="+scenicSpots); } }