jdbc01
JDBC:(java dataBase connectivity,java数据库连接) 是一种执行sql语句的java API!
java语言编写的一些类和接口组成!
使用jdbc链接数据库需要的4要素!
01.连接数据库的驱动包!
02.url(localhost:3306/news)
03.用户名
04.密码
public class JdbcTest { public static void main(String[] args) { // selectUser();查询所有的用户信息 // addUser("小黑", "123", "567"); 新增 // updateUser("小黑", "123"); delUser("5'" + " or 1=1 and id='4"); // sql 注入 } // 查询所有的用户信息 private static void selectUser() { /** * 获取数据库连接的4要素 * 连接数据库的前提 */ String driver = "com.mysql.jdbc.Driver"; // 驱动 String url = "jdbc:mysql://localhost:3306/news"; // 连接地址String url = // "jdbc:mysql:///news"; String userName = "t11"; // 用户名 String password = "t11"; // 密码 // 获取数据库的链接 Connection connection = null; Statement statement = null; ResultSet rs = null; try { // 01.加载数据库驱动 Class.forName(driver); // 02.获取数据库的链接 connection = DriverManager.getConnection(url, userName, password); // 03.通过连接获取statement对象,并执行sql语句 ,不安全 sql注入 statement = connection.createStatement(); String sql = "select * from news_user"; rs = statement.executeQuery(sql); // 04. 处理结果集 while (rs.next()) {// rs.next() 获取一行记录 int id = rs.getInt("id"); String name = rs.getString("userName"); String pwd = rs.getString("password"); String email = rs.getString("email"); int type = rs.getInt("userType"); System.out.println("***********************************"); System.out.println("用户的编号:" + id); System.out.println("用户的姓名:" + name); System.out.println("用户的密码:" + pwd); System.out.println("用户的email:" + email); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 05.释放资源 try { rs.close(); statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 新增用户信息 private static void addUser(String userName, String password, String email) { /** * 获取数据库连接的4要素 * 连接数据库的前提 */ String driver = "com.mysql.jdbc.Driver"; // 驱动 String url = "jdbc:mysql://localhost:3306/news"; // 连接地址String url = // "jdbc:mysql:///news"; String name = "t11"; // 用户名 String pwd = "t11"; // 密码 // 获取数据库的链接 Connection connection = null; Statement statement = null; int rowNum = 0; // 影响的行数 try { // 01.加载数据库驱动 Class.forName(driver); // 02.获取数据库的链接 connection = DriverManager.getConnection(url, name, pwd); // 03.通过连接获取statement对象,并执行sql语句 ,不安全 sql注入 statement = connection.createStatement(); String sql = "INSERT INTO news_user(userName,PASSWORD,email) VALUES(" + "'" + userName + "','" + password + "','" + email + "')"; // 04.执行sql rowNum = statement.executeUpdate(sql); if (rowNum > 0) { System.out.println("新增成功!"); } else { System.out.println("新增失败!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 05.释放资源 try { statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 修改用户信息 根据用户名修改密码 private static void updateUser(String userName, String password) { /** * 获取数据库连接的4要素 * 连接数据库的前提 */ String driver = "com.mysql.jdbc.Driver"; // 驱动 String url = "jdbc:mysql://localhost:3306/news"; // 连接地址String url = // "jdbc:mysql:///news"; String name = "t11"; // 用户名 String pwd = "t11"; // 密码 // 获取数据库的链接 Connection connection = null; Statement statement = null; int rowNum = 0; // 影响的行数 try { // 01.加载数据库驱动 Class.forName(driver); // 02.获取数据库的链接 connection = DriverManager.getConnection(url, name, pwd); // 03.通过连接获取statement对象,并执行sql语句 ,不安全 sql注入 statement = connection.createStatement(); String sql = "UPDATE news_user SET PASSWORD='" + password + "' WHERE username='" + userName + "'"; // 04.执行sql rowNum = statement.executeUpdate(sql); if (rowNum > 0) { System.out.println("修改成功!"); } else { System.out.println("修改失败!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 05.释放资源 try { statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 删除指定用户信息 根据用户名删除 private static void delUser(String id) { /** * 获取数据库连接的4要素 * 连接数据库的前提 */ String driver = "com.mysql.jdbc.Driver"; // 驱动 String url = "jdbc:mysql://localhost:3306/news"; // 连接地址String url = // "jdbc:mysql:///news"; String name = "t11"; // 用户名 String pwd = "t11"; // 密码 // 获取数据库的链接 Connection connection = null; Statement statement = null; int rowNum = 0; // 影响的行数 try { // 01.加载数据库驱动 Class.forName(driver); // 02.获取数据库的链接 connection = DriverManager.getConnection(url, name, pwd); // 03.通过连接获取statement对象,并执行sql语句 ,不安全 sql注入 statement = connection.createStatement(); String sql = "DELETE FROM news_user WHERE id='" + id + "'"; // 04.执行sql rowNum = statement.executeUpdate(sql); if (rowNum > 0) { System.out.println("删除成功!"); } else { System.out.println("删除失败!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 05.释放资源 try { statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
出现的问题:
01.重复的代码 数据库需要的4要素
02.重复的代码
Connection connection = null;
Statement statement = null;
03.释放资源
04.所有的增删改 都是使用的executeUpdate()
05.所有的查询 都是使用的executeQuery()
06.我们使用的是statement对象! 不安全!
07.我们传递的参数太多了!
1.创建对应的数据库以及表
/* SQLyog 企业版 - MySQL GUI v8.14 MySQL - 5.5.32-log : Database - news ********************************************************************* */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; CREATE DATABASE /*!32312 IF NOT EXISTS*/`news` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */; USE `news`; /*Table structure for table `news_category` */ DROP TABLE IF EXISTS `news_category`; CREATE TABLE `news_category` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `createDate` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='新闻分类表'; /*Data for the table `news_category` */ insert into `news_category`(`id`,`name`,`createDate`) values (1,'国内','2014-09-16 14:41:24'),(2,'国际','2014-09-16 14:42:58'),(3,'娱乐','2014-09-16 14:42:58'),(4,'军事','2014-09-16 14:42:58'),(5,'财经','2014-09-16 14:42:58'),(6,'天气','2014-09-16 14:42:58'); /*Table structure for table `news_comment` */ DROP TABLE IF EXISTS `news_comment`; CREATE TABLE `news_comment` ( `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT 'id', `newsId` bigint(10) DEFAULT NULL COMMENT '评论新闻id', `content` varchar(2000) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '评论内容', `author` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '评论者', `ip` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '评论ip', `createDate` datetime DEFAULT NULL COMMENT '发表时间', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='新闻评论表'; /*Data for the table `news_comment` */ /*Table structure for table `news_detail` */ DROP TABLE IF EXISTS `news_detail`; CREATE TABLE `news_detail` ( `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT 'id', `categoryId` bigint(10) DEFAULT NULL COMMENT '新闻类别id', `title` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '新闻标题', `summary` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '新闻摘要', `content` text COLLATE utf8_unicode_ci COMMENT '新闻内容', `picPath` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '新闻图片路径', `author` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '发表者', `createDate` datetime DEFAULT NULL COMMENT '创建时间', `modifyDate` datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='新闻明细表'; /*Data for the table `news_detail` */ insert into `news_detail`(`id`,`categoryId`,`title`,`summary`,`content`,`picPath`,`author`,`createDate`,`modifyDate`) values (1,2,'尼日利亚一架客机坠毁','尼日利亚一架客机坠毁,伤亡惨重','尼日利亚一架客机坠毁,伤亡惨重,10人重伤','','admin','2014-09-16 14:43:53','2014-09-16 14:43:53'),(2,1,'谈北京精神','北京是一座拥有灿烂文明的古城','北京是一座拥有灿烂文明的古城,厚重的历史积淀,涵育了辉煌的北京文化。而这种融贯北京万众情怀、铸造北京城市特质、传沿北京文化基因、孕育北京创新灵魂的文化精髓,就是北京精神。侯仁之先生在谈到北京的城市建设时曾经提到过3个里程碑:紫禁城,天安门广场和国家奥林匹克体育中心、亚运村。侯先生认为,紫禁城是封建社会宫殿建筑中最有代表性的一组建筑群,是历史上封建皇权统治的中心,无论在文化上还是古迹上都举世闻名。新中国把天安门广场这样一个旧时代的宫廷广场,改造成人民的广场,给北京带来了一个全新的景象,这在北京城市建设发展史上具有重要意义。国家奥林匹克体育中心和亚运村的建设是对北京城传统中轴线的延伸,代表着北京走向国际、走向世界。北京的城市建设和建筑是与民族的兴衰联系在一起的,就像北京的中轴线,从北京厚重的历史中出发,奔向充满光明、充满希望的未来,奔向广阔的世界、无垠的宇宙。北京有着3000多年的建城史,800多年的建都史。从西周时期到辽金时期,北京作为地方首府,城市的中心点和中轴线不断改变。直到元代,蒙古铁骑扫荡了华夏四方,北京才真正成为全国的政治中心,中轴线也确定下来。中轴线在北京城市规划上具有重要意义,它就像一条奔涌着民族血液的动脉,为我们的民族、我们的国家、我们的北京时刻输送着营养和活力。中轴线凝聚了北京人民的爱国情怀,显示了北京的宽容、厚重与博大,也体现了北京的吸纳与创新。纵观世界,多少历史古城在浩瀚的风云中固守而亡,而北京几经磨难,依然能迈着豪迈的步伐,坚定自信地向充满希望的未来走去,我们不能不为北京的吸纳与创新而自豪! ',NULL,'admin','2014-09-16 14:43:53','2014-09-16 14:43:53'); /*Table structure for table `news_user` */ DROP TABLE IF EXISTS `news_user`; CREATE TABLE `news_user` ( `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '用户ID', `userName` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户名', `password` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '密码', `email` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'email', `userType` int(5) DEFAULT NULL COMMENT '用户类型 0:管理员 1:普通用户', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户表'; /*Data for the table `news_user` */ insert into `news_user`(`id`,`userName`,`password`,`email`,`userType`) values (1,'admin','admin','admin@bdqn.cn',0),(2,'user','user','user@bdqn.cn',1),(3,'test','test','test@bdqn.cn',1); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
2.创建对应的测试类
public class NewsTest { public static void main(String[] args) { //查询新闻信息 newsQuery(); /* * sql注入 修改指定新闻的信息 发现其他的也更改了 * newsUpdate("999999999", "1 or 1=1 and id=2"); */ } /** *01. 查询所有的新闻信息 */ public static void newsQuery() { //前提.把数据库驱动 Jar 放入项目中 String url="jdbc:mysql://localhost:3306/news"; String user="wym"; String password="wym"; //对象放在这里 是为了 方便 关闭资源 Connection connection=null; Statement statement=null; ResultSet set=null; try { //01.利用反射技术动态获取数据库的驱动 Class.forName("com.mysql.jdbc.Driver"); //02.获取数据库链接 Url User Pwd connection = DriverManager.getConnection(url, user, password); //03.通过链接获取statement对象,并执行sql语句 sql注入 不安全 statement = connection.createStatement(); String sql="SELECT * FROM news_detail"; set = statement.executeQuery(sql); //04.处理结果集 while(set.next()){ int id = set.getInt("id");//id指的就是数据库对应表中的 字段名称 String author=set.getString("author"); String title=set.getString("title"); String content=set.getString("content"); Timestamp createDate = set.getTimestamp("createDate"); //获取 //Date createDate= set.getDate("createDate"); 获取的是 年月日 //Time createDate= set.getTime("createDate"); 获取的是 时分秒 //输出 System.out.println("新闻的编号:"+id); System.out.println("新闻的作者:"+author); System.out.println("新闻的标题:"+title); System.out.println("新闻的内容:"+content); System.out.println("新闻的创建日期:"+createDate); System.out.println("*********************************"); } } catch (Exception e) { e.printStackTrace(); }finally{ try { //关闭资源 先开的后关 set.close(); statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** *02修改指定ID的新闻信息 * */ public static void newsUpdate(String content,String id) { //前提.把数据库驱动 Jar 放入项目中 String url="jdbc:mysql://localhost:3306/news"; String user="wym"; String password="wym"; //对象放在这里 是为了 方便 关闭资源 Connection connection=null; Statement statement=null; int num=0; try { //01.利用反射技术动态获取数据库的驱动 Class.forName("com.mysql.jdbc.Driver"); //02.获取数据库链接 Url User Pwd connection = DriverManager.getConnection(url, user, password); //03.通过链接获取statement对象,并执行sql语句 sql注入 不安全 statement = connection.createStatement(); String sql="UPDATE news_detail SET content="+"'" +content+"'"+ "where id="+id; System.out.println(sql); num= statement.executeUpdate(sql); if (num>0) { System.out.println("修改成功"); }else { System.out.println("失败"); } //04.处理结果集 } catch (Exception e) { e.printStackTrace(); }finally{ try { //关闭资源 先开的后关 statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
3.总结JDBC连接数据库的步骤 和 上面代码的问题
/* JDBC: 是java一套连接数据库的技术! JDBC API 01.引入需要的数据库驱动jar包 02.利用反射加载驱动 Class.forName("com.mysql.jdbc.Driver"); 03.通过DriverManager.getConnection获取数据库链接 需要三个参数 001.url="jdbc:mysql://localhost:3306/数据库名" 002. 用户名 003.密码 04.提供一个sql语句,Connection接口createStatement()创建Statement对象 Statement对象执行sql语句 001.查询executeQuery() 返回值 ResultSet 002.增删改 executeUpdate() 返回值int 05.处理结果 001. ResultSet 遍历 002.int 判断 06.关闭资源 重复的代码步骤: 02.加载驱动 03.获取数据库链接 06.关闭资源*/
针对上面的问题 怎么解决?? 提取成方法?
用户名 密码 url 驱动 是相对固定的值!
01.使用Properties 把 创建连接需要的 用户名 密码 url 驱动 进行管理!
02.怎么获取 Properties 文件中的内容
03.使用单例创建工具类 来读取配置文件
4.创建properties文件
5.创建读取properties文件的工具类
//单例 读取配置文件的工具类 public class ConfigManager { //01.创建静态的自身对象 private static ConfigManager manager=new ConfigManager(); //我们读取的配置文件需要的类 private static Properties properties; //02.构造私有化 private ConfigManager(){ String path="jdbc.properties"; properties=new Properties(); //获取流 InputStream stream = ConfigManager.class.getClassLoader().getResourceAsStream(path); try { properties.load(stream); //读取配置文件 } catch (IOException e) { e.printStackTrace(); }finally{ try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } } //03.提供外部访问的接口 public static synchronized ConfigManager getInstance(){ return manager; } //提供一个获取配置文件 value的方法 public static String getValue(String key){ return properties.getProperty(key); } }
6.修改测试类
public class NewsTest { public static void main(String[] args) { //查询新闻信息 newsQuery(); } /** *01. 查询所有的新闻信息 */ public static void newsQuery() { //前提.把数据库驱动 Jar 放入项目中 String url=ConfigManager.getInstance().getValue("url"); String user=ConfigManager.getInstance().getValue("userName"); String password=ConfigManager.getInstance().getValue("password"); String driver=ConfigManager.getInstance().getValue("driverClass"); //对象放在这里 是为了 方便 关闭资源 Connection connection=null; Statement statement=null; ResultSet set=null; try { //01.利用反射技术动态获取数据库的驱动 Class.forName(driver); //02.获取数据库链接 Url User Pwd connection = DriverManager.getConnection(url, user, password); //03.通过链接获取statement对象,并执行sql语句 sql注入 不安全 statement = connection.createStatement(); String sql="SELECT * FROM news_detail"; set = statement.executeQuery(sql); //04.处理结果集 while(set.next()){ int id = set.getInt("id");//id指的就是数据库对应表中的 字段名称 String author=set.getString("author"); String title=set.getString("title"); String content=set.getString("content"); Timestamp createDate = set.getTimestamp("createDate"); //获取 //Date createDate= set.getDate("createDate"); 获取的是 年月日 //Time createDate= set.getTime("createDate"); 获取的是 时分秒 //输出 System.out.println("新闻的编号:"+id); System.out.println("新闻的作者:"+author); System.out.println("新闻的标题:"+title); System.out.println("新闻的内容:"+content); System.out.println("新闻的创建日期:"+createDate); System.out.println("*********************************"); } } catch (Exception e) { e.printStackTrace(); }finally{ try { //关闭资源 先开的后关 set.close(); statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } /* *02修改指定ID的新闻信息 */ public static void newsUpdate(String content,String id) { //前提.把数据库驱动 Jar 放入项目中 String url=ConfigManager.getInstance().getValue("url"); String user=ConfigManager.getInstance().getValue("userName"); String password=ConfigManager.getInstance().getValue("password"); String driver=ConfigManager.getInstance().getValue("driverClass"); //对象放在这里 是为了 方便 关闭资源 Connection connection=null; Statement statement=null; int num=0; try { //01.利用反射技术动态获取数据库的驱动 Class.forName(driver); //02.获取数据库链接 Url User Pwd connection = DriverManager.getConnection(url, user, password); //03.通过链接获取statement对象,并执行sql语句 sql注入 不安全 statement = connection.createStatement(); String sql="UPDATE news_detail SET content="+"'" +content+"'"+ "where id="+id; System.out.println(sql); num= statement.executeUpdate(sql); if (num>0) { System.out.println("修改成功"); }else { System.out.println("失败"); } //04.处理结果集 } catch (Exception e) { e.printStackTrace(); }finally{ try { //关闭资源 先开的后关 statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
7.发现的问题
/*按上面的操作 执行完毕后 发现! 每个方法都有这个 String url=ConfigManager.getInstance().getValue("url"); String user=ConfigManager.getInstance().getValue("userName"); String password=ConfigManager.getInstance().getValue("password"); String driver=ConfigManager.getInstance().getValue("driverClass"); 关闭资源 也没有提取! 怎么解决sql语句的注入? 提取成一个公共的类!这个类的功能 01.创建连接 02.关闭资源! 还有 所有的对数据库的操作 都是 增删改查 03.增删改 都是一个方法executeUpdate 04.查 (查询所有,根据指定ID查询,根据标题查询,根据....) 都是一个方法 executeQuery*/
8.解决的方法创建BaseDao工具类
//通用的工具类 public class BaseDao { //jdbc 需要的API 创建出来 private Connection con; //连接对象 private PreparedStatement ps; //执行sql 防止sql注入 private ResultSet rs; //查询的返回结果集 //01.开启连接 public boolean getConnection(){ //读取配置文件 String url=ConfigManager.getInstance().getValue("url"); String user=ConfigManager.getInstance().getValue("userName"); String password=ConfigManager.getInstance().getValue("password"); String driver=ConfigManager.getInstance().getValue("driverClass"); try { Class.forName(driver); //加载驱动 con=DriverManager.getConnection(url,user,password); //创建连接 } catch (ClassNotFoundException e) { e.printStackTrace(); return false; } catch (SQLException e) { e.printStackTrace(); return false; } return true; } //02.关闭连接 public boolean closeConnection(){ //如果对象都没有创建 就没法关闭 所以 要非空判断 if (rs!=null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (ps!=null) { try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if (con!=null) { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } return true; } /* * 03.增删改 executeUpdate * * delete from user where name='小黑' and name='小白' * * Object ... o * 参数类型是数组类型的!在作为参数的时候 参数个数 可以为0和任意多个 */ public int executeUpdate(String sql,Object... params){ int updateRow=0; if (getConnection()) { //如果有连接进行操作 try { ps=con.prepareStatement(sql); //你在传sql语句的时候 有参数 就给参数赋值 for (int i = 0; i < params.length; i++) { ps.setObject(i+1, params[i]); } //执行sql语句 updateRow=ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } return updateRow; } //04.查询 select * from user where id=1 public ResultSet executeQuery(String sql,Object... params){ if (getConnection()) { //如果有连接进行操作 try { ps=con.prepareStatement(sql); //你在传sql语句的时候 有参数 就给参数赋值 for (int i = 0; i < params.length; i++) { ps.setObject(i+1, params[i]); } //执行sql语句 rs=ps.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } } return rs; } }
9.创建新的测试类
public class BaseDaoTest extends BaseDao { public static void main(String[] args) { BaseDaoTest test=new BaseDaoTest(); //查询新闻信息 test.newsQueryAll(); } /** *01. 查询指定的新闻信息 */ public void newsQuery(String id) { //获取连接 getConnection(); String sql="select * from news_detail where id=?"; //怎么给?赋值 ?就是占位符 Object [] params={id}; ResultSet set = executeQuery(sql, params); //处理结果集 try { while(set.next()){ int ids = set.getInt("id"); String title=set.getString("title"); String content=set.getString("content"); Timestamp createDate = set.getTimestamp("createDate"); System.out.println("新闻的编号:"+ids); System.out.println("新闻的标题:"+title); System.out.println("新闻的内容:"+content); System.out.println("新闻的创建日期:"+createDate); } } catch (SQLException e) { e.printStackTrace(); }finally{ closeConnection(); } } /* * 查询所有 没有参数就不传 不需要实例化参数对象 */ public void newsQueryAll() { //获取连接 getConnection(); String sql="select * from news_detail"; ResultSet set = executeQuery(sql); //处理结果集 try { while(set.next()){ int ids = set.getInt("id"); String title=set.getString("title"); String content=set.getString("content"); Timestamp createDate = set.getTimestamp("createDate"); System.out.println("新闻的编号:"+ids); System.out.println("新闻的标题:"+title); System.out.println("新闻的内容:"+content); System.out.println("新闻的创建日期:"+createDate); } } catch (SQLException e) { e.printStackTrace(); }finally{ closeConnection(); } } }
10.问题
/* * 现在从数据库中取得的字段 返回都是 变量接收的! * 字段有多少!就有多少个变量?? * 按照 java面向对象的编程思想! 我们把变量提取成 类 * * 我们这个变量 和 数据库 中的字段 什么关系! * 实体类 表 * 属性 字段 */
11.创建对应的News实体类
public class News { // 新闻信息的实体类 private String id; private String categoryId; private String title; private String summary; private String content; private String picPath; private String author; private Date createDate; private Date modifyDate; @Override public String toString() { return "News [id=" + id + ", categoryId=" + categoryId + ", title=" + title + ", summary=" + summary + ", content=" + content + ", picPath=" + picPath + ", author=" + author + ", createDate=" + createDate + ", modifyDate=" + modifyDate + "]"; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getCategoryId() { return categoryId; } public void setCategoryId(String categoryId) { this.categoryId = categoryId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getPicPath() { return picPath; } public void setPicPath(String picPath) { this.picPath = picPath; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public Date getModifyDate() { return modifyDate; } public void setModifyDate(Date modifyDate) { this.modifyDate = modifyDate; } }
12.根据ID查询指定的新闻
public class BaseDaoTest extends BaseDao { /** *01. 查询指定的新闻信息 并返回 */ public News newsQuery(String id) { //获取连接 getConnection(); String sql="select * from news_detail where id=?"; Object [] params={id}; ResultSet set = executeQuery(sql, params); //创建新闻对象 News news=new News(); //处理结果集 try { if (set.next()) { //根据ID查询 肯定只有一个! //给新闻对象赋值 news.setId(set.getString("id")); news.setTitle(set.getString("title")); news.setContent(set.getString("content")); news.setCreateDate(set.getTimestamp("createDate")); news.setAuthor(set.getString("author")); news.setCategoryId(set.getString("categoryId")); news.setModifyDate(set.getTimestamp("modifyDate")); news.setSummary(set.getString("summary")); } } catch (SQLException e) { e.printStackTrace(); }finally{ closeConnection(); } return news; } //测试方法 public static void main(String[] args) { BaseDaoTest test=new BaseDaoTest(); //获取指定的新闻信息 News news = test.newsQuery("1"); System.out.println(news); } }
13.新增新闻信息代码
public class BaseDaoTest extends BaseDao { /** * 新增新闻信息 */ public void addNews(News news){ getConnection();//获取连接 String sql="insert into news_detail(id,title,content,createDate) " + " values(?,?,?,?)"; Object[] params={news.getId(),news.getTitle(),news.getContent(),news.getCreateDate()}; //执行sql语句 int update = executeUpdate(sql, params); if (update>0) { System.out.println("新增成功!"); }else { System.out.println("失败"); } //关闭连接 closeConnection(); } //测试方法 public static void main(String[] args) { //新增用户 News news2=new News(); news2.setId("3"); news2.setTitle("大家辛苦了"); news2.setContent("真的好苦啊"); news2.setCreateDate(new Date()); test.addNews(news2); } }
14.总结
/* JDBC: 是java一套连接数据库的技术! JDBC API 01.引入需要的数据库驱动jar包 02.利用反射加载驱动 Class.forName("com.mysql.jdbc.Driver"); 03.通过DriverManager.getConnection获取数据库链接 需要三个参数 001.url="jdbc:mysql://localhost:3306/数据库名" 002. 用户名 003.密码 04.提供一个sql语句,Connection接口createStatement()创建Statement对象 Statement对象执行sql语句 001.查询 executeQuery() 返回值 ResultSet 002.增删改 executeUpdate() 返回值int 05.处理结果 001. ResultSet 遍历 002.int 判断 06.关闭资源 重复的代码: 02.加载驱动 03.获取数据库链接 06.关闭资源 针对上面的问题 怎么解决?? 提取方法? 用户名 密码 url 驱动 是相对固定的值! 01.使用Properties 把 创建连接需要的 用户名 密码 url 驱动 进行管理! 02.怎么获取 Properties 文件中的内容 03.使用单例工具类 来读取配置文件 按上面的操作 执行完毕后 发现! 每个方法都有这个 String url=ConfigManager.getInstance().getValue("url"); String user=ConfigManager.getInstance().getValue("userName"); String password=ConfigManager.getInstance().getValue("password"); String driver=ConfigManager.getInstance().getValue("driverClass"); 关闭资源 也没有提取! 怎么解决sql语句的注入? 提取成一个公共的类!这个类的功能 01.创建连接 02.关闭资源! 还有 所有的对数据库的操作 都是 增删改查 03.增删改 都是一个方法executeUpdate 04.查 (查询所有,根据指定ID查询,根据标题查询,根据....) 都是一个方法 executeQuery con.prepareStatement(sql) 和 con.createStatement() prepareStatement在创建的时候需要sql语句 执行sql语句是 不需要! 安全 防注入 Statement在创建的时候不需要sql 执行的时候需要! 不安全 可以注入 经典面试题 int a =5; double b =10; a=a/b; //编译错误 a/=b; //默认隐式转换成了(int) (a/b) */